mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Expand and fix account API
This commit is contained in:
		| @@ -44,12 +44,18 @@ class ExchangeRateConverter | ||||
|     private array $prepared        = []; | ||||
|     private int   $queryCount      = 0; | ||||
| 
 | ||||
| 
 | ||||
|     public function enabled(): bool | ||||
|     { | ||||
|         return false !== config('cer.enabled'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function convert(TransactionCurrency $from, TransactionCurrency $to, Carbon $date, string $amount): string | ||||
|     { | ||||
|         if (false === config('cer.enabled')) { | ||||
|         if (false === $this->enabled()) { | ||||
|             Log::debug('ExchangeRateConverter: disabled, return amount as is.'); | ||||
| 
 | ||||
|             return $amount; | ||||
| @@ -64,7 +70,7 @@ class ExchangeRateConverter | ||||
|      */ | ||||
|     public function getCurrencyRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string | ||||
|     { | ||||
|         if (false === config('cer.enabled')) { | ||||
|         if (false === $this->enabled()) { | ||||
|             Log::debug('ExchangeRateConverter: disabled, return "1".'); | ||||
| 
 | ||||
|             return '1'; | ||||
| @@ -79,8 +85,8 @@ class ExchangeRateConverter | ||||
|      */ | ||||
|     private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string | ||||
|     { | ||||
|         $key    = $this->getCacheKey($from, $to, $date); | ||||
|         $res    = Cache::get($key, null); | ||||
|         $key = $this->getCacheKey($from, $to, $date); | ||||
|         $res = Cache::get($key, null); | ||||
| 
 | ||||
|         // find in cache
 | ||||
|         if (null !== $res) { | ||||
| @@ -90,7 +96,7 @@ class ExchangeRateConverter | ||||
|         } | ||||
| 
 | ||||
|         // find in database
 | ||||
|         $rate   = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d')); | ||||
|         $rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d')); | ||||
|         if (null !== $rate) { | ||||
|             Cache::forever($key, $rate); | ||||
|             Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d'))); | ||||
| @@ -99,7 +105,7 @@ class ExchangeRateConverter | ||||
|         } | ||||
| 
 | ||||
|         // find reverse in database
 | ||||
|         $rate   = $this->getFromDB($to->id, $from->id, $date->format('Y-m-d')); | ||||
|         $rate = $this->getFromDB($to->id, $from->id, $date->format('Y-m-d')); | ||||
|         if (null !== $rate) { | ||||
|             $rate = bcdiv('1', $rate); | ||||
|             Cache::forever($key, $rate); | ||||
| @@ -132,7 +138,7 @@ class ExchangeRateConverter | ||||
|         if ($from === $to) { | ||||
|             return '1'; | ||||
|         } | ||||
|         $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; | ||||
| @@ -142,7 +148,7 @@ class ExchangeRateConverter | ||||
|             return $preparedRate; | ||||
|         } | ||||
| 
 | ||||
|         $cache        = new CacheProperties(); | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($key); | ||||
|         if ($cache->has()) { | ||||
|             $rate = $cache->get(); | ||||
| @@ -155,16 +161,15 @@ class ExchangeRateConverter | ||||
|         } | ||||
| 
 | ||||
|         /** @var null|CurrencyExchangeRate $result */ | ||||
|         $result       = auth()->user() | ||||
|             ->currencyExchangeRates() | ||||
|             ->where('from_currency_id', $from) | ||||
|             ->where('to_currency_id', $to) | ||||
|             ->where('date', '<=', $date) | ||||
|             ->orderBy('date', 'DESC') | ||||
|             ->first() | ||||
|         ; | ||||
|         $result = auth()->user() | ||||
|                         ->currencyExchangeRates() | ||||
|                         ->where('from_currency_id', $from) | ||||
|                         ->where('to_currency_id', $to) | ||||
|                         ->where('date', '<=', $date) | ||||
|                         ->orderBy('date', 'DESC') | ||||
|                         ->first(); | ||||
|         ++$this->queryCount; | ||||
|         $rate         = (string) $result?->rate; | ||||
|         $rate = (string) $result?->rate; | ||||
| 
 | ||||
|         if ('' === $rate) { | ||||
|             app('log')->debug(sprintf('ExchangeRateConverter: Found no rate for #%d->#%d (%s) in the DB.', $from, $to, $date)); | ||||
| @@ -204,13 +209,13 @@ class ExchangeRateConverter | ||||
|         if ($euroId === $currency->id) { | ||||
|             return '1'; | ||||
|         } | ||||
|         $rate   = $this->getFromDB($currency->id, $euroId, $date->format('Y-m-d')); | ||||
|         $rate = $this->getFromDB($currency->id, $euroId, $date->format('Y-m-d')); | ||||
| 
 | ||||
|         if (null !== $rate) { | ||||
|             //            app('log')->debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate));
 | ||||
|             return $rate; | ||||
|         } | ||||
|         $rate   = $this->getFromDB($euroId, $currency->id, $date->format('Y-m-d')); | ||||
|         $rate = $this->getFromDB($euroId, $currency->id, $date->format('Y-m-d')); | ||||
|         if (null !== $rate) { | ||||
|             return bcdiv('1', $rate); | ||||
|             //            app('log')->debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate));
 | ||||
| @@ -239,7 +244,7 @@ class ExchangeRateConverter | ||||
|         if ($cache->has()) { | ||||
|             return (int) $cache->get(); | ||||
|         } | ||||
|         $euro  = TransactionCurrency::whereCode('EUR')->first(); | ||||
|         $euro = TransactionCurrency::whereCode('EUR')->first(); | ||||
|         ++$this->queryCount; | ||||
|         if (null === $euro) { | ||||
|             throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.'); | ||||
| @@ -254,21 +259,20 @@ class ExchangeRateConverter | ||||
|      */ | ||||
|     public function prepare(TransactionCurrency $from, TransactionCurrency $to, Carbon $start, Carbon $end): void | ||||
|     { | ||||
|         if (false === config('cer.enabled')) { | ||||
|         if (false === $this->enabled()) { | ||||
|             return; | ||||
|         } | ||||
|         Log::debug('prepare()'); | ||||
|         $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() | ||||
|         ; | ||||
|         $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(); | ||||
|         ++$this->queryCount; | ||||
|         if (0 === $set->count()) { | ||||
|             Log::debug('No prepared rates found in this period, use the fallback'); | ||||
| @@ -282,10 +286,10 @@ class ExchangeRateConverter | ||||
|         $this->isPrepared = true; | ||||
| 
 | ||||
|         // so there is a fallback just in case. Now loop the set of rates we DO have.
 | ||||
|         $temp             = []; | ||||
|         $count            = 0; | ||||
|         $temp  = []; | ||||
|         $count = 0; | ||||
|         foreach ($set as $rate) { | ||||
|             $date = $rate->date->format('Y-m-d'); | ||||
|             $date        = $rate->date->format('Y-m-d'); | ||||
|             $temp[$date] ??= [ | ||||
|                 $from->id => [ | ||||
|                     $to->id => $rate->rate, | ||||
| @@ -294,11 +298,11 @@ class ExchangeRateConverter | ||||
|             ++$count; | ||||
|         } | ||||
|         Log::debug(sprintf('Found %d rates in this period.', $count)); | ||||
|         $currentStart     = clone $start; | ||||
|         $currentStart = clone $start; | ||||
|         while ($currentStart->lte($end)) { | ||||
|             $currentDate = $currentStart->format('Y-m-d'); | ||||
|             $currentDate                  = $currentStart->format('Y-m-d'); | ||||
|             $this->prepared[$currentDate] ??= []; | ||||
|             $fallback    = $temp[$currentDate][$from->id][$to->id] ?? $this->fallback[$from->id][$to->id] ?? '0'; | ||||
|             $fallback                     = $temp[$currentDate][$from->id][$to->id] ?? $this->fallback[$from->id][$to->id] ?? '0'; | ||||
|             if (0 === count($this->prepared[$currentDate]) && 0 !== bccomp('0', $fallback)) { | ||||
|                 // fill from temp or fallback or from temp (see before)
 | ||||
|                 $this->prepared[$currentDate][$from->id][$to->id] = $fallback; | ||||
| @@ -329,7 +333,7 @@ class ExchangeRateConverter | ||||
| 
 | ||||
|     public function summarize(): void | ||||
|     { | ||||
|         if (false === config('cer.enabled')) { | ||||
|         if (false === $this->enabled()) { | ||||
|             return; | ||||
|         } | ||||
|         Log::debug(sprintf('ExchangeRateConverter ran %d queries.', $this->queryCount)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user