2626use App \Settings \SystemSettings \LocalizationSettings ;
2727use Brick \Math \BigDecimal ;
2828use Brick \Math \RoundingMode ;
29+ use Exchanger \Exception \UnsupportedCurrencyPairException ;
30+ use Exchanger \Exception \UnsupportedExchangeQueryException ;
2931use Swap \Swap ;
3032
3133class ExchangeRateUpdater
@@ -39,15 +41,21 @@ public function __construct(private LocalizationSettings $localizationSettings,
3941 */
4042 public function update (Currency $ currency ): Currency
4143 {
42- //Currency pairs are always in the format "BASE/QUOTE"
43- $ rate = $ this ->swap ->latest ($ this ->localizationSettings ->baseCurrency .'/ ' .$ currency ->getIsoCode ());
44- //The rate says how many quote units are worth one base unit
45- //So we need to invert it to get the exchange rate
46-
47- $ rate_bd = BigDecimal::of ($ rate ->getValue ());
48- $ rate_inverted = BigDecimal::one ()->dividedBy ($ rate_bd , Currency::PRICE_SCALE , RoundingMode::HALF_UP );
49-
50- $ currency ->setExchangeRate ($ rate_inverted );
44+ try {
45+ //Try it in the direction QUOTE/BASE first, as most providers provide rates in this direction
46+ $ rate = $ this ->swap ->latest ($ currency ->getIsoCode ().'/ ' .$ this ->localizationSettings ->baseCurrency );
47+ $ effective_rate = BigDecimal::of ($ rate ->getValue ());
48+ } catch (UnsupportedCurrencyPairException |UnsupportedExchangeQueryException $ exception ) {
49+ //Otherwise try to get it inverse and calculate it ourselfes, from the format "BASE/QUOTE"
50+ $ rate = $ this ->swap ->latest ($ this ->localizationSettings ->baseCurrency .'/ ' .$ currency ->getIsoCode ());
51+ //The rate says how many quote units are worth one base unit
52+ //So we need to invert it to get the exchange rate
53+
54+ $ rate_bd = BigDecimal::of ($ rate ->getValue ());
55+ $ effective_rate = BigDecimal::one ()->dividedBy ($ rate_bd , Currency::PRICE_SCALE , RoundingMode::HALF_UP );
56+ }
57+
58+ $ currency ->setExchangeRate ($ effective_rate );
5159
5260 return $ currency ;
5361 }
0 commit comments