first upload all files

This commit is contained in:
NW
2023-06-11 13:14:03 +01:00
parent f14dbc52b5
commit c08b36d1b6
1705 changed files with 106852 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\Currency\Admin;
use Modules\Currency\Currency;
use Modules\Admin\Ui\AdminTable;
class CurrencyRateTable extends AdminTable
{
/**
* Raw columns that will not be escaped.
*
* @var array
*/
protected $rawColumns = ['rate', 'updated_at'];
/**
* Make table response for the resource.
*
* @return \Illuminate\Http\JsonResponse
*/
public function make()
{
return $this->newTable()
->editColumn('currency_name', function ($currencyRate) {
return Currency::name($currencyRate->currency);
})
->editColumn('updated_at', function ($currencyRate) {
return view('admin::partials.table.date')->with('date', $currencyRate->updated_at);
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Modules\Currency\Admin;
use Modules\Admin\Ui\Tab;
use Modules\Admin\Ui\Tabs;
class CurrencyRateTabs extends Tabs
{
/**
* Make new tabs with groups.
*
* @return void
*/
public function make()
{
$this->group('currency_rate_information', trans('currency::currency_rates.tabs.group.currency_rate_information'))
->active()
->add($this->general());
}
private function general()
{
return tap(new Tab('general', trans('currency::currency_rates.tabs.general')), function (Tab $tab) {
$tab->active();
$tab->weight(5);
$tab->fields(['rate']);
$tab->view('currency::admin.currency_rates.tabs.general');
});
}
}

View File

@@ -0,0 +1,21 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Define which assets will be available through the asset manager
|--------------------------------------------------------------------------
| These assets are registered on the asset manager
*/
'all_assets' => [
'admin.currency.js' => ['module' => 'currency:admin/js/currency.js'],
],
/*
|--------------------------------------------------------------------------
| Define which default assets will always be included in your pages
| through the asset pipeline
|--------------------------------------------------------------------------
*/
'required_assets' => [],
];

View File

@@ -0,0 +1,10 @@
<?php
return [
'services' => [
'array' => ['latest_rates' => []],
'fixer' => ['access_key' => env('FIXER_ACCESS_KEY')],
'forge' => ['api_key' => env('FORGE_API_KEY')],
'currency_data_feed' => ['api_key' => env('CURRENCY_DATA_FEED_API_KEY')],
],
];

View File

@@ -0,0 +1,8 @@
<?php
return [
'admin.currency_rates' => [
'index' => 'currency::permissions.index',
'edit' => 'currency::permissions.edit',
],
];

View File

@@ -0,0 +1,58 @@
<?php
namespace Modules\Currency\Console;
use Illuminate\Console\Command;
use Modules\Currency\Entities\CurrencyRate;
use Modules\Currency\Services\CurrencyRateExchanger;
class RefreshCurrencyRatesCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'currency:refresh-rates';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Refresh currency rates.';
/**
* The currency rate exchanger instance.
*
* @var \Modules\Currency\Services\CurrencyRateExchanger
*/
private $exchanger;
/**
* Create a new command instance.
*
* @param \Modules\Currency\Services\CurrencyRateExchanger $exchanger
* @return void
*/
public function __construct(CurrencyRateExchanger $exchanger)
{
parent::__construct();
$this->exchanger = $exchanger;
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if (is_null(setting('currency_rate_exchange_service'))) {
return logger()->error('RefreshCurrencyRatesCommand: Currency rate exchange service is not configured.');
}
CurrencyRate::refreshRates($this->exchanger);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Currency;
class Currency
{
/**
* Path of the resource.
*
* @var string
*/
const RESOURCE_PATH = __DIR__ . '/Resources/currencies.php';
/**
* Array of all currencies.
*
* @var array
*/
private static $currencies;
/**
* Get all currencies.
*
* @return array
*/
public static function all()
{
if (is_null(self::$currencies)) {
self::$currencies = require self::RESOURCE_PATH;
}
return self::$currencies;
}
/**
* Get all currency codes.
*
* @return array
*/
public static function codes()
{
return array_keys(self::all());
}
/**
* Get all currency names.
*
* @return array
*/
public static function names()
{
return array_map(function ($currency) {
return $currency['name'];
}, self::all());
}
/**
* Get name of the give currency code.
*
* @param string $code
* @return string
*/
public static function name($code)
{
return array_get(self::all(), "{$code}.name");
}
/**
* Get subunit for the given currency code.
*
* @param string $code
* @return int
*/
public static function subunit($code)
{
return array_get(self::all(), "{$code}.subunit");
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCurrencyRatesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('currency_rates', function (Blueprint $table) {
$table->increments('id');
$table->string('currency')->unique();
$table->decimal('rate', 8, 4)->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('currency_rates');
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Modules\Currency\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Currency\Entities\CurrencyRate;
class CurrencyDatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
CurrencyRate::create(['currency' => 'USD', 'rate' => 1]);
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Modules\Currency\Entities;
use Money\Currency;
use Modules\Support\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Modules\Currency\Admin\CurrencyRateTable;
use Modules\Currency\Services\CurrencyRateExchanger;
class CurrencyRate extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['currency', 'rate'];
/**
* Perform any actions required after the model boots.
*
* @return void
*/
public static function booted()
{
static::saved(function ($currencyRate) {
Cache::forget(md5("currency_rate.{$currencyRate->currency}"));
});
}
/**
* Refresh all supported currencies exchange rate.
*
* @param \Modules\Currency\Services\CurrencyRateExchanger $exchanger
* @return void
*/
public static function refreshRates(CurrencyRateExchanger $exchanger)
{
$fromCurrency = setting('default_currency');
foreach (setting('supported_currencies') as $toCurrency) {
$rate = $exchanger->exchange($fromCurrency, $toCurrency);
static::where('currency', $toCurrency)->first()->update(['rate' => $rate]);
}
}
/**
* Get currency rate for the given currency.
*
* @param string $currency
* @return int|float
*/
public static function for($currency)
{
return Cache::rememberForever(md5("currency_rate.{$currency}"), function () use ($currency) {
return static::where('currency', $currency)->value('rate');
});
}
/**
* Get table data for the resource
*
* @return \Illuminate\Http\JsonResponse
*/
public function table()
{
return new CurrencyRateTable($this->newQuery());
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Modules\Currency\Http\Controllers\Admin;
use Modules\Admin\Traits\HasCrudActions;
use Modules\Currency\Entities\CurrencyRate;
use Modules\Currency\Services\CurrencyRateExchanger;
use Modules\Currency\Http\Requests\UpdateCurrencyRateRequest;
class CurrencyRateController
{
use HasCrudActions;
/**
* Model for the resource.
*
* @var string
*/
protected $model = CurrencyRate::class;
/**
* Label of the resource.
*
* @var string
*/
protected $label = 'currency::currency_rates.currency_rate';
/**
* View path of the resource.
*
* @var string
*/
protected $viewPath = 'currency::admin.currency_rates';
/**
* Form requests for the resource.
*
* @var array
*/
protected $validation = UpdateCurrencyRateRequest::class;
/**
* Refresh currency rates.
*
* @param \Modules\Currency\Services\CurrencyRateExchanger $exchanger
* @return \Illuminate\Http\Response
*/
public function refresh(CurrencyRateExchanger $exchanger)
{
if (is_null(setting('currency_rate_exchange_service'))) {
abort(400, trans('currency::messages.exchange_service_is_not_configured'));
}
CurrencyRate::refreshRates($exchanger);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Modules\Currency\Http\Controllers;
class CurrentCurrencyController
{
/**
* Store a newly created resource in storage.
*
* @param string $currency
* @return \Illuminate\Http\Response
*/
public function store($currency)
{
if (! in_array($currency, setting('supported_currencies'))) {
return back();
}
$cookie = cookie()->forever('currency', $currency);
return back()->withCookie($cookie);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Currency\Http\Requests;
use Modules\Core\Http\Requests\Request;
class UpdateCurrencyRateRequest extends Request
{
/**
* Available attributes.
*
* @var string
*/
protected $availableAttributes = 'currency::attributes';
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'rate' => 'required|numeric|max:9999',
];
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Modules\Currency\Listeners;
use Modules\Setting\Events\SettingSaved;
use Modules\Currency\Entities\CurrencyRate;
class CreateCurrencyRates
{
/**
* Handle the event.
*
* @param \Modules\Setting\Events\SettingSaved $event
* @return void
*/
public function handle(SettingSaved $event)
{
CurrencyRate::insert($this->rates());
}
/**
* Get the currency rates.
*
* @return array
*/
private function rates()
{
$currencyRates = CurrencyRate::pluck('currency');
return collect(request('supported_currencies'))->reject(function ($currency) use ($currencyRates) {
return $currencyRates->contains($currency);
})->map(function ($currency) {
return [
'currency' => $currency,
'rate' => 1,
'created_at' => now(),
'updated_at' => now(),
];
})->all();
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Modules\Currency\Providers;
use Swap\Builder;
use Illuminate\Support\ServiceProvider;
use Modules\Currency\Services\CurrencyRateExchanger;
class CurrencyExchangeRateServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
if (! config('app.installed')) {
return;
}
$this->setupCurrencyRateExchangeService();
$this->app->singleton(CurrencyRateExchanger::class, function () {
$service = setting('currency_rate_exchange_service', 'array');
$options = config("fleetcart.modules.currency.config.services.{$service}");
$swap = (new Builder)->add($service, $options)->build();
return new CurrencyRateExchanger($swap);
});
}
/**
* Setup currency rate exchange service.
*
* @return void
*/
private function setupCurrencyRateExchangeService()
{
config([
'fleetcart.modules.currency.config.services.fixer.access_key' => setting('fixer_access_key'),
'fleetcart.modules.currency.config.services.forge.api_key' => setting('forge_api_key'),
'fleetcart.modules.currency.config.services.currency_data_feed.api_key' => setting('currency_data_feed_api_key'),
]);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Modules\Currency\Providers;
use Modules\Support\Traits\AddsAsset;
use Illuminate\Support\ServiceProvider;
use Modules\Admin\Ui\Facades\TabManager;
use Illuminate\Console\Scheduling\Schedule;
use Modules\Currency\Admin\CurrencyRateTabs;
use Modules\Currency\Console\RefreshCurrencyRatesCommand;
class CurrencyServiceProvider extends ServiceProvider
{
use AddsAsset;
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
if (! config('app.installed')) {
return;
}
TabManager::register('currency_rates', CurrencyRateTabs::class);
$this->addAdminAssets('admin.currency_rates.index', ['admin.currency.js']);
if ($this->app->runningInConsole() && setting('auto_refresh_currency_rates', false)) {
$this->commands(RefreshCurrencyRatesCommand::class);
$this->registerScheduler();
}
}
private function registerScheduler()
{
$this->app->booted(function ($app) {
$frequency = setting('auto_refresh_currency_rate_frequency');
if (in_array($frequency, ['daily', 'weekly', 'monthly'])) {
$app[Schedule::class]->command(RefreshCurrencyRatesCommand::class)->{$frequency}();
}
});
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Modules\Currency\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
\Modules\Setting\Events\SettingSaved::class => [
\Modules\Currency\Listeners\CreateCurrencyRates::class,
],
];
}

View File

@@ -0,0 +1,16 @@
$('#refresh-rates').on('click', (e) => {
$.ajax({
type: 'GET',
url: route('admin.currency_rates.refresh'),
success() {
DataTable.reload('#currency-rates-table .table');
window.admin.stopButtonLoading($(e.currentTarget));
},
error(xhr) {
error(xhr.responseJSON.message);
window.admin.stopButtonLoading($(e.currentTarget));
},
});
});

View File

@@ -0,0 +1,660 @@
<?php
return [
'AFN' => [
'name' => 'Afghan Afghani',
'subunit' => 2,
],
'ALL' => [
'name' => 'Albanian Lek',
'subunit' => 2,
],
'DZD' => [
'name' => 'Algerian Dinar',
'subunit' => 2,
],
'AOA' => [
'name' => 'Angolan Kwanza',
'subunit' => 2,
],
'ARS' => [
'name' => 'Argentine Peso',
'subunit' => 2,
],
'AMD' => [
'name' => 'Armenian Dram',
'subunit' => 2,
],
'AWG' => [
'name' => 'Aruban Florin',
'subunit' => 2,
],
'AUD' => [
'name' => 'Australian Dollar',
'subunit' => 2,
],
'AZN' => [
'name' => 'Azerbaijani Manat',
'subunit' => 2,
],
'BSD' => [
'name' => 'Bahamian Dollar',
'subunit' => 2,
],
'BHD' => [
'name' => 'Bahraini Dinar',
'subunit' => 3,
],
'BDT' => [
'name' => 'Bangladeshi Taka',
'subunit' => 2,
],
'BBD' => [
'name' => 'Barbadian Dollar',
'subunit' => 2,
],
'BYN' => [
'name' => 'Belarusian Ruble',
'subunit' => 2,
],
'BZD' => [
'name' => 'Belize Dollar',
'subunit' => 2,
],
'BMD' => [
'name' => 'Bermudan Dollar',
'subunit' => 2,
],
'BTN' => [
'name' => 'Bhutanese Ngultrum',
'subunit' => 2,
],
'BOB' => [
'name' => 'Bolivian Boliviano',
'subunit' => 2,
],
'BOV' => [
'name' => 'Bolivian Mvdol',
'subunit' => 2,
],
'BAM' => [
'name' => 'Bosnia-Herzegovina Convertible Mark',
'subunit' => 2,
],
'BWP' => [
'name' => 'Botswanan Pula',
'subunit' => 2,
],
'BRL' => [
'name' => 'Brazilian Real',
'subunit' => 2,
],
'GBP' => [
'name' => 'British Pound',
'subunit' => 2,
],
'BND' => [
'name' => 'Brunei Dollar',
'subunit' => 2,
],
'BGN' => [
'name' => 'Bulgarian Lev',
'subunit' => 2,
],
'BIF' => [
'name' => 'Burundian Franc',
'subunit' => 0,
],
'XPF' => [
'name' => 'CFP Franc',
'subunit' => 0,
],
'KHR' => [
'name' => 'Cambodian Riel',
'subunit' => 2,
],
'CAD' => [
'name' => 'Canadian Dollar',
'subunit' => 2,
],
'CVE' => [
'name' => 'Cape Verdean Escudo',
'subunit' => 2,
],
'KYD' => [
'name' => 'Cayman Islands Dollar',
'subunit' => 2,
],
'XAF' => [
'name' => 'Central African CFA Franc',
'subunit' => 0,
],
'CLP' => [
'name' => 'Chilean Peso',
'subunit' => 0,
],
'CLF' => [
'name' => 'Chilean Unit of Account (UF)',
'subunit' => 4,
],
'CNY' => [
'name' => 'Chinese Yuan',
'subunit' => 2,
],
'COP' => [
'name' => 'Colombian Peso',
'subunit' => 2,
],
'COU' => [
'name' => 'Colombian Real Value Unit',
'subunit' => 2,
],
'KMF' => [
'name' => 'Comorian Franc',
'subunit' => 0,
],
'CDF' => [
'name' => 'Congolese Franc',
'subunit' => 2,
],
'CRC' => [
'name' => 'Costa Rican Colón',
'subunit' => 2,
],
'HRK' => [
'name' => 'Croatian Kuna',
'subunit' => 2,
],
'CUC' => [
'name' => 'Cuban Convertible Peso',
'subunit' => 2,
],
'CUP' => [
'name' => 'Cuban Peso',
'subunit' => 2,
],
'CZK' => [
'name' => 'Czech Koruna',
'subunit' => 2,
],
'DKK' => [
'name' => 'Danish Krone',
'subunit' => 2,
],
'DJF' => [
'name' => 'Djiboutian Franc',
'subunit' => 0,
],
'DOP' => [
'name' => 'Dominican Peso',
'subunit' => 2,
],
'XCD' => [
'name' => 'East Caribbean Dollar',
'subunit' => 2,
],
'EGP' => [
'name' => 'Egyptian Pound',
'subunit' => 2,
],
'ERN' => [
'name' => 'Eritrean Nakfa',
'subunit' => 2,
],
'ETB' => [
'name' => 'Ethiopian Birr',
'subunit' => 2,
],
'EUR' => [
'name' => 'Euro',
'subunit' => 2,
],
'FKP' => [
'name' => 'Falkland Islands Pound',
'subunit' => 2,
],
'FJD' => [
'name' => 'Fijian Dollar',
'subunit' => 2,
],
'GMD' => [
'name' => 'Gambian Dalasi',
'subunit' => 2,
],
'GEL' => [
'name' => 'Georgian Lari',
'subunit' => 2,
],
'GHS' => [
'name' => 'Ghanaian Cedi',
'subunit' => 2,
],
'GIP' => [
'name' => 'Gibraltar Pound',
'subunit' => 2,
],
'GTQ' => [
'name' => 'Guatemalan Quetzal',
'subunit' => 2,
],
'GNF' => [
'name' => 'Guinean Franc',
'subunit' => 0,
],
'GYD' => [
'name' => 'Guyanaese Dollar',
'subunit' => 2,
],
'HTG' => [
'name' => 'Haitian Gourde',
'subunit' => 2,
],
'HNL' => [
'name' => 'Honduran Lempira',
'subunit' => 2,
],
'HKD' => [
'name' => 'Hong Kong Dollar',
'subunit' => 2,
],
'HUF' => [
'name' => 'Hungarian Forint',
'subunit' => 2,
],
'ISK' => [
'name' => 'Icelandic Króna',
'subunit' => 0,
],
'INR' => [
'name' => 'Indian Rupee',
'subunit' => 2,
],
'IDR' => [
'name' => 'Indonesian Rupiah',
'subunit' => 2,
],
'IRR' => [
'name' => 'Iranian Rial',
'subunit' => 2,
],
'IQD' => [
'name' => 'Iraqi Dinar',
'subunit' => 3,
],
'ILS' => [
'name' => 'Israeli New Shekel',
'subunit' => 2,
],
'JMD' => [
'name' => 'Jamaican Dollar',
'subunit' => 2,
],
'JPY' => [
'name' => 'Japanese Yen',
'subunit' => 0,
],
'JOD' => [
'name' => 'Jordanian Dinar',
'subunit' => 3,
],
'KZT' => [
'name' => 'Kazakhstani Tenge',
'subunit' => 2,
],
'KES' => [
'name' => 'Kenyan Shilling',
'subunit' => 2,
],
'KWD' => [
'name' => 'Kuwaiti Dinar',
'subunit' => 3,
],
'KGS' => [
'name' => 'Kyrgystani Som',
'subunit' => 2,
],
'LAK' => [
'name' => 'Laotian Kip',
'subunit' => 2,
],
'LBP' => [
'name' => 'Lebanese Pound',
'subunit' => 2,
],
'LSL' => [
'name' => 'Lesotho Loti',
'subunit' => 2,
],
'LRD' => [
'name' => 'Liberian Dollar',
'subunit' => 2,
],
'LYD' => [
'name' => 'Libyan Dinar',
'subunit' => 3,
],
'MOP' => [
'name' => 'Macanese Pataca',
'subunit' => 2,
],
'MKD' => [
'name' => 'Macedonian Denar',
'subunit' => 2,
],
'MGA' => [
'name' => 'Malagasy Ariary',
'subunit' => 2,
],
'MWK' => [
'name' => 'Malawian Kwacha',
'subunit' => 2,
],
'MYR' => [
'name' => 'Malaysian Ringgit',
'subunit' => 2,
],
'MVR' => [
'name' => 'Maldivian Rufiyaa',
'subunit' => 2,
],
'MRO' => [
'name' => 'Mauritanian Ouguiya',
'subunit' => 2,
],
'MUR' => [
'name' => 'Mauritian Rupee',
'subunit' => 2,
],
'MXV' => [
'name' => 'Mexican Investment Unit',
'subunit' => 2,
],
'MXN' => [
'name' => 'Mexican Peso',
'subunit' => 2,
],
'MDL' => [
'name' => 'Moldovan Leu',
'subunit' => 2,
],
'MNT' => [
'name' => 'Mongolian Tugrik',
'subunit' => 2,
],
'MAD' => [
'name' => 'Moroccan Dirham',
'subunit' => 2,
],
'MZN' => [
'name' => 'Mozambican Metical',
'subunit' => 2,
],
'MMK' => [
'name' => 'Myanmar Kyat',
'subunit' => 2,
],
'NAD' => [
'name' => 'Namibian Dollar',
'subunit' => 2,
],
'NPR' => [
'name' => 'Nepalese Rupee',
'subunit' => 2,
],
'ANG' => [
'name' => 'Netherlands Antillean Guilder',
'subunit' => 2,
],
'TWD' => [
'name' => 'New Taiwan Dollar',
'subunit' => 2,
],
'NZD' => [
'name' => 'New Zealand Dollar',
'subunit' => 2,
],
'NIO' => [
'name' => 'Nicaraguan Córdoba',
'subunit' => 2,
],
'NGN' => [
'name' => 'Nigerian Naira',
'subunit' => 2,
],
'KPW' => [
'name' => 'North Korean Won',
'subunit' => 2,
],
'NOK' => [
'name' => 'Norwegian Krone',
'subunit' => 2,
],
'OMR' => [
'name' => 'Omani Rial',
'subunit' => 3,
],
'PKR' => [
'name' => 'Pakistani Rupee',
'subunit' => 2,
],
'PAB' => [
'name' => 'Panamanian Balboa',
'subunit' => 2,
],
'PGK' => [
'name' => 'Papua New Guinean Kina',
'subunit' => 2,
],
'PYG' => [
'name' => 'Paraguayan Guarani',
'subunit' => 0,
],
'PEN' => [
'name' => 'Peruvian Sol',
'subunit' => 2,
],
'PHP' => [
'name' => 'Philippine Peso',
'subunit' => 2,
],
'PLN' => [
'name' => 'Polish Zloty',
'subunit' => 2,
],
'QAR' => [
'name' => 'Qatari Rial',
'subunit' => 2,
],
'RON' => [
'name' => 'Romanian Leu',
'subunit' => 2,
],
'RUB' => [
'name' => 'Russian Ruble',
'subunit' => 2,
],
'RWF' => [
'name' => 'Rwandan Franc',
'subunit' => 0,
],
'SVC' => [
'name' => 'Salvadoran Colón',
'subunit' => 2,
],
'WST' => [
'name' => 'Samoan Tala',
'subunit' => 2,
],
'SAR' => [
'name' => 'Saudi Riyal',
'subunit' => 2,
],
'RSD' => [
'name' => 'Serbian Dinar',
'subunit' => 2,
],
'SCR' => [
'name' => 'Seychellois Rupee',
'subunit' => 2,
],
'SLL' => [
'name' => 'Sierra Leonean Leone',
'subunit' => 2,
],
'SGD' => [
'name' => 'Singapore Dollar',
'subunit' => 2,
],
'SBD' => [
'name' => 'Solomon Islands Dollar',
'subunit' => 2,
],
'SOS' => [
'name' => 'Somali Shilling',
'subunit' => 2,
],
'ZAR' => [
'name' => 'South African Rand',
'subunit' => 2,
],
'KRW' => [
'name' => 'South Korean Won',
'subunit' => 0,
],
'SSP' => [
'name' => 'South Sudanese Pound',
'subunit' => 2,
],
'LKR' => [
'name' => 'Sri Lankan Rupee',
'subunit' => 2,
],
'SHP' => [
'name' => 'St. Helena Pound',
'subunit' => 2,
],
'SDG' => [
'name' => 'Sudanese Pound',
'subunit' => 2,
],
'SRD' => [
'name' => 'Surinamese Dollar',
'subunit' => 2,
],
'SZL' => [
'name' => 'Swazi Lilangeni',
'subunit' => 2,
],
'SEK' => [
'name' => 'Swedish Krona',
'subunit' => 2,
],
'CHF' => [
'name' => 'Swiss Franc',
'subunit' => 2,
],
'SYP' => [
'name' => 'Syrian Pound',
'subunit' => 2,
],
'STD' => [
'name' => 'São Tomé & Príncipe Dobra',
'subunit' => 2,
],
'TJS' => [
'name' => 'Tajikistani Somoni',
'subunit' => 2,
],
'TZS' => [
'name' => 'Tanzanian Shilling',
'subunit' => 2,
],
'THB' => [
'name' => 'Thai Baht',
'subunit' => 2,
],
'TOP' => [
'name' => 'Tongan Paʻanga',
'subunit' => 2,
],
'TTD' => [
'name' => 'Trinidad & Tobago Dollar',
'subunit' => 2,
],
'TND' => [
'name' => 'Tunisian Dinar',
'subunit' => 3,
],
'TRY' => [
'name' => 'Turkish Lira',
'subunit' => 2,
],
'TMT' => [
'name' => 'Turkmenistani Manat',
'subunit' => 2,
],
'USD' => [
'name' => 'US Dollar',
'subunit' => 2,
],
'UGX' => [
'name' => 'Ugandan Shilling',
'subunit' => 0,
],
'UAH' => [
'name' => 'Ukrainian Hryvnia',
'subunit' => 2,
],
'AED' => [
'name' => 'United Arab Emirates Dirham',
'subunit' => 2,
],
'UYU' => [
'name' => 'Uruguayan Peso',
'subunit' => 2,
],
'UYI' => [
'name' => 'Uruguayan Peso (Indexed Units)',
'subunit' => 0,
],
'UZS' => [
'name' => 'Uzbekistani Som',
'subunit' => 2,
],
'VUV' => [
'name' => 'Vanuatu Vatu',
'subunit' => 0,
],
'VEF' => [
'name' => 'Venezuelan Bolívar',
'subunit' => 2,
],
'VND' => [
'name' => 'Vietnamese Dong',
'subunit' => 0,
],
'CHE' => [
'name' => 'WIR Euro',
'subunit' => 2,
],
'CHW' => [
'name' => 'WIR Franc',
'subunit' => 2,
],
'XOF' => [
'name' => 'West African CFA Franc',
'subunit' => 0,
],
'YER' => [
'name' => 'Yemeni Rial',
'subunit' => 2,
],
'ZMW' => [
'name' => 'Zambian Kwacha',
'subunit' => 2,
],
'ZWL' => [
'name' => 'Zimbabwean Dollar',
'subunit' => 2,
],
];

View File

@@ -0,0 +1,5 @@
<?php
return [
'rate' => 'Rate',
];

View File

@@ -0,0 +1,20 @@
<?php
return [
'currency_rate' => 'Currency Rate',
'currency_rates' => 'Currency Rates',
'refresh_rates' => 'Refresh Rates',
'refresh_currency_rates_from' => 'Refresh currency rates from :service',
'table' => [
'currency' => 'Currency',
'code' => 'Code',
'rate' => 'Rate',
'last_updated' => 'Last Updated',
],
'tabs' => [
'group' => [
'currency_rate_information' => 'Currency Rate Information',
],
'general' => 'General',
],
];

View File

@@ -0,0 +1,5 @@
<?php
return [
'exchange_service_is_not_configured' => 'Currency rate exchange service is not configured.',
];

View File

@@ -0,0 +1,6 @@
<?php
return [
'index' => 'Index Currency Rates',
'edit' => 'Edit Currency Rates',
];

View File

@@ -0,0 +1,7 @@
<?php
return [
'fixer' => 'Fixer',
'forge' => 'Forge',
'currency_data_feed' => 'Currency Data Feed',
];

View File

@@ -0,0 +1,33 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('admin::resource.edit', ['resource' => trans('currency::currency_rates.currency_rate')]))
@slot('subtitle', $currencyRate->currency)
<li><a href="{{ route('admin.currency_rates.index') }}">{{ trans('currency::currency_rates.currency_rates') }}</a></li>
<li class="active">{{ trans('admin::resource.edit', ['resource' => trans('currency::currency_rates.currency_rate')]) }}</li>
@endcomponent
@section('content')
<form method="POST" action="{{ route('admin.currency_rates.update', $currencyRate) }}" class="form-horizontal" id="currency-rate-edit-form" novalidate>
{{ csrf_field() }}
{{ method_field('put') }}
{!! $tabs->render(compact('currencyRate')) !!}
</form>
@endsection
@push('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('admin::admin.shortcuts.back_to_index', ['name' => trans('currency::currency_rates.currency_rate')]) }}</dd>
</dl>
@endpush
@push('scripts')
<script>
keypressAction([
{ key: 'b', route: "{{ route('admin.currency_rates.index') }}" }
]);
</script>
@endpush

View File

@@ -0,0 +1,50 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('currency::currency_rates.currency_rates'))
<li class="active">{{ trans('currency::currency_rates.currency_rates') }}</li>
@endcomponent
@section('content')
<div class="row">
<div class="btn-group pull-right">
<button id="refresh-rates" class="btn btn-primary btn-actions" data-loading>
{{ trans('currency::currency_rates.refresh_rates') }}
</button>
</div>
</div>
<div class="box box-primary">
<div class="box-body index-table" id="currency-rates-table">
@component('admin::components.table')
@slot('thead')
<tr>
<th>{{ trans('currency::currency_rates.table.currency') }}</th>
<th data-sort="asc">{{ trans('currency::currency_rates.table.code') }}</th>
<th>{{ trans('currency::currency_rates.table.rate') }}</th>
<th>{{ trans('currency::currency_rates.table.last_updated') }}</th>
</tr>
@endslot
@endcomponent
</div>
</div>
@endsection
@push('scripts')
<script>
DataTable.setRoutes('#currency-rates-table .table', {
index: 'admin.currency_rates.index',
edit: 'admin.currency_rates.edit',
});
new DataTable('#currency-rates-table .table', {
columns: [
{ data: 'currency_name', orderable: false, searchable: false },
{ data: 'currency' },
{ data: 'rate', searchable: false },
{ data: 'updated_at', searchable: false },
],
});
</script>
@endpush

View File

@@ -0,0 +1,5 @@
<div class="row">
<div class="col-md-8">
{{ Form::number('rate', trans('currency::attributes.rate'), $errors, $currencyRate, ['required' => true]) }}
</div>
</div>

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Support\Facades\Route;
Route::get('currency-rates', [
'as' => 'admin.currency_rates.index',
'uses' => 'CurrencyRateController@index',
'middleware' => 'can:admin.currency_rates.index',
]);
Route::get('currency-rates/{id}/edit', [
'as' => 'admin.currency_rates.edit',
'uses' => 'CurrencyRateController@edit',
'middleware' => 'can:admin.currency_rates.edit',
]);
Route::put('currency-rates/{id}', [
'as' => 'admin.currency_rates.update',
'uses' => 'CurrencyRateController@update',
'middleware' => 'can:admin.currency_rates.edit',
]);
Route::get('currency-rates/refresh', [
'as' => 'admin.currency_rates.refresh',
'uses' => 'CurrencyRateController@refresh',
'middleware' => 'can:admin.currency_rates.edit',
]);

View File

@@ -0,0 +1,5 @@
<?php
use Illuminate\Support\Facades\Route;
Route::get('current-currency/{code}', 'CurrentCurrencyController@store')->name('current_currency.store');

View File

@@ -0,0 +1,42 @@
<?php
namespace Modules\Currency\Services;
use Swap\Swap;
use Exchanger\Exception\Exception;
class CurrencyRateExchanger
{
/**
* Instance of swap.
*
* @var \Swap\Swap
*/
private $swap;
/**
* Create a new CurrencyRateExchanger instance.
*
* @param \Swap\Swap $swap
*/
public function __construct(Swap $swap)
{
$this->swap = $swap;
}
/**
* Exchange to the latest currency rate.
*
* @param string $fromCurrency
* @param string $toCurrency
* @return float|null
*/
public function exchange($fromCurrency, $toCurrency)
{
try {
return $this->swap->latest("{$fromCurrency}/{$toCurrency}")->getValue();
} catch (Exception $e) {
return 1;
}
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Modules\Currency\Sidebar;
use Maatwebsite\Sidebar\Item;
use Maatwebsite\Sidebar\Menu;
use Maatwebsite\Sidebar\Group;
use Modules\Admin\Sidebar\BaseSidebarExtender;
class SidebarExtender extends BaseSidebarExtender
{
public function extend(Menu $menu)
{
$menu->group(trans('admin::sidebar.system'), function (Group $group) {
$group->item(trans('admin::sidebar.localization'), function (Item $item) {
$item->item(trans('currency::currency_rates.currency_rates'), function (Item $item) {
$item->route('admin.currency_rates.index');
$item->weight(10);
$item->authorize(
$this->auth->hasAccess('admin.currency_rates.index')
);
});
});
});
}
}

View File

@@ -0,0 +1,31 @@
{
"name": "fleetcart/currency",
"description": "The FleetCart Currency Module.",
"authors": [
{
"name": "Envay Soft",
"email": "envaysoft@gmail.com"
}
],
"require": {
"php": "^8.0.2",
"florianv/swap": "^4.0",
"nyholm/psr7": "^1.2",
"php-http/curl-client": "^2.1",
"php-http/message": "^1.8"
},
"autoload": {
"psr-4": {
"Modules\\Currency\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}

View File

@@ -0,0 +1,11 @@
{
"name": "Currency",
"alias": "currency",
"description": "The FleetCart Currency Module.",
"priority": 100,
"providers": [
"Modules\\Currency\\Providers\\CurrencyServiceProvider",
"Modules\\Currency\\Providers\\EventServiceProvider",
"Modules\\Currency\\Providers\\CurrencyExchangeRateServiceProvider"
]
}

View File

@@ -0,0 +1,3 @@
let mix = require('laravel-mix');
mix.js(`${__dirname}/Resources/assets/admin/js/main.js`, `${__dirname}/Assets/admin/js/currency.js`);