Skip to main content
1 of 2
MRO
  • 11
  • 1

Laravel show and update currency from rest api

I need:

  1. Daily save new exchange rates from the REST API in the database.

  2. Return the current exchange rate for a given currency, the whole table for a given day, the exchange rate for a given currency depending on the given currency and convert currency.

The code works, but I know it should not look that way. I do not know how to write it better.

2019_01_31_155244_create_nbp_rates_table.php

<?php

    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;

    class CreateNbpRatesTable extends Migration
    {

        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::connection('mysql_nbp')->create('rates', function (Blueprint $table) {
                $table->increments('id');
                $table->char('no', 20)->unique();
                $table->date('effectiveDate')->unique();
                $table->json('table_a');
                $table->timestamps();
            });
        }

        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::connection('mysql_nbp')->dropIfExists('rates');
        }

    }

NBP.php - model

<?php

    namespace Modules\NBP\Entities;

    use Illuminate\Database\Eloquent\Model;
    use Exception;
    use GuzzleHttp\Client;
    use GuzzleHttp\Exception\RequestException;

    class NBP extends Model
    {

        protected $table = 'rates';
        protected $connection = 'mysql_nbp';
        protected $fillable = [
            'no', 'effectiveDate', 'table_a'
        ];
        public $date;
        protected $_ratesCurrent;
        protected $_ratesByDate;

        function __construct()
        {
            parent::__construct();
        }

        public function getCurrentRates()
        {
            return $this->getByDateRates(self::max('effectiveDate'));
        }

        public function getByDateRates($date)
        {
            $this->date = $date;
            $this->validatedDate();

            while (true) {
                $result = self::where('effectiveDate', $this->date)->get()->toArray();
                if (count($result) == 0) {
                    $this->date = date('Y-m-d', strtotime($this->date . "-1 days"));
                } else {
                    $result = self::where('effectiveDate', $this->date)->get()->toArray();
                    $this->effectiveDate = $result[0]['effectiveDate'];
                    $this->no = $result[0]['no'];
                    $this->table = json_decode($result[0]['table_a'], true);
                    $this->_ratesByDate = $this->generateTable();
                    break;
                }
            }
            return $this->_ratesByDate;
        }

        public function getCurrentRateByIso($iso)
        {
            if (!isset($this->_ratesCurrent)) {
                $this->getCurrentRates();
            }
            if (array_key_exists($iso, $this->_ratesCurrent)) {
                return $this->_ratesCurrent[$iso];
            } else {
                throw new Exception('Brak kursu dla podanego kodu ISO', 400);
            }
        }

        public function getByDateRateByIso($iso, $date)
        {
            $this->date = $date;
            $this->validatedDate();
            $this->getByDateRates($date);

            if (array_key_exists($iso, $this->_ratesByDate)) {
                return $this->_ratesByDate[$iso];
            } else {
                throw new Exception('Brak kursu dla podanego kodu ISO', 400);
            }
        }

        public function exchange($isoFrom, $isoTo, $amount, $date = false)
        {
            if (!is_numeric($amount)) {
                throw new Exception('Nieprawidłowa kwota', 400);
            }
            $this->date = $date;
            if ($isoFrom == $isoTo) {
                return $amount;
            }

            if ($this->date === false) {
                $this->date = date('Y-m-d');
            } else {
                $this->validatedDate();
            }
            if ($isoFrom == 'PLN') {
                return $amount * $this->getByDateRateByIso($isoTo, $this->date);
            }

            if ($isoTo == 'PLN') {
                return $amount / $this->getByDateRateByIso($isoFrom, $this->date);
            }

            return $amount * $this->getByDateRateByIso($isoFrom, $this->date) / $this->getByDateRateByIso($isoTo, $this->date);
        }

        private function validatedDate()
        {
            if (!$this->date) {
                throw new Exception('Brak daty', 400);
            }

            try {
                new \DateTime($this->date);
                $this->date = date('Y-m-d', strtotime($this->date));
            } catch (\Exception $e) {
                throw new Exception('Nieprawidłowy format daty', 400);
            }
        }

        private function generateTable()
        {
            if (!$this->table) {
                throw new Exception('Brak wyników', 400);
            }
            $rates = [];
            foreach ($this->table as $rate) {
                $rates[(string) $rate['code']] = $rate['mid'];
            }
            $this->rates = $rates;
            return $this->rates;
        }

        public function downloadNowTables() {
            $begin = new \DateTime(date('Y-m-d', strtotime('- 1 week')));
            $end = new \DateTime(date('Y-m-d'));
            $end = $end->modify('+1 day');

            $interval = new \DateInterval('P1D');
            $daterange = new \DatePeriod($begin, $interval, $end);
            $GuzzleClient = new Client([
                'base_uri' => 'http://api.nbp.pl/api/',
                'defaults' => [
                    'headers' => ['Accept' => 'application/json']
                ]
            ]);
            foreach ($daterange as $date) {
                var_dump($date->format("Y-m-d"));
                while (true) {
                    try {
                        if (self::where('effectiveDate',$date->format("Y-m-d"))->count() == 0) {
                            $response = $GuzzleClient->get('exchangerates/tables/a/' . $date->format("Y-m-d"));
                            $array = json_decode($response->getBody(), true);
                            $rates = [];
                            foreach ($array[0]['rates'] as $rate) {
                                $rates[$rate['code']] = $rate;
                            }
                            self::insert([
                                'no' => $array[0]['no'],
                                'effectiveDate' => $array[0]['effectiveDate'],
                                'table_a' => json_encode($rates),
                                'created_at' => date('Y-m-d H:i:s'),
                                'updated_at' => date('Y-m-d H:i:s')
                            ]);
                        }
                        break;
                    } catch (RequestException $e) {
                        if (strpos($e->getMessage(), 'Brak danych')) {
                            break;
                        }
                    }
                }
            }
        }

    }
MRO
  • 11
  • 1