mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 10:33:30 +00:00
Various improvements for https://github.com/firefly-iii/firefly-iii/issues/8281
This commit is contained in:
@@ -101,6 +101,10 @@ class BasicController extends Controller
|
|||||||
$billData = $this->getBillInformation($start, $end);
|
$billData = $this->getBillInformation($start, $end);
|
||||||
$spentData = $this->getLeftToSpendInfo($start, $end);
|
$spentData = $this->getLeftToSpendInfo($start, $end);
|
||||||
$netWorthData = $this->getNetWorthInfo($start, $end);
|
$netWorthData = $this->getNetWorthInfo($start, $end);
|
||||||
|
// $balanceData = [];
|
||||||
|
// $billData = [];
|
||||||
|
// $spentData = [];
|
||||||
|
// $netWorthData = [];
|
||||||
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
|
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
|
||||||
|
|
||||||
// give new keys
|
// give new keys
|
||||||
|
@@ -225,6 +225,7 @@ class BudgetController extends Controller
|
|||||||
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount);
|
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@@ -288,6 +289,7 @@ class BudgetController extends Controller
|
|||||||
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']));
|
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
@@ -137,6 +137,7 @@ class CategoryController extends Controller
|
|||||||
usort($return, static function (array $a, array $b) {
|
usort($return, static function (array $a, array $b) {
|
||||||
return (float)$a['native_amount'] < (float)$b['native_amount'] ? 1 : -1;
|
return (float)$a['native_amount'] < (float)$b['native_amount'] ? 1 : -1;
|
||||||
});
|
});
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return response()->json($this->clean($return));
|
return response()->json($this->clean($return));
|
||||||
}
|
}
|
||||||
|
@@ -278,7 +278,6 @@ class BasicController extends Controller
|
|||||||
*/
|
*/
|
||||||
foreach ($spent as $currencyId => $row) {
|
foreach ($spent as $currencyId => $row) {
|
||||||
app('log')->debug(sprintf('Processing spent array in currency #%d', $currencyId));
|
app('log')->debug(sprintf('Processing spent array in currency #%d', $currencyId));
|
||||||
$currencyId = $currencyId;
|
|
||||||
$spent = '0';
|
$spent = '0';
|
||||||
$spentNative = '0';
|
$spentNative = '0';
|
||||||
|
|
||||||
@@ -351,6 +350,7 @@ class BasicController extends Controller
|
|||||||
}
|
}
|
||||||
$return[] = $nativeLeft;
|
$return[] = $nativeLeft;
|
||||||
$return[] = $nativePerDay;
|
$return[] = $nativePerDay;
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
@@ -927,7 +927,7 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
{
|
{
|
||||||
$currentCollection = $collection;
|
$currentCollection = $collection;
|
||||||
|
|
||||||
app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection)));
|
// app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Closure $function
|
* @var \Closure $function
|
||||||
|
@@ -138,6 +138,7 @@ class NetWorth implements NetWorthInterface
|
|||||||
$netWorth['native']['native_balance'] = bcadd($nativeBalance, $netWorth['native']['native_balance']);
|
$netWorth['native']['native_balance'] = bcadd($nativeBalance, $netWorth['native']['native_balance']);
|
||||||
}
|
}
|
||||||
$cache->store($netWorth);
|
$cache->store($netWorth);
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $netWorth;
|
return $netWorth;
|
||||||
}
|
}
|
||||||
|
@@ -118,6 +118,7 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@@ -167,6 +168,7 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
$return[$currencyId]['native_sum'] = bcadd($return[$currencyId]['native_sum'], bcmul($nativeAverage, (string)$total));
|
$return[$currencyId]['native_sum'] = bcadd($return[$currencyId]['native_sum'], bcmul($nativeAverage, (string)$total));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
@@ -67,6 +67,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
|||||||
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $availableBudget->amount);
|
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $availableBudget->amount);
|
||||||
$return[$currencyId]['native_amount'] = bcadd($return[$currencyId]['native_amount'], $nativeAmount);
|
$return[$currencyId]['native_amount'] = bcadd($return[$currencyId]['native_amount'], $nativeAmount);
|
||||||
}
|
}
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
@@ -193,6 +193,7 @@ class AccountBalanceGrouped
|
|||||||
$convertedKey = sprintf('native_%s', $key);
|
$convertedKey = sprintf('native_%s', $key);
|
||||||
$this->data[$currencyId][$period][$convertedKey] = bcadd($this->data[$currencyId][$period][$convertedKey], $amountConverted);
|
$this->data[$currencyId][$period][$convertedKey] = bcadd($this->data[$currencyId][$period][$convertedKey], $amountConverted);
|
||||||
}
|
}
|
||||||
|
$converter->summarize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAccounts(Collection $accounts): void
|
public function setAccounts(Collection $accounts): void
|
||||||
|
@@ -37,6 +37,8 @@ use Illuminate\Support\Facades\Log;
|
|||||||
class ExchangeRateConverter
|
class ExchangeRateConverter
|
||||||
{
|
{
|
||||||
// use ConvertsExchangeRates;
|
// use ConvertsExchangeRates;
|
||||||
|
private int $queryCount = 0;
|
||||||
|
private array $prepared = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
@@ -48,6 +50,56 @@ class ExchangeRateConverter
|
|||||||
return bcmul($amount, $rate);
|
return bcmul($amount, $rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function prepare(TransactionCurrency $from, TransactionCurrency $to, Carbon $start, Carbon $end): void
|
||||||
|
{
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
Log::debug(sprintf('Preparing for %s to %s between %s and %s', $from->code, $to->code, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||||
|
$set = auth()->user()
|
||||||
|
->currencyExchangeRates()
|
||||||
|
->where('from_currency_id', $from->id)
|
||||||
|
->where('to_currency_id', $to->id)
|
||||||
|
->where('date', '<=', $end->format('Y-m-d'))
|
||||||
|
->where('date', '>=', $start->format('Y-m-d'))
|
||||||
|
->orderBy('date', 'DESC')->get()
|
||||||
|
;
|
||||||
|
$fallback = $this->getRate($from, $to, $start);
|
||||||
|
++$this->queryCount;
|
||||||
|
if (0 === $set->count()) {
|
||||||
|
Log::debug('No rates found in this period.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Je moet een fallback rate hebben van voor de periode zodat je die altijd kan gebruiken.
|
||||||
|
* Dus de laatste met de meest recente datum voor je periode.
|
||||||
|
* Dan moet je gaan loopen per dag, en als er iets in $temp zit toevallig gebruik je die.
|
||||||
|
*/
|
||||||
|
$temp = [];
|
||||||
|
$count = 0;
|
||||||
|
foreach ($set as $rate) {
|
||||||
|
$date = $rate->date->format('Y-m-d');
|
||||||
|
$temp[$date] ??= [
|
||||||
|
$from->id => [
|
||||||
|
$to->id => $rate->rate,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
++$count;
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('Found %d rates in this period.', $count));
|
||||||
|
$currentStart = clone $start;
|
||||||
|
while ($currentStart->lte($end)) {
|
||||||
|
$currentDate = $currentStart->format('Y-m-d');
|
||||||
|
$this->prepared[$currentDate] ??= [];
|
||||||
|
$fallback = $temp[$currentDate][$from->id][$to->id] ?? $fallback;
|
||||||
|
if (0 === count($this->prepared[$currentDate])) {
|
||||||
|
// fill from temp or fallback or from temp (see before)
|
||||||
|
$this->prepared[$currentDate][$from->id][$to->id] = $fallback;
|
||||||
|
}
|
||||||
|
$currentStart->addDay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
@@ -58,6 +110,11 @@ class ExchangeRateConverter
|
|||||||
return '0' === $rate ? '1' : $rate;
|
return '0' === $rate ? '1' : $rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function summarize(): void
|
||||||
|
{
|
||||||
|
Log::info(sprintf('ExchangeRateConverter ran %d queries.', $this->queryCount));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
@@ -94,6 +151,12 @@ class ExchangeRateConverter
|
|||||||
{
|
{
|
||||||
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
|
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
|
||||||
|
|
||||||
|
// perhaps the rate has been cached during this particular run
|
||||||
|
$preparedRate = $this->prepared[$date][$from][$to] ?? null;
|
||||||
|
if (null !== $preparedRate) {
|
||||||
|
return $preparedRate;
|
||||||
|
}
|
||||||
|
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($key);
|
$cache->addProperty($key);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
@@ -115,8 +178,23 @@ class ExchangeRateConverter
|
|||||||
->orderBy('date', 'DESC')
|
->orderBy('date', 'DESC')
|
||||||
->first()
|
->first()
|
||||||
;
|
;
|
||||||
|
++$this->queryCount;
|
||||||
$rate = (string) $result?->rate;
|
$rate = (string) $result?->rate;
|
||||||
$cache->store($rate);
|
$cache->store($rate);
|
||||||
|
|
||||||
|
// if the rate has not been cached during this particular run, save it
|
||||||
|
$this->prepared[$date] ??= [
|
||||||
|
$from => [
|
||||||
|
$to => $rate,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
// also save the exchange rate the other way around:
|
||||||
|
$this->prepared[$date] ??= [
|
||||||
|
$to => [
|
||||||
|
$from => bcdiv('1', $rate),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
if ('' === $rate) {
|
if ('' === $rate) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -168,6 +246,7 @@ class ExchangeRateConverter
|
|||||||
return (int) $cache->get();
|
return (int) $cache->get();
|
||||||
}
|
}
|
||||||
$euro = TransactionCurrency::whereCode('EUR')->first();
|
$euro = TransactionCurrency::whereCode('EUR')->first();
|
||||||
|
++$this->queryCount;
|
||||||
if (null === $euro) {
|
if (null === $euro) {
|
||||||
throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.');
|
throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.');
|
||||||
}
|
}
|
||||||
|
@@ -79,6 +79,7 @@ class SummaryBalanceGrouped
|
|||||||
}
|
}
|
||||||
app('log')->debug(sprintf('this->amounts[%s][native] is now %s', $key, $this->amounts[$key]['native']));
|
app('log')->debug(sprintf('this->amounts[%s][native] is now %s', $key, $this->amounts[$key]['native']));
|
||||||
app('log')->debug(sprintf('this->amounts[%s][native] is now %s', self::SUM, $this->amounts[$key]['native']));
|
app('log')->debug(sprintf('this->amounts[%s][native] is now %s', self::SUM, $this->amounts[$key]['native']));
|
||||||
|
$converter->summarize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function groupData(): array
|
public function groupData(): array
|
||||||
|
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Support;
|
namespace FireflyIII\Support;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
@@ -157,7 +156,7 @@ class Steam
|
|||||||
// use foreign amount:
|
// use foreign amount:
|
||||||
$amount = $foreignModified;
|
$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);
|
$currentBalance = bcadd($currentBalance, $amount);
|
||||||
$carbon = new Carbon($entry->date, config('app.timezone'));
|
$carbon = new Carbon($entry->date, config('app.timezone'));
|
||||||
$date = $carbon->format('Y-m-d');
|
$date = $carbon->format('Y-m-d');
|
||||||
@@ -315,6 +314,7 @@ class Steam
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cache->store($balances);
|
$cache->store($balances);
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $balances;
|
return $balances;
|
||||||
}
|
}
|
||||||
@@ -327,15 +327,15 @@ class Steam
|
|||||||
*/
|
*/
|
||||||
public function balanceConverted(Account $account, Carbon $date, TransactionCurrency $native): string
|
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));
|
// 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:
|
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($account->id);
|
$cache->addProperty($account->id);
|
||||||
$cache->addProperty('balance');
|
$cache->addProperty('balance');
|
||||||
$cache->addProperty($date);
|
$cache->addProperty($date);
|
||||||
$cache->addProperty($native->id);
|
$cache->addProperty($native->id);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return $cache->get();
|
// Log::debug('Cached!');
|
||||||
|
// return $cache->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var AccountRepositoryInterface $repository */
|
/** @var AccountRepositoryInterface $repository */
|
||||||
@@ -343,6 +343,7 @@ class Steam
|
|||||||
$currency = $repository->getAccountCurrency($account);
|
$currency = $repository->getAccountCurrency($account);
|
||||||
$currency = null === $currency ? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup) : $currency;
|
$currency = null === $currency ? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup) : $currency;
|
||||||
if ($native->id === $currency->id) {
|
if ($native->id === $currency->id) {
|
||||||
|
// Log::debug('No conversion necessary!');
|
||||||
return $this->balance($account, $date);
|
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)
|
// 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
|
// but we need to convert each transaction separately because the date difference may
|
||||||
// incur huge currency changes.
|
// incur huge currency changes.
|
||||||
|
$start = clone $date;
|
||||||
|
$end = clone $date;
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
foreach ($new as $set) {
|
foreach ($new as $set) {
|
||||||
foreach ($set as $transaction) {
|
foreach ($set as $transaction) {
|
||||||
$date = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date']);
|
$currentDate = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date']);
|
||||||
if (false === $date) {
|
if (false === $currentDate) {
|
||||||
$date = today(config('app.timezone'));
|
$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);
|
$convertedAmount = bcmul($transaction['amount'], $rate);
|
||||||
$balance = bcadd($balance, $convertedAmount);
|
$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)
|
// add virtual balance (also needs conversion)
|
||||||
$virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance;
|
$virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance;
|
||||||
$virtual = $converter->convert($currency, $native, $account->created_at, $virtual);
|
$virtual = $converter->convert($currency, $native, $account->created_at, $virtual);
|
||||||
$balance = bcadd($balance, $virtual);
|
$balance = bcadd($balance, $virtual);
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
$cache->store($balance);
|
$cache->store($balance);
|
||||||
|
$converter->summarize();
|
||||||
|
|
||||||
return $balance;
|
return $balance;
|
||||||
}
|
}
|
||||||
|
@@ -192,6 +192,7 @@ class BillTransformer extends AbstractTransformer
|
|||||||
$date = null === $startParam ? today() : clone $startParam;
|
$date = null === $startParam ? today() : clone $startParam;
|
||||||
|
|
||||||
$nextExpectedMatchDiff = $this->getNextExpectedMatchDiff($nextExpectedMatch, $payDates);
|
$nextExpectedMatchDiff = $this->getNextExpectedMatchDiff($nextExpectedMatch, $payDates);
|
||||||
|
$this->converter->summarize();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $bill->id,
|
'id' => $bill->id,
|
||||||
|
@@ -193,6 +193,7 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
$savePerMonth = $this->getSuggestedMonthlyAmount($currentAmount, $targetAmount, $piggyBank->startdate, $piggyBank->targetdate);
|
$savePerMonth = $this->getSuggestedMonthlyAmount($currentAmount, $targetAmount, $piggyBank->startdate, $piggyBank->targetdate);
|
||||||
$nativeSavePerMonth = $this->converter->convert($this->default, $currency, today(), $savePerMonth);
|
$nativeSavePerMonth = $this->converter->convert($this->default, $currency, today(), $savePerMonth);
|
||||||
}
|
}
|
||||||
|
$this->converter->summarize();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (string)$piggyBank->id,
|
'id' => (string)$piggyBank->id,
|
||||||
|
@@ -161,6 +161,7 @@ class TransactionGroupTransformer extends AbstractTransformer
|
|||||||
$foreignAmount = app('steam')->positive($transaction['foreign_amount']);
|
$foreignAmount = app('steam')->positive($transaction['foreign_amount']);
|
||||||
$nativeForeignAmount = $this->converter->convert($this->default, $this->currencies[$foreignCurrencyId], $transaction['date'], $foreignAmount);
|
$nativeForeignAmount = $this->converter->convert($this->default, $this->currencies[$foreignCurrencyId], $transaction['date'], $foreignAmount);
|
||||||
}
|
}
|
||||||
|
$this->converter->summarize();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'user' => (string)$transaction['user_id'],
|
'user' => (string)$transaction['user_id'],
|
||||||
|
Reference in New Issue
Block a user