Avand de realizat o aplicatie in care aveam nevoie de cursul valutar BNR la euro m-am lovit de o problema pe care nu o banuiam.inainte. Toate siteurile pe care le-am gasit si care afiseaza cursul valutar BNR afiseaza de fapt cursul BNR stabilit de BNR in ziua respectiva si nu cursul oficial care se utilizeaza in ziua respectiva.

Pentru cei care nu stiu, desi probabil ca daca ai ajuns aici stiti despre ce e vorba, cursul valutar se stabileste de catre BNR zilnic pentru urmatoarea zi lucratoare. Daca sunt zile nelucratoare intre ziua curenta si urmatoarea zi lucratoare atunci acest curs valutar se va folosi pentru toate aceste zile nelucratoare. Cu alte cuvinte mecanismul e explicat si pe site-ul www.cursbnr.ro la adresa http://www.cursbnr.ro/despre-cursul-bnr.

Site-ul www.bnr.ro ofera posibilitatea de a descarca fisiere xml cu cursurile valutare la zi (pentru ultima sedinta valutara), ultimele 10 sedinte valutare sau pentru fiecare an de cand se aplica procedeul acesta de stabilire a cursurtilor valutare BNR. Nu exista insa posibilitatea de a prelua cursul valutar dintr-o data oarecare, cu atat mai putin posibilitatea de a prelua cursul valutar valabil intr-o zi oarecare.

Am cautat pe web niste servicii web care sa imi returneze ceea ce doream dar dinnou nu am gasit. Singurul serviciu web gasit si care de asemenea genereaza cursul valutar stabilit la o anumita data (si nu valabil la o anumita data) este de www.infovalutar.ro, mai exact serviciul de la adresa http://www.infovalutar.ro/curs.asmx?WSDL. Scriptul php pentru preluarea acestui curs valutar este urmatorul:
curs_valutar.php:
<?php
if(!array_key_exists("data_valuta",$_POST)){
 $data_valuta=date("Y-m-d");
}
else{
 $data_valuta=$_GET["data_valuta"];
 if(!checkdate(intval(substr($data_valuta,5,2)), intval(substr($data_valuta,8,2)), intval(substr($data_valuta,0,4)))){
  echo 0;
 }
}

$data_test=new DateTime($data_valuta);
$data_maxima=new DateTime(date("Y-m-d"));
$data_minima=new DateTime(date("Y-m-d", mktime(0, 0, 0, 1, 4, 2005)));
if($data_test<$data_minima || $data_test>$data_maxima){
  echo 0;
}

 $client = new SoapClient("http://www.infovalutar.ro/curs.asmx?WSDL");
 $result = $client->GetValue(array('TheDate'=>$data_valuta, 'Moneda'=>'EUR'));

 $curs_euro=$result->getvalueResult;
 echo $curs_euro;
?>
apelul se face transmitand data dorita scriptului, de exemplu: curs_valutar.php?data_valuta=2015-03-25.
Bineinteles informatiile se pot prelua intr-o tabela si pastrate, e mai putin important asta.

Revenind la problema initiala rezolvarea am facuta-o preluand datele de pe site-ul BNR in scriptul de mai jos care returneaza cursul valutar VALABIL in data ceruta.

<?php
if(!array_key_exists("data_valuta",$_GET)){
    $data_valuta=date("Y-m-d");
}
else{
    $data_valuta=$_GET["data_valuta"];
    if(!checkdate(intval(substr($data_valuta,5,2)), intval(substr($data_valuta,8,2)), intval(substr($data_valuta,0,4)))){
        echo 0;
    }
}
$curs_euro = preia_curs($data_test->format("Y"));
if(!$curs_euro){
    $curs_euro = preia_curs((int)$data_test->format("Y")-1);
}
echo $curs_euro;

function preia_curs($an){
    global $data_valuta;
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_URL, "http://www.bnr.ro/files/xml/years/nbrfxrates".$an.".xml");
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    $contents = curl_exec($ch);
    curl_close($ch);

    $linii=explode("\n", $contents);
    $curs=0;
    foreach($linii as $linie){
        $t1 = explode('<Rate currency="EUR">', $linie);
        if(count($t1)>1){
            $t2 = explode('</Rate>', $t1[1]);
            if(count($t2)>1){
                $curs = (float)$t2[0];
            }
        }
        $t1 = explode('<Cube date="', $linie);
        if(count($t1)>1){
            $t2 = explode('">', $t1[1]);
            if(count($t2)>1){
                $data_curenta = new DateTime($t2[0]);
                if((strtotime($data_curenta->format("Y-m-d")) - strtotime($data_valuta))/(24*3600)>=0){
                    break;
                }
            }
        }
   }
   return $curs;
}

?>

Ideea scriptului e urmatorea: se preia fisierul xml corespunzator anului datei cerute de pe site-ul BNR. Din acest fisier se preia cursul ultimei zile lucratoare anterioare zilei in care ne intereseaza cursul (in fisierul xml de la BNR exista doar cursurile stabilite in zilele lucratore). In cazul in care nu se gaseste in fisier o zi lucratoare pentru care putem prelua cursul valutar se preia fisierul din anul anterior si se incearca acest lucru (situatiile astea sunt cand se cere cursul valutar pentru primele zile ale anului, inainte de prima zi lucratore din an).

Preluarea fisierului xml se face folosind extensia curl deci daca scriptul da eroare la apelul functiei trebuie activata aceasta extensie (se decomenteaza linia respectiva din php.ini si se restarteaza apache-ul). Am ales varianta asta pentru ca functioneaza in general pe serverele de hosting.
Bafta!

Niciun comentariu:

Trimiteți un comentariu