public static function CurrenyRatesUpdate() { ini_set('max_execution_time', 150000); ini_set("memory_limit", "128M"); $max_date_sql = "select MAX(day) day from currency_rates"; $max_date_res = Yii::app()->db->createCommand($max_date_sql)->queryAll(true); //var_dump($max_date_res[0]["day"]); //exit; $start_date = date($max_date_res[0]["day"]); // date("2000-01-01"); // date('Y-m-d', strtotime('-1 years')); $start_date = strtotime($start_date); $start_date = strtotime("+1 day", $start_date); $start_date = date('Y-m-d', $start_date); $currencies = ['EUR', 'JPY', 'GBP', 'AUD', 'CHF', 'CAD', 'MXN', 'CNY', 'CNH', 'NZD', 'SEK', 'RUB', 'DKK', 'NOK', 'HKD', 'SGD', 'TRY', 'KRW', 'ZAR', 'BRL', 'INR']; while (strtotime($start_date) <= strtotime("now")) { $existing_rate = CurrencyRates::model()->findByAttributes(['day' => $start_date]); if (count($existing_rate) == 0) { $currency_rates = new CurrencyRates(); $currency_rates->day = $start_date; foreach ($currencies as $cur) { $currency_rates->{$cur} = 1; $Url = "http://currencies.apps.grandtrunk.net/getrate/" . $start_date . "/" . $cur . "/USD"; $get_rate = Self::url_get_contents($Url); if ($get_rate >= 0) { $currency_rates->{$cur} = $get_rate; } } $currency_rates->save(); } ///+one day// $start_date = strtotime($start_date); $start_date = strtotime("+1 day", $start_date); $start_date = date('Y-m-d', $start_date); } }
/** * Convert an amount in USD to a particular currency * * This is grossly rudimentary and likely wildly inaccurate. * This mimics the hard-coded values used by the WMF to convert currencies * for validation on the front-end on the first step landing pages of their * donation process - the idea being that we can get a close approximation * of converted currencies to ensure that contributors are not going above * or below the price ceiling/floor, even if they are using a non-US currency. * * In reality, this probably ought to use some sort of webservice to get real-time * conversion rates. * * @param float $amount * @param string $currency * @return float * @throws UnexpectedValueException */ public static function convert($amount, $currency) { $rates = CurrencyRates::getCurrencyRates(); $code = strtoupper($currency); if (array_key_exists($code, $rates)) { return $amount * $rates[$code]; } throw new UnexpectedValueException('Bad programmer! Bad currency made it too far through the portcullis'); }
/** * Integration test to verify that the Amazon gateway converts Canadian * dollars before redirecting * * @dataProvider canadaLanguageProvider */ function testCanadianDollarConversion($language) { $init = $this->getDonorTestData('CA'); unset($init['order_id']); $init['payment_method'] = 'amazon'; $init['ffname'] = 'amazon'; $init['language'] = $language; $rates = CurrencyRates::getCurrencyRates(); $cadRate = $rates['CAD']; $expectedAmount = floor($init['amount'] / $cadRate); TestingAmazonAdapter::$fakeGlobals = array('FallbackCurrency' => 'USD', 'NotifyOnConvert' => true); $expectedNotification = wfMessage('donate_interface-fallback-currency-notice', 'USD')->inLanguage($language)->text(); $locale = $init['language'] . '_' . $init['country']; $expectedDisplayAmount = Amount::format($expectedAmount, 'USD', $locale); $that = $this; //needed for PHP pre-5.4 $convertTest = function ($amountString) use($expectedDisplayAmount, $that) { $that->assertEquals($expectedDisplayAmount, trim($amountString), 'Displaying wrong amount'); }; $assertNodes = array('selected-amount' => array('innerhtml' => $convertTest), 'mw-content-text' => array('innerhtmlmatches' => "/.*{$expectedNotification}.*/")); $this->verifyFormOutput('AmazonGateway', $init, $assertNodes, false); }
/** * Called when a currency code error exists. If a fallback currency * conversion is enabled for this adapter, convert intended amount to * default currency. * * @throws DomainException */ protected function fallbackToDefaultCurrency() { $adapterClass = $this->gateway->getGatewayAdapterClass(); $defaultCurrency = null; if ($this->gateway->getGlobal('FallbackCurrencyByCountry')) { $country = $this->getVal('country'); if ($country !== null) { $defaultCurrency = NationalCurrencies::getNationalCurrency($country); } } else { $defaultCurrency = $this->gateway->getGlobal('FallbackCurrency'); } if (!$defaultCurrency) { return; } // Our conversion rates are all relative to USD, so use that as an // intermediate currency if converting between two others. $oldCurrency = $this->getVal('currency_code'); if ($oldCurrency === $defaultCurrency) { throw new DomainException(__FUNCTION__ . " Unsupported currency {$defaultCurrency} set as fallback for {$adapterClass}."); } $oldAmount = $this->getVal('amount'); $usdAmount = 0.0; $newAmount = 0; $conversionRates = CurrencyRates::getCurrencyRates(); if ($oldCurrency === 'USD') { $usdAmount = $oldAmount; } elseif (array_key_exists($oldCurrency, $conversionRates)) { $usdAmount = $oldAmount / $conversionRates[$oldCurrency]; } else { // We can't convert from this unknown currency. return; } if ($defaultCurrency === 'USD') { $newAmount = floor($usdAmount); } elseif (array_key_exists($defaultCurrency, $conversionRates)) { $newAmount = floor($usdAmount * $conversionRates[$defaultCurrency]); } $this->setVal('amount', $newAmount); $this->setVal('currency_code', $defaultCurrency); $this->logger->info("Unsupported currency {$oldCurrency} forced to {$defaultCurrency}"); // We have a fallback, so let's revalidate. $this->getValidationErrors(true); $notify = $this->gateway->getGlobal('NotifyOnConvert'); // If we're configured to notify, or if there are already other errors, // add a notification message. if ($notify || !empty($this->validationErrors)) { $error['general'] = MessageUtils::getCountrySpecificMessage('donate_interface-fallback-currency-notice', $this->getVal('country'), $this->getVal('language'), array($this->gateway->getGlobal('FallbackCurrency'))); $this->gateway->addManualError($error); } }
/** * @see ResourceLoaderModule::getScript() */ public function getScript(ResourceLoaderContext $context) { return 'mw.config.set( "wgDonationInterfaceCurrencyRates", ' . Xml::encodeJsVar(CurrencyRates::getCurrencyRates()) . ' );'; }
/** * @internal * @param $arOrder * @param $arOptions * @param $arErrors */ public static function calculateDeliveryTax(&$arOrder, $arOptions, &$arErrors) { if ((!array_key_exists("TAX_LOCATION", $arOrder) || strval(trim($arOrder["TAX_LOCATION"])) == "") && (!$arOrder["USE_VAT"] || $arOrder["USE_VAT"] != "Y")) { return; } if (!array_key_exists("COUNT_DELIVERY_TAX", $arOptions)) { $arOptions["COUNT_DELIVERY_TAX"] = COption::GetOptionString("sale", "COUNT_DELIVERY_TAX", "N"); } if (doubleval($arOrder["DELIVERY_PRICE"]) <= 0 || $arOptions["COUNT_DELIVERY_TAX"] != "Y") { return; } if (!$arOrder["USE_VAT"] || $arOrder["USE_VAT"] != "Y") { if (!array_key_exists("TAX_EXEMPT", $arOrder)) { $arUserGroups = CUser::GetUserGroup($arOrder["USER_ID"]); $dbTaxExemptList = CSaleTax::GetExemptList(array("GROUP_ID" => $arUserGroups)); while ($TaxExemptList = $dbTaxExemptList->Fetch()) { if (!in_array(intval($TaxExemptList["TAX_ID"]), $arOrder["TAX_EXEMPT"])) { $arOrder["TAX_EXEMPT"][] = intval($TaxExemptList["TAX_ID"]); } } } if (!array_key_exists("TAX_LIST", $arOrder)) { $arOrder["TAX_LIST"] = array(); $dbTaxRate = CSaleTaxRate::GetList(array("APPLY_ORDER" => "ASC"), array("LID" => $arOrder["SITE_ID"], "PERSON_TYPE_ID" => $arOrder["PERSON_TYPE_ID"], "ACTIVE" => "Y", "LOCATION_CODE" => $arOrder["TAX_LOCATION"])); while ($arTaxRate = $dbTaxRate->GetNext()) { if (is_array($arOrder["TAX_EXEMPT"]) && !in_array(intval($arTaxRate["TAX_ID"]), $arOrder["TAX_EXEMPT"])) { if ($arTaxRate["IS_PERCENT"] != "Y") { $arTaxRate["VALUE"] = \Bitrix\Sale\PriceMaths::roundPrecision(CurrencyRates::ConvertCurrency($arTaxRate["VALUE"], $arTaxRate["CURRENCY"], $arOrder["CURRENCY"])); $arTaxRate["CURRENCY"] = $arOrder["CURRENCY"]; } $arOrder["TAX_LIST"][] = $arTaxRate; } } } if (count($arOrder["TAX_LIST"]) > 0) { CSaleOrderTax::CountTaxes($arOrder["DELIVERY_PRICE"], $arOrder["TAX_LIST"], $arOrder["CURRENCY"]); $arOrder["TAX_PRICE"] = 0; foreach ($arOrder["TAX_LIST"] as &$arTax) { $arTax["VALUE_MONEY"] += \Bitrix\Sale\PriceMaths::roundPrecision($arTax["TAX_VAL"]); $arTax['VALUE_MONEY_FORMATED'] = SaleFormatCurrency($arTax["VALUE_MONEY"], $arOrder["CURRENCY"]); if ($arTax["IS_IN_PRICE"] != "Y" || !empty($arOptions['ENABLE_INCLUSIVE_TAX']) && $arOptions['ENABLE_INCLUSIVE_TAX'] == "Y") { $arOrder["TAX_PRICE"] += $arTax["VALUE_MONEY"]; } } unset($arTax); } } else { $deliveryVat = $arOrder["DELIVERY_PRICE"] * $arOrder["VAT_RATE"] / (1 + $arOrder["VAT_RATE"]); $arOrder["VAT_SUM"] += $deliveryVat; $arOrder["VAT_DELIVERY"] += $deliveryVat; //if (!array_key_exists("TAX_LIST", $arOrder)) //{ $arOrder["TAX_LIST"][0] = array("NAME" => GetMessage("SOA_VAT"), "IS_PERCENT" => "Y", "VALUE" => $arOrder["VAT_RATE"] * 100, "VALUE_FORMATED" => "(" . $arOrder["VAT_RATE"] * 100 . "%, " . GetMessage("SOA_VAT_INCLUDED") . ")", "VALUE_MONEY" => $arOrder["VAT_SUM"], "VALUE_MONEY_FORMATED" => SaleFormatCurrency($arOrder["VAT_SUM"], $arOrder["CURRENCY"]), "APPLY_ORDER" => 100, "IS_IN_PRICE" => "Y", "CODE" => "VAT"); //} } $arOrder["TAX_PRICE"] = \Bitrix\Sale\PriceMaths::roundPrecision($arOrder["TAX_PRICE"]); $arOrder["VAT_SUM"] = \Bitrix\Sale\PriceMaths::roundPrecision($arOrder["VAT_SUM"]); $arOrder["VAT_DELIVERY"] = \Bitrix\Sale\PriceMaths::roundPrecision($arOrder["VAT_DELIVERY"]); }
/** * Returns the data model based on the primary key given in the GET variable. * If the data model is not found, an HTTP exception will be raised. * @param integer $id the ID of the model to be loaded * @return CurrencyRates the loaded model * @throws CHttpException */ public function loadModel($id) { $model = CurrencyRates::model()->findByPk($id); if ($model === null) { throw new CHttpException(404, 'The requested page does not exist.'); } return $model; }