Auto exchange rate feature added

This commit is contained in:
Pranshu Tomar 2020-04-27 19:57:13 +05:30
parent 579490779c
commit b3b20a904c
16 changed files with 214 additions and 82 deletions

View File

@ -30,12 +30,16 @@ return [
],
'exchange-api' => [
'default' => 'fixer',
'default' => 'exchange_rates',
'fixer' => [
'paid_account' => false,
'key' => env('fixer_api_key'),
'class' => 'Webkul\Core\Helpers\Exchange\FixerExchange'
]
],
'exchange_rates' => [
'class' => 'Webkul\Core\Helpers\Exchange\ExchangeRates'
],
],
'stripe' => [

View File

@ -507,7 +507,7 @@ Route::group(['middleware' => ['web']], function () {
'view' => 'admin::settings.exchange_rates.edit'
])->name('admin.exchange_rates.edit');
Route::get('/exchange_rates/update-rates/{service}', 'Webkul\Core\Http\Controllers\ExchangeRateController@updateRates')->name('admin.exchange_rates.update-rates');
Route::get('/exchange_rates/update-rates', 'Webkul\Core\Http\Controllers\ExchangeRateController@updateRates')->name('admin.exchange_rates.update_rates');
Route::put('/exchange_rates/edit/{id}', 'Webkul\Core\Http\Controllers\ExchangeRateController@update')->defaults('_config', [
'redirect' => 'admin.exchange_rates.index'

View File

@ -729,7 +729,7 @@ return [
'target_currency' => 'العملة المستهدفة',
'rate' => 'معدل',
'exchange-class-not-found' => ':service لم يتم العثور على فئة سعر الصرف آسيف',
'update-rates' => ':service تحديث الأسعار باستخدام ',
'update-rates' => 'الأسعار',
'create-success' => 'تم إنشاء سعر الصرف بنجاح',
'update-success' => 'تم تحديث سعر الصرف بنجاح',
'delete-success' => 'تم حذف سعر الصرف بنجاح',

View File

@ -729,7 +729,7 @@ return [
'target_currency' => 'Target Currency',
'rate' => 'Rate',
'exchange-class-not-found' => ':service exchange rate class not found',
'update-rates' => 'Update rates using :service',
'update-rates' => 'Update Rates',
'create-success' => 'Exchange Rate created successfully.',
'update-success' => 'Exchange Rate updated successfully.',
'delete-success' => 'Exchange Rate deleted successfully.',

View File

@ -729,7 +729,7 @@ return [
'target_currency' => 'هدف ارز',
'rate' => 'نرخ',
'exchange-class-not-found' => 'کلاس نرخ ارز :service یافت نشد',
'update-rates' => ' به روز کنید :service نرخ ها را با استفاده از',
'update-rates' => 'نرخ ها را به روز کنید',
'create-success' => 'نرخ ارز با موفقیت ایجاد شد.',
'update-success' => 'نرخ ارز با موفقیت به روز شد.',
'delete-success' => 'نرخ ارز با موفقیت حذف شد.',

View File

@ -729,7 +729,7 @@ return [
'target_currency' => 'Valuta doel',
'rate' => 'Tarief',
'exchange-class-not-found' => ':service wisselkoersklasse niet gevonden',
'update-rates' => 'Tarieven bijwerken met :service',
'update-rates' => 'Tarieven bijwerken',
'create-success' => 'Wisselkoers succesvol aangemaakt.',
'update-success' => 'Wisselkoers succesvol bijgewerkt.',
'delete-success' => 'Wisselkoers succesvol verwijderd.',

View File

@ -729,6 +729,7 @@ return [
'target_currency' => 'Moeda Alvo',
'rate' => 'Taxa',
'exchange-class-not-found' => ':service de taxa de câmbio de serviço não encontrada',
'update-rates' => 'Atualizar Tarifas',
'rate' => 'Taxa',
'create-success' => 'Taxa de Câmbio criada com sucesso.',
'update-success' => 'Taxa de Câmbio atualizada com sucesso.',

View File

@ -56,7 +56,7 @@
<div class="control-group" :class="[errors.has('target_currency') ? 'has-error' : '']">
<select v-validate="'required'" class="control" name="target_currency" data-vv-as="&quot;{{ __('admin::app.settings.exchange_rates.target_currency') }}&quot;">
@foreach ($currencies as $currency)
@if (is_null($currency->CurrencyExchangeRate))
@if (is_null($currency->exchange_rate))
<option value="{{ $currency->id }}">{{ $currency->name }}</option>
@endif
@endforeach

View File

@ -12,25 +12,20 @@
</div>
<div class="page-action">
<a href="{{ route('admin.exchange_rates.update_rates') }}" class="btn btn-lg btn-primary">
{{ __('admin::app.settings.exchange_rates.update-rates') }}
</a>
<a href="{{ route('admin.exchange_rates.create') }}" class="btn btn-lg btn-primary">
{{ __('admin::app.settings.exchange_rates.add-title') }}
</a>
@php
$defaultService = config('services.exchange-api.default');
@endphp
{{-- <a href="{{ route('admin.exchange_rates.update-rates', $defaultService) }}" class="btn btn-lg btn-primary">
{{ __('admin::app.settings.exchange_rates.update-rates', [
'service' => $defaultService
]) }}
</a> --}}
</div>
</div>
<div class="page-content">
@inject('exchange_rates','Webkul\Admin\DataGrids\ExchangeRatesDataGrid')
{!! $exchange_rates->render() !!}
{!! app('Webkul\Admin\DataGrids\ExchangeRatesDataGrid')->render() !!}
</div>
</div>
@stop

View File

@ -0,0 +1,36 @@
<?php
namespace Webkul\Core\Console\Commands;
use Illuminate\Console\Command;
class ExchangeRateUpdate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'exchange-rate:update';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Automatically updates currency exchange rates ';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
try {
app(config('services.exchange-api.' . config('services.exchange-api.default') . '.class'))->updateRates();
} catch(\Exception $e) {
}
}
}

View File

@ -4,7 +4,5 @@ namespace Webkul\Core\Helpers\Exchange;
abstract class ExchangeRate
{
abstract public function fetchRates();
abstract public function UpdateRates();
abstract public function updateRates();
}

View File

@ -0,0 +1,88 @@
<?php
namespace Webkul\Core\Helpers\Exchange;
use Webkul\Core\Helpers\Exchange\ExchangeRate;
use Webkul\Core\Repositories\CurrencyRepository;
use Webkul\Core\Repositories\ExchangeRateRepository;
class ExchangeRates extends ExchangeRate
{
/**
* API endpoint
*
* @var string
*/
protected $apiEndPoint;
/**
* Holds CurrencyRepository instance
*
* @var \Webkul\Core\Repositories\CurrencyRepository
*/
protected $currencyRepository;
/**
* Holds ExchangeRateRepository instance
*
* @var \Webkul\Core\Repositories\ExchangeRateRepository
*/
protected $exchangeRateRepository;
/**
* Create a new helper instance.
*
* @param \Webkul\Core\Repositories\CurrencyRepository $currencyRepository
* @param \Webkul\Core\Repositories\ExchangeRateRepository $exchangeRateRepository
* @return void
*/
public function __construct(
CurrencyRepository $currencyRepository,
ExchangeRateRepository $exchangeRateRepository
)
{
$this->currencyRepository = $currencyRepository;
$this->exchangeRateRepository = $exchangeRateRepository;
$this->apiEndPoint = 'https://api.exchangeratesapi.io/latest';
}
/**
* Fetch rates and updates in currency_exchange_rates table
*
* @return \Exception|void
*/
public function updateRates()
{
$client = new \GuzzleHttp\Client();
foreach ($this->currencyRepository->all() as $currency) {
if ($currency->code == config('app.currency')) {
continue;
}
$result = $client->request('GET', $this->apiEndPoint . '?base=' . config('app.currency') . '&symbols=' . $currency->code);
$result = json_decode($result->getBody()->getContents(), true);
if (isset($result['success']) && ! $result['success']) {
throw new E\xception(
isset($result['error']['info'])
? $result['error']['info']
: $result['error']['type'], 1);
}
if ($exchangeRate = $currency->exchange_rate) {
$this->exchangeRateRepository->update([
'rate' => $result['rates'][$currency->code],
], $exchangeRate->id);
} else {
$this->exchangeRateRepository->create([
'rate' => $result['rates'][$currency->code],
'target_currency' => $currency->id,
]);
}
}
}
}

View File

@ -3,9 +3,10 @@
namespace Webkul\Core\Helpers\Exchange;
use Webkul\Core\Helpers\Exchange\ExchangeRate;
use Webkul\Core\Repositories\CurrencyRepository;
use Webkul\Core\Repositories\ExchangeRateRepository;
class FixerExchange extends ExchangeRate
class FixerExchange extends ExchangeRate
{
/**
* API key
@ -21,49 +22,76 @@ class FixerExchange extends ExchangeRate
*/
protected $apiEndPoint;
/**
* Holds CurrencyRepository instance
*
* @var \Webkul\Core\Repositories\CurrencyRepository
*/
protected $currencyRepository;
/**
* Holds ExchangeRateRepository instance
*
* @var \Webkul\Core\Helpers\Exchange\ExchangeRate
* @var \Webkul\Core\Repositories\ExchangeRateRepository
*/
protected $exchangeRate;
protected $exchangeRateRepository;
/**
* Create a new helper instance.
*
* @param \Webkul\Core\Repositories\CurrencyRepository $currencyRepository
* @param \Webkul\Core\Repositories\ExchangeRateRepository $exchangeRateRepository
* @return void
*/
public function __construct()
public function __construct(
CurrencyRepository $currencyRepository,
ExchangeRateRepository $exchangeRateRepository
)
{
$this->apiKey = config('services.exchange-api')['fixer']['key'];
$this->currencyRepository = $currencyRepository;
$this->apiEndPoint = 'http://data.fixer.io/api/latest?access_key=' . $this->apiKey;
$this->exchangeRateRepository = $exchangeRateRepository;
$this->apiEndPoint = 'http://data.fixer.io/api';
$this->apiKey = config('services.exchange-api')['fixer']['key'];
}
/**
* @return array
* Fetch rates and updates in currency_exchange_rates table
*
* @return \Exception|void
*/
public function fetchRates()
{
$rates = array();
$this->exchangeRate = app('Webkul\Core\Repositories\ExchangeRateRepository');
// dummy api call
$client = new \GuzzleHttp\Client();
if (config('services.exchange-api')['fixer']['paid_account']) {
$result = $client->request('GET', 'http://data.fixer.io/api/' . date('Y-m-d').'?access_key=' . $this->apiKey.'&base=' . core()->getBaseCurrency()->code . '&symbols=INR');
} else {
$result = $client->request('GET', 'http://data.fixer.io/api/' . date('Y-m-d') . '?access_key=' . $this->apiKey . '&symbols=USD');
}
$result = json_decode($result->getBody()->getContents());
return $result;
}
public function updateRates()
{
$client = new \GuzzleHttp\Client();
foreach ($this->currencyRepository->all() as $currency) {
if ($currency->code == config('app.currency')) {
continue;
}
$result = $client->request('GET', $this->apiEndPoint . '/' . date('Y-m-d') . '?access_key=' . $this->apiKey .'&base=' . config('app.currency') . '&symbols=' . $currency->code);
$result = json_decode($result->getBody()->getContents(), true);
if (isset($result['success']) && ! $result['success']) {
throw new \Exception(
isset($result['error']['info'])
? $result['error']['info']
: $result['error']['type'], 1);
}
if ($exchangeRate = $currency->exchange_rate) {
$this->exchangeRateRepository->update([
'rate' => $result['rates'][$currency->code],
], $exchangeRate->id);
} else {
$this->exchangeRateRepository->create([
'rate' => $result['rates'][$currency->code],
'target_currency' => $currency->id,
]);
}
}
}
}

View File

@ -67,7 +67,7 @@ class ExchangeRateController extends Controller
*/
public function create()
{
$currencies = $this->currencyRepository->with('CurrencyExchangeRate')->all();
$currencies = $this->currencyRepository->with('exchange_rate')->all();
return view($this->_config['view'], compact('currencies'));
}
@ -137,38 +137,19 @@ class ExchangeRateController extends Controller
/**
* Update Rates Using Exchange Rates API
*
* @param string $service
* @return \Illuminate\Http\JsonResponse
*/
public function updateRates($service)
public function updateRates()
{
$exchangeService = config('services.exchange-api')[$service];
try {
app(config('services.exchange-api.' . config('services.exchange-api.default') . '.class'))->updateRates();
if (is_array($exchangeService)) {
if (! array_key_exists('class', $exchangeService)) {
return response()->json([
'success' => false,
'rates' => null,
'error' => trans('admin::app.exchange-rate.exchange-class-not-found', [
'service' => $service,
]),
], 400);
}
$exchangeServiceInstance = new $exchangeService['class'];
$updatedRates = $exchangeServiceInstance->fetchRates();
return response()->json([
'success' => true,
'rates' => 'rates',
], 200);
} else {
return response()->json([
'success' => false,
'rates' => null,
'error' => trans('admin::app.exchange-rate.invalid-config'),
], 400);
session()->flash('success', trans('admin::app.settings.exchange_rates.update-success'));
} catch(\Exception $e) {
session()->flash('error', $e->getMessage());
}
return redirect()->back();
}
/**

View File

@ -30,9 +30,9 @@ class Currency extends Model implements CurrencyContract
}
/**
* Get the currency_exchange associated with the currency.
* Get the exchange rate associated with the currency.
*/
public function CurrencyExchangeRate()
public function exchange_rate()
{
return $this->hasOne(CurrencyExchangeRateProxy::modelClass(), 'target_currency');
}

View File

@ -12,6 +12,7 @@ use Webkul\Core\Models\SliderProxy;
use Webkul\Core\Observers\SliderObserver;
use Webkul\Core\Console\Commands\BagistoVersion;
use Webkul\Core\Console\Commands\Install;
use Webkul\Core\Console\Commands\ExchangeRateUpdate;
class CoreServiceProvider extends ServiceProvider
{
@ -78,7 +79,7 @@ class CoreServiceProvider extends ServiceProvider
protected function registerCommands(): void
{
if ($this->app->runningInConsole()) {
$this->commands([BagistoVersion::class, Install::class,]);
$this->commands([BagistoVersion::class, Install::class, ExchangeRateUpdate::class]);
}
}