Settings_CurrencyUpdate_ECB_BankModel::getRates()   F
last analyzed

Complexity

Conditions 29
Paths 2242

Size

Total Lines 109
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 38
CRAP Score 85.3657

Importance

Changes 0
Metric Value
eloc 67
dl 0
loc 109
ccs 38
cts 64
cp 0.5938
rs 0
c 0
b 0
f 0
cc 29
nc 2242
nop 3
crap 85.3657

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright YetiForce S.A.
4
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
5
 * @author    Maciej Stencel <[email protected]>
6
 */
7
8
/**
9
 * Class for connection to European Central Bank currency exchange rates.
10
 */
11
class Settings_CurrencyUpdate_ECB_BankModel extends Settings_CurrencyUpdate_AbstractBank_Model
12
{
13
	// Returns bank name
14
15 1
	public function getName()
16
	{
17 1
		return 'ECB';
18
	}
19
20
	// Returns url sources from where exchange rates are taken from
21
22 1
	public function getSource()
23
	{
24 1
		return ['https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml', 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml'];
25
	}
26
27
	// Returns list of currencies supported by this bank
28
29 1
	public function getSupportedCurrencies()
30
	{
31 1
		$supportedCurrencies = [];
32 1
		$supportedCurrencies[Settings_CurrencyUpdate_Module_Model::getCRMCurrencyName($this->getMainCurrencyCode())] = $this->getMainCurrencyCode();
33 1
		$source = $this->getSource();
34
35 1
		$XML = simplexml_load_file($source[0]);
36
37 1
		foreach ($XML->Cube->Cube[0] as $currency) {
38 1
			$currencyCode = (string) $currency['currency'];
39 1
			$supportedCurrencies[Settings_CurrencyUpdate_Module_Model::getCRMCurrencyName($currencyCode)] = $currencyCode;
40
		}
41 1
		return $supportedCurrencies;
42
	}
43
44
	// Returns banks main currency
45
46 1
	public function getMainCurrencyCode()
47
	{
48 1
		return 'EUR';
49
	}
50
51
	/**
52
	 * Fetch exchange rates.
53
	 *
54
	 * @param <Array> $currencies        - list of systems active currencies
0 ignored issues
show
Documentation Bug introduced by
The doc comment <Array> at position 0 could not be parsed: Unknown type name '<' at position 0 in <Array>.
Loading history...
55
	 * @param <Date>  $date              - date for which exchange is fetched
56
	 * @param bool    $cron              - if true then it is fired by server and crms currency conversion rates are updated
57
	 * @param mixed   $otherCurrencyCode
58 1
	 * @param mixed   $dateParam
59
	 */
60 1
	public function getRates($otherCurrencyCode, $dateParam, $cron = false)
61 1
	{
62 1
		$moduleModel = Settings_CurrencyUpdate_Module_Model::getCleanInstance();
63
		$selectedBank = $moduleModel->getActiveBankId();
64
		$yesterday = date('Y-m-d', strtotime('-1 day'));
65 1
66
		// check if data is correct, currency rates can be retrieved only for working days
67 1
		$lastWorkingDay = vtlib\Functions::getLastWorkingDay($yesterday);
68 1
69
		$today = date('Y-m-d');
70
		$mainCurrency = \App\Fields\Currency::getDefault()['currency_code'];
71
72
		// source, ECB has 2 sources for older rates
73
		// 0 - last 90 days
74 1
		// 1 - historical data from year 1999
75
		// we speed script choosing the smaller file for our needs
76 1
		$source = $this->getSource();
77 1
		// how old is the currency rate
78 1
		$now = time(); // or your date as well
79
		$rateDay = strtotime($dateParam);
80 1
		$datediff = $now - $rateDay;
81
82
		if (floor($datediff / (60 * 60 * 24)) >= 90) {
83 1
			$sourceURL = $source[1];
84
		} else {
85
			$sourceURL = $source[0];
86 1
		}
87
88 1
		$XML = simplexml_load_file($sourceURL); // European Central Bank xml only contains business days! oh well....
89
90
		if (false === $XML) {
91 1
			return false;
92 1
		}
93
		$datePublicationOfFile = $dateParam;
94 1
		$exchangeRate = 1.0;
95 1
		// if currency is diffrent than EUR we need to calculate rate for converting other currencies to this one from EUR
96 1
		if ($mainCurrency != $this->getMainCurrencyCode()) {
97 1
			$foundRate = false;
98
			foreach ($XML->Cube->Cube as $time) {
99
				if ($time['time'] == $dateParam) {
100
					foreach ($time->Cube as $rate) {
101
						if ($rate['currency'] == $mainCurrency) {
102
							$exchangeRate = $rate['rate'];
103
							$foundRate = true;
104
						}
105
						if ($foundRate) {
106
							break;
107
						}
108 1
					}
109
				}
110
				if ($foundRate) {
111
					break;
112
				}
113
			}
114 1
		}
115 1
116 1
		$foundRate = false;
117
		foreach ($XML->Cube->Cube as $time) {
118
			if ($time['time'] == $dateParam) {
119
				$num = \count($time->Cube);
120
				for ($i = 0; $i < $num; ++$i) {
121
					$currency = (string) $time->Cube[$i]['currency'];   // currency code
122
					foreach ($otherCurrencyCode as $key => $currId) {
123
						if ($key == $currency && $currency != $mainCurrency) {
124
							$exchange = $time->Cube[$i]['rate'];
125
							$exchangeVtiger = (float) $exchange / (float) $exchangeRate;
126
							$exchange = (float) $exchangeRate / (float) $exchange;
127
128
							if (true === $cron || ((strtotime($dateParam) == strtotime($today)) || (strtotime($dateParam) == strtotime($lastWorkingDay)))) {
129
								$moduleModel->setCRMConversionRate($currency, $exchangeVtiger);
130
							}
131
							$existingId = $moduleModel->getCurrencyRateId($currId, $datePublicationOfFile, $selectedBank);
132
							if ($existingId > 0) {
133
								$moduleModel->updateCurrencyRate($existingId, $exchange);
134
							} else {
135
								$moduleModel->addCurrencyRate($currId, $datePublicationOfFile, $exchange, $selectedBank);
136
							}
137
						}
138
					}
139
				}
140 1
				$foundRate = true;
141
			}
142
			if ($foundRate) {
143
				break;
144
			}
145
		}
146 1
147 1
		// currency diffrent than EUR, we need to add manually EUR rates
148 1
		if ($mainCurrency != $this->getMainCurrencyCode()) {
149 1
			$yfRate = 1.00000 / (float) $exchangeRate;
150 1
			$exchange = (float) $exchangeRate;
151 1
			$mainCurrencyId = false;
152 1
			foreach ($otherCurrencyCode as $code => $id) {
153
				if ($code == $this->getMainCurrencyCode()) {
154
					$mainCurrencyId = $id;
155
				}
156 1
			}
157 1
158 1
			if ($mainCurrencyId) {
159
				if (true === $cron || ((strtotime($dateParam) == strtotime($today)) || (strtotime($dateParam) == strtotime($lastWorkingDay)))) {
160
					$moduleModel->setCRMConversionRate($this->getMainCurrencyCode(), $yfRate);
161 1
				}
162
163 1
				$existingId = $moduleModel->getCurrencyRateId($mainCurrencyId, $datePublicationOfFile, $selectedBank);
164
165
				if ($existingId > 0) {
166 1
					$moduleModel->updateCurrencyRate($existingId, $exchange);
167
				} else {
168
					$moduleModel->addCurrencyRate($mainCurrencyId, $datePublicationOfFile, $exchange, $selectedBank);
169
				}
170 1
			}
171
		}
172
	}
173
}
174