getAll(); $defaultCurrency = $currencyContext->getDefaultId(); if ($defaultCurrency == 'CZK') { $conversionRate = DecimalConstants::one(); } else { $conversionRate = DecimalConstants::one()->div($new_currencies[$defaultCurrency]); } $new_currencies['CZK'] = DecimalConstants::one(); /** @var Currency $currency */ foreach ($currencies as $currency) { if ($currency->getSync() == 'Y') { $currency_name = $currency->getId(); if (!empty($new_currencies[$currency_name])) { $value = self::prepPrice($new_currencies[$currency_name]); if (!$currency->getCorrections()->isZero()) { $value = $value->add(self::prepPrice($currency->getCorrections())); } $value = $value->mul($conversionRate); if ($currency->getRate()->isPositive()) { $old_currency = $currency->getRate()->asFloat(); $new_currency = $value->asFloat(); $difference = ($old_currency - $new_currency) / ($old_currency / 100); if (!$admin && abs($difference) > self::$allow_difference) { throw new Exception('Aktualizace kurzu měn selhala. Měna "'.$currency_name.'", rozdíl '.round($difference, 2)." % !!, stará = '{$old_currency}', nová = '{$new_currency}'"); } } $currency->setRate($value); $currency->setSyncDateUpdated(); } } } $em->flush(); $dispatcher = ServiceContainer::getService('event_dispatcher'); $dispatcher->dispatch(new KupShop\KupShopBundle\Event\CNBSyncEvent(), KupShop\KupShopBundle\Event\CNBSyncEvent::NAME); } public static function prepPrice($price, $div = null) { $price = toDecimal(floatval(str_replace(',', '.', trim($price)))); if ($div) { $div = toDecimal(floatval(str_replace(',', '.', trim($div)))); if ($div->isPositive()) { $price = $price->div($div); } } return $price; } /** * @throws Exception */ public static function getCurrency($currency): Decimal { if ($currency === 'CZK') { return Decimal::create(1, 20); } $currencies = static::getCurrencies(); if (!isset($currencies[$currency])) { throw new Exception("CNB: Undefined currency: {$currency}"); } return $currencies[$currency]; } /** * Download actual CNB currencies and update on shared DB. * * @throws Exception */ public static function updateSharedCurrencies(): void { $currencies = self::downloadCurrencies(); foreach ($currencies as $id => $rate) { sqlQuery( 'INSERT INTO kupshop_shared.cnb_currencies (id,rate) VALUES (:id, :rate) ON DUPLICATE KEY UPDATE id=:id, rate=:rate', [ 'id' => $id, 'rate' => $rate, ] ); } } /** * @return Decimal[] * * @throws Exception */ public static function getCurrencies(): array { static $currencies = null; if (!$currencies) { $currencies = static::getSharedCurrencies(); } return $currencies; } /** * @return Decimal[] * * @throws Exception */ private static function downloadCurrencies(): array { $currencies_file = self::downloadFile(); $currencies = []; foreach ($currencies_file as $v) { $h = explode('|', $v); if (!empty($h[3])) { $currencies[$h[3]] = self::prepPrice($h[4], $h[2]); } } return $currencies; } /** * Get CNB currencies from shared db. */ private static function getSharedCurrencies(): array { $result = sqlQueryBuilder()->select('id, rate') ->from('kupshop_shared.cnb_currencies') ->execute(); $currencies = []; foreach ($result as $row) { $currencies[$row['id']] = Decimal::create($row['rate'], 20); } return $currencies; } /** * @throws Exception */ private static function downloadFile(): array { $file = file(self::$url); if ($file === false) { throw new Exception('Soubor CNB nedostupny.'); } return $file; } public static function setUrl(string $url) { self::$url = $url; } /** * @throws Exception */ public static function convertPrice(Decimal $price, $from, $to) { $exchange_rate = self::getCurrency($from)->div(self::getCurrency($to)); return $price->mul($exchange_rate); } }