phspa / laravel-currencies
Requires
- php: >=7.4.0|^8.0
- illuminate/container: ^8.0|^9.0|^10.0
- illuminate/support: ^8.0|^9.0|^10.0
Requires (Dev)
- calebporzio/sushi: ^2.0
- fakerphp/faker: ^1.4
- mockery/mockery: ^1.5
- nunomaduro/larastan: ^1.0|^2.0
- orchestra/testbench: ^6.0|^7.0|^8.0
- phpunit/phpunit: ^9.5|^10.0
This package is auto-updated.
Last update: 2024-10-11 04:10:17 UTC
README
This package provides a convenient and powerful way of interacting with currencies and amounts in Laravel.
This package was originally from: https://github.com/makeabledk/laravel-currencies
Install
You can install this package via composer:
composer require phpsa/laravel-currencies
After installation you mus publish and run migrations to create the currencies
table
php artisan vendor:publish --provider="Phpsa\LaravelCurrencies\CurrenciesServiceProvider"
php artisan migrate
Setup
Recommended: Seed currencies
This package provides a eloquent 'Currency' model out of the box that fetches available currencies from your database.
Often you would want to seed these currencies from your code in order to normalize them across environments. This can easily be achieved with the Laravel Production Seeding package.
Create the following seeder and let it run on each deployment:
<?php class CurrencySeeder extends \Illuminate\Database\Seeder { use \Phpsa\ProductionSeeding\SyncStrategy; /** * @var array */ protected $currencies = [ [ 'code' => 'EUR', 'exchange_rate' => 100 ], [ 'code' => 'DKK', 'exchange_rate' => 750 ], // ... ]; /** * Seed the currencies */ public function run() { $this->apply($this->currencies, \Phpsa\LaravelCurrencies\Currency::class, 'code'); } }
Now your database table should look something like this:
Tip: Consider using https://github.com/dwightwatson/rememberable to cache currencies and throttle database queries.
Tip: If you don't want to hardcode exchange rates, create a console-command that fetches and updates from an external service, and ommit the field from the seeder.
Register base currency (required)
The amount object requires a base currency that it uses to convert between currencies.
The exchange rates given for your currencies must all relate to the base currency.
Define it in your AppServiceProvider@boot
:
public function boot() { $this->app->singleton(\Phpsa\LaravelCurrencies\Contracts\BaseCurrency::class, function () { return \Phpsa\LaravelCurrencies\Currency::fromCode('EUR'); }); }
Register default currency (optional)
Additionally you have the option to define a default currency if this is not the same as your base-currency.
You may want to have a global currency such as USD or EUR for your base-currency to perform conversions, meanwhile your application defaults to display a local currency.
This can be achieved by defining a default-currency in your AppServiceProvider@boot
as well:
public function boot() { // Define base currency // [...] // Define default currency $this->app->singleton(\Phpsa\LaravelCurrencies\Contracts\BaseCurrency::class, function () { return \Phpsa\LaravelCurrencies\Currency::fromCode('DKK'); }); }
Now when instantiating an amount without an explicit Currency it will default to 'DKK':
new Amount (100); // 100 DKK Amount::zero(); // 0 DKK
Example usages
Quickly create an amount
new Amount(100); // EUR since that's our default new Amount(100, Currency::fromCode('DKK')); new Amount(100, 'DKK'); // It automatically instantiates a currency instance given a currency-code
Convert between currencies
$eur = new Amount(100); $dkk = $eur->convertTo('DKK'); // 750 DKK
Perform simple calculations - even between currencies!
$amount = new Amount(100, 'EUR'); $amount->subtract(new Amount(50)); // 50 eur $amount->subtract(new Amount(375, 'DKK')); // 50 eur
Imagine you have a Product eloquent model with a @getPriceAttribute() accessor that returns an Amount object, you can even do this:
$products = Product::all(); $productsTotalSum = Amount::sum($products, 'price');
Use the fluent modifiers for easy manipulation
$amount = new Amount(110); // Ensure that the amount at least a certain amount $amount->minimum(new Amount(80)); // 110 EUR $amount->minimum(new Amount(120)); // 120 EUR // Ensure that the amount is no bigger than a certain amount $amount->maximum(new Amount(80)); // 80 EUR $amount->maximum(new Amount(750, 'DKK'); // 100 EUR (eq. 750 DKK)
Easily export as an array, and re-instantiate if needed. Great for serving client API*.
$exported = (new Amount(100))->toArray(); // ['amount' => 100, 'currency' => 'EUR', 'formatted' => 'EUR 100'] $imported = Amount::fromArray($exported);
*Note it implements illuminate/support Arrayable contract, so it automatically casts to an array for eloquent models.
Change log
Please see CHANGELOG for more information what has changed recently.
Testing
You can run the tests with:
composer test
Contributing
We are happy to receive pull requests for additional functionality. Please see CONTRIBUTING for details.
Credits
License
Attribution-ShareAlike 4.0 International. Please see License File for more information.