/** * Load rates by date * * @param ICurrency[] $currencies * @param \DateTime|null $date * * @return ICurrencyRate[] * * @throws NoRatesAvailableForDateException * @throws BadXMLQueryException */ public function getRates($currencies, \DateTime $date = null) { $currencyCodes = []; foreach ($currencies as $currency) { $currencyCodes[] = $currency->getCode() . '=X'; } if (null === $date) { $date = new \DateTime(); } $queryData = ['q' => 'select * from yahoo.finance.historicaldata where symbol in ("' . implode('","', $currencyCodes) . '") and startDate = "' . $date->format('Y-m-d') . '" and endDate = "' . $date->format('Y-m-d') . '"', 'env' => 'store://datatables.org/alltableswithkeys']; $query = self::BASE_URL . '?' . http_build_query($queryData); $ratesXml = $this->xmlLoader->load($query); if (false === $ratesXml) { throw new BadXMLQueryException($query, $this); } if (0 === count($ratesXml->results->quote)) { throw new NoRatesAvailableForDateException($date, $this); } $rates = []; /** @var \SimpleXMLElement $rate */ foreach ($ratesXml->results->quote as $quote) { $quote = (array) $quote; $code = (string) $quote['@attributes']['Symbol']; $code = str_replace('%3dX', '', $code); $rate = $quote['Close']; $rates[$code] = $this->currencyRateManager->getNewInstance($this->currencyManager->getCurrency($code), $this, $date, (double) $rate, 1); } return $rates; }
/** * Load rates by date * * @param ICurrency[] $currencies * @param \DateTime $date * @throws \Exception * @return ICurrencyRate[] */ public function getRates($currencies, \DateTime $date = null) { if ($date === null) { $date = new \DateTime('now'); } if ($date->format('Y-m-d') !== date('Y-m-d')) { throw new NoRatesAvailableForDateException($date, $this); } $ratesXml = $this->xmlLoader->load(self::BASE_URL); if (false === $ratesXml) { throw new BadXMLQueryException(self::BASE_URL, $this); } $result = array(); foreach ($currencies as $currency) { $rate = null; foreach ($ratesXml->Cube->Cube->Cube as $ecbRate) { if ((string) $ecbRate['currency'] === $currency->getCode()) { $rate = (double) $ecbRate['rate']; break; } } if (!$rate) { continue; } $rate = $this->currencyRateManager->getNewInstance($this->currencyManager->getCurrency($currency->getCode()), $this, $date, $rate, 1); $result[$currency->getCode()] = $rate; } return $result; }
public function setUp() { $currencies = []; $currencies['RUB'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['RUB']->method('getCode')->willReturn('RUB'); $currencies['EUR'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['EUR']->method('getCode')->willReturn('EUR'); $currencies['USD'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['USD']->method('getCode')->willReturn('USD'); $this->currencyRateManager = $this->getMock('\\RedCode\\Currency\\Rate\\ICurrencyRateManager'); $this->currencyRateManager->method('getNewInstance')->will($this->returnCallback(function (ICurrency $currency, ICurrencyRateProvider $provider, \DateTime $date, $rateValue, $nominal) { $rate = $this->getMock('\\RedCode\\Currency\\Rate\\ICurrencyRate'); $rate->method('getDate')->willReturn($date); $rate->method('getRate')->willReturn($rateValue); $rate->method('getNominal')->willReturn($nominal); $rate->method('getProviderName')->willReturn($provider->getName()); $rate->method('getCurrency')->willReturn($currency); return $rate; })); $this->currencyManager = $this->getMock('\\RedCode\\Currency\\ICurrencyManager'); $this->currencyManager->method('getCurrency')->will($this->returnCallback(function ($name) use($currencies) { $name = strtoupper($name); if (isset($currencies[$name])) { return $currencies[$name]; } return null; })); $this->currencyManager->method('getAll')->will($this->returnCallback(function () use($currencies) { return array_values($currencies); })); }
/** * Load rates by date * * @param ICurrency[] $currencies * @param \DateTime $date * @return ICurrencyRate[] */ public function getRates($currencies, \DateTime $date = null) { if ($date === null) { $date = new \DateTime('now'); } $client = new \SoapClient("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL"); $curs = $client->GetCursOnDate(array("On_date" => $date->format('Y-m-d'))); $ratesXml = new \SimpleXMLElement($curs->GetCursOnDateResult->any); $result = array(); foreach ($currencies as $currency) { $rateCbr = $ratesXml->xpath('ValuteData/ValuteCursOnDate/VchCode[.="' . $currency->getCode() . '"]/parent::*'); if (empty($rateCbr)) { continue; } $rate = $this->currencyRateManager->getNewInstance($this->currencyManager->getCurrency($currency->getCode()), $this, $date, (double) $rateCbr[0]->Vcurs, (int) $rateCbr[0]->Vnom); $result[$currency->getCode()] = $rate; } return $result; }
/** * Get currency rate * * @param ICurrency $currency * @param ICurrencyRateProvider $provider * @param null $date * @return float */ private function getRate(ICurrency $currency, ICurrencyRateProvider $provider, $date = null) { if ($currency->getCode() != $provider->getBaseCurrency()->getCode()) { $rate = $this->rateManager->getRate($currency, $provider, $date); if (!$rate) { return null; } if (!$provider->isInversed()) { $rate = $rate->getNominal() * $rate->getRate(); } else { $rate = $rate->getNominal() / $rate->getRate(); } } else { $rate = 1.0; } return $rate; }
public function setUp() { $currencies = []; $currencies['RUB'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['RUB']->method('getCode')->willReturn('RUB'); $currencies['EUR'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['EUR']->method('getCode')->willReturn('EUR'); $currencies['USD'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['USD']->method('getCode')->willReturn('USD'); $currencies['GBP'] = $this->getMock('\\RedCode\\Currency\\ICurrency'); $currencies['GBP']->method('getCode')->willReturn('GBP'); $inversedProvider = $this->getMock('\\RedCode\\Currency\\Rate\\Provider\\ICurrencyRateProvider'); $inversedProvider->method('getName')->willReturn($this->inversedProviderName); $inversedProvider->method('getBaseCurrency')->willReturn($currencies['RUB']); $inversedProvider->method('isInversed')->willReturn(true); $notInversedProvider = $this->getMock('\\RedCode\\Currency\\Rate\\Provider\\ICurrencyRateProvider'); $notInversedProvider->method('getName')->willReturn($this->notInversedProviderName); $notInversedProvider->method('getBaseCurrency')->willReturn($currencies['EUR']); $notInversedProvider->method('isInversed')->willReturn(false); $factory = new ProviderFactory([$inversedProvider, $notInversedProvider]); $this->currencyRateManager = $this->getMock('\\RedCode\\Currency\\Rate\\ICurrencyRateManager'); $this->currencyRateManager->method('getNewInstance')->will($this->returnCallback(function (ICurrency $currency, ICurrencyRateProvider $provider, \DateTime $date, $rateValue, $nominal) { $rate = $this->getMock('\\RedCode\\Currency\\Rate\\ICurrencyRate'); $rate->method('getDate')->willReturn($date); $rate->method('getRate')->willReturn($rateValue); $rate->method('getNominal')->willReturn($nominal); $rate->method('getProviderName')->willReturn($provider->getName()); $rate->method('getCurrency')->willReturn($currency); return $rate; })); $this->currencyRateManager->method('getRate')->will($this->returnCallback(function (ICurrency $currency, ICurrencyRateProvider $provider, \DateTime $rateDate = null) { switch (true) { case $provider->getName() == $this->inversedProviderName && $currency->getCode() == 'EUR': $rateValue = 40; break; case $provider->getName() == $this->inversedProviderName && $currency->getCode() == 'USD': $rateValue = 30; break; case $provider->getName() == $this->notInversedProviderName && $currency->getCode() == 'RUB': $rateValue = 40; break; case $provider->getName() == $this->notInversedProviderName && $currency->getCode() == 'USD': $rateValue = 1.13; break; default: return null; } $rate = $this->getMock('\\RedCode\\Currency\\Rate\\ICurrencyRate'); $rate->method('getDate')->willReturn(!empty($rateDate) ? $rateDate : new \DateTime()); $rate->method('getRate')->willReturn($rateValue); $rate->method('getNominal')->willReturn(1); $rate->method('getProviderName')->willReturn($provider->getName()); $rate->method('getCurrency')->willReturn($currency); return $rate; })); $this->currencyManager = $this->getMock('\\RedCode\\Currency\\ICurrencyManager'); $this->currencyManager->method('getCurrency')->will($this->returnCallback(function ($name) use($currencies) { $name = strtoupper($name); if (isset($currencies[$name])) { return $currencies[$name]; } return null; })); $this->currencyManager->method('getAll')->will($this->returnCallback(function () use($currencies) { return array_values($currencies); })); $this->currencyConverter = new CurrencyConverter($factory, $this->currencyRateManager, $this->currencyManager); $this->assertInstanceOf('\\RedCode\\Currency\\Rate\\CurrencyConverter', $this->currencyConverter); }