first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

207
class/class.CNB.php Normal file
View File

@@ -0,0 +1,207 @@
<?php
use KupShop\I18nBundle\Entity\Currency;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
class CNB
{
private static $url = 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt';
// Allowed difference in percent between old and new currency
private static $allow_difference = 10;
/**
* @param false $admin
*
* @throws Exception
*/
public static function updateCurrencies($admin = false)
{
$new_currencies = self::getSharedCurrencies();
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$em = ServiceContainer::getService('doctrine.orm.entity_manager');
$currencies = $currencyContext->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);
}
}