Post by cofran » Thu Dec 13, 2018 12:31 pm

He visto que opencart sigue utilizando la auto-conversión de moneda con el servicio de yahoo finance, que ha dejado de funcionar hace ya un año.
Lo mismo ha pasa con el cotizador de google finance converter que también ha dejado de funcionar.

He visto que si uno busca en google, algo como por ejemplo "100 USD to ARS" nos de como resultado de la parte superior de la búsqueda, cuanto sería el equivalente de 100 dolares en Pesos Argentinos (un montonazo de plata!) https://www.google.com/search?q=100+usd+to+ars

Entonces imagine que parseando el código, podría tomar dicho valor y encontré una discución sobre este mismo tema en github https://gist.github.com/daveismyname/80 ... nt-2741350 donde un usuario proponía lo mismo!

Tome ese código, lo modifique un poco y realice unas pruebas, agregándolo como un disparador de eventos en el admin de opencart
Voy a dejar este modulo-de-eventos (deben tener instalado opencart 3.x) adjunto para quien quiera usarlo. Aunque en la próxima actualización de opencart ya han trabajado sobre este tema y ahora las monedas van a poder ser convertidas desde diferentes fuentes de servicio (como debería haber sido hace muuuucho)

Para quienes tengan versiones anteriores a opencart 3.x les dejo las modificaciones en el código que se deben hacer. Vean si modifican el código original, si lo quieren hacer por vqmod, ocmod o como más les guste.

Modificar el archivo ubicado en: admin -> model -> localisation -> currency.php
Allí dentro, buscar la función llamada refresh y cambiar este código (puede variar dependiendo de tu versión opencart):

Code: Select all

foreach ($query->rows as $result) {
			$currency_data[] = $this->config->get('config_currency') . $result['code'] . '=X';
			$currency_data[] = $result['code'] . $this->config->get('config_currency') . '=X';
		}

		$curl = curl_init();

		curl_setopt($curl, CURLOPT_URL, 'http://download.finance.yahoo.com/d/quotes.csv?s=' . implode(',', $currency_data) . '&f=sl1&e=.json');
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($curl, CURLOPT_HEADER, false);
		curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($curl, CURLOPT_TIMEOUT, 30);

		$content = curl_exec($curl);
		
		curl_close($curl);

		$line = explode("\n", trim($content));

		for ($i = 0; $i < count($line); $i = $i + 2) {
			$currency = utf8_substr($line[$i], 4, 3);
			$value = utf8_substr($line[$i], 11, 6);
			
			if ((float)$value < 1 && isset($line[$i + 1])) {
				$value = (1 / utf8_substr($line[$i + 1], 11, 6));
			}	
						
			if ((float)$value) {
				$this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '" . (float)$value . "', date_modified = '" .  $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($currency) . "'");
			}
		}
Por este nuevo código:

Code: Select all

		if (ini_get('allow_url_fopen')) {
			$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "'");

			foreach ($query->rows as $result) {

				$content = file_get_contents( 'https://www.google.com/search?q=' . $this->config->get('config_currency') . '+to+' . $result['code'] );

			    preg_match("/<div class=\"J7UKTe\">(.*)<\/div>/",$content, $results);
			    $results = preg_replace("/[^0-9.]/", "", $results[1]);
			    $rate =  round($results, 2);
				
				if ((float)$rate && ($this->config->get('config_currency') != $result['code'])) {
					$this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '" . (float)number_format(substr($rate, 1),2) . "', date_modified = '" .  $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($result['code']) . "'");
				}
			}
		}

		else {
			$this->log->write('habilite en su phph.ini allow_url_fopen');
		}
Quienes se pregunten... ¿Cómo actualiza opencart la moneda? esto sucede cuando se visite el dashboard del admin... si si si un absurdo, pero es así.
Dentro del controlador del dashboard del admin, tenemos la llamada para actualizar las monedas. Esto podemos comprobarlo (dependiendo de tu versión de opencart) abriendo el archivo: admin -> controller -> common -> dashboard.php

Podrás ver el siguiente código:

Code: Select all

		if ($this->config->get('config_currency_auto')) {
			$this->load->model('localisation/currency');

			$this->model_localisation_currency->refresh();
		}
Esto en pocas palabras dice; que si esta configurado la auto-conversión de la moneda. Se carga el modelo currency y llama al metodo refresh() el cual ya vimos arriba y es el que actualiza la moneda.
Pero también el metodo refresh() posee un condicional que: solo actualiza la moneda 1 vez cada 24hs.
Podemos pasar una variable dentro del metodo refresh() que fuerza actualizar todas las monedas, sin tener en cuenta ningún tiempo condicional. En ese caso, la llamada al metodo refresh() debería quedar así:

Code: Select all

$this->model_localisation_currency->refresh(true);
Cualquier duda, consulta, revisión acá mismo, dejo adjunto el evento para quienes quieran descargarlo.

Attachments


User avatar
Active Member

Posts

Joined
Thu Oct 01, 2009 7:37 am
Location - Córdoba, Argentina
Who is online

Users browsing this forum: No registered users and 4 guests