All Projects â†’ andriichuk â†’ laracash

andriichuk / laracash

Licence: MIT license
PHP Laravel Money Package 💰

Programming Languages

PHP
23972 projects - #3 most used programming language

Projects that are alternatives of or similar to laracash

flash
An easy way for Laravel flash notifications.
Stars: ✭ 14 (-73.08%)
Mutual labels:  laravel-package
crypton
Laravel Request & Response Encryption
Stars: ✭ 31 (-40.38%)
Mutual labels:  laravel-package
aliyun-oss-laravel
Laravel įš„ Aliyun OSS æ‰Šåą•, 支持 Laravel 9. Alibaba Cloud Object Storage Service For Laravel.
Stars: ✭ 91 (+75%)
Mutual labels:  laravel-package
bankster
Money Creation Made Easy
Stars: ✭ 30 (-42.31%)
Mutual labels:  money
laravel-repositories
DEPRECATED – A neat repository Pattern implementation for Laravel.
Stars: ✭ 18 (-65.38%)
Mutual labels:  laravel-package
laravel-secureheaders
🔒 SecureHeaders wrapper for Laravel.
Stars: ✭ 52 (+0%)
Mutual labels:  laravel-package
jwt-auth
🔐 JSON Web Token Authentication for Laravel & Lumen
Stars: ✭ 525 (+909.62%)
Mutual labels:  laravel-package
firebase-php
Firebase Realtime Database PHP Wrapper
Stars: ✭ 41 (-21.15%)
Mutual labels:  laravel-package
laravel-startkit
Laravel Admin Dashboard, Admin Template with Frontend Template, for scalable Laravel projects. It is to save your time when You start with new scalable Laravel projects with many features Bootstrap, cooreui, infyom admin Generator, roles and permissions, translatable models, spatie media and much more
Stars: ✭ 55 (+5.77%)
Mutual labels:  laravel-package
meituan-pub-union
🌈 įžŽå›ĸåˆ†é”€č”į›Ÿ PHP-SDK
Stars: ✭ 19 (-63.46%)
Mutual labels:  laravel-package
laravel-cache
An improved helper for working with cache
Stars: ✭ 64 (+23.08%)
Mutual labels:  laravel-package
laravel-geocode
Laravel Package to find Lat and Long of a given Address
Stars: ✭ 15 (-71.15%)
Mutual labels:  laravel-package
laravel-coming-soon
Laravel package to display Coming Soon page
Stars: ✭ 19 (-63.46%)
Mutual labels:  laravel-package
relations-widgets-for-backpack
Views/widgets for preview laravel relations in laravel backpack
Stars: ✭ 21 (-59.62%)
Mutual labels:  laravel-package
binaryapi
Binary.com & Deriv.com API for Python
Stars: ✭ 32 (-38.46%)
Mutual labels:  money
laravel-two-factor-authentication
A two-factor authentication package for Laravel >= 8
Stars: ✭ 37 (-28.85%)
Mutual labels:  laravel-package
laravel-spotify
Laravel-Spotify is a simple wrapper around the Spotify Web API that makes working with its endpoints a breeze!
Stars: ✭ 141 (+171.15%)
Mutual labels:  laravel-package
hurtrade
An Open Source Forex Trading Platform
Stars: ✭ 22 (-57.69%)
Mutual labels:  money
apitest
this is a tool for testing Laravel REST API
Stars: ✭ 11 (-78.85%)
Mutual labels:  laravel-package
django-concurrency-talk
🎭 Database Integrity in Django: Safely Handling Critical Data in Distributed Systems
Stars: ✭ 49 (-5.77%)
Mutual labels:  money

PHP Laravel Money Package

SWUbanner

Logo

GitHub stars Total Downloads Latest Stable Version Psalm type coverage Psalm enabled License

  • Laravel wrapper over the MoneyPHP library
  • Provides a convenient way to work with the money column as a Value Object
  • Uses the Custom Casts Laravel 7.x feature

Table of Contents

Features

  • Convenient work with the native the MoneyPHP library and Laravel Eloquent ORM
  • Money columns casting
  • Currencies columns casting
  • Supported concepts
    • Money columns with default Currency (without a specific column)
    • Currency columns without Money
    • Many Money columns reference to one Currency column
    • Money to Currencies columns mapping

Requirements

  • PHP ^8.0
  • Laravel v7.x|v8.x

Suggest

  • BCMath (ext-bcmath) and GMP (ext-gmp) PHP Extensions for calculations with large integers
  • Intl PHP Extension (ext-intl) for formatting

Installation

Require package

composer require andriichuk/laracash

Publish vendor settings

php artisan vendor:publish --provider="Andriichuk\Laracash\ServiceProviders\LaracashServiceProvider" --tag="config"

Default settings

[
    'currency' => 'USD',
    'locale' => 'en_US',
]

Usage Concepts

Money columns with default Currency

<?php

namespace App;

use Andriichuk\Laracash\Casts\MoneyCast;
use Illuminate\Database\Eloquent\Model;
use Money\Money;

/**
 * Class OrderItem
 *
 * @property Money $price
 * @property Money $discount
 */
class OrderItem extends Model
{
    protected $fillable = ['name', 'price', 'discount'];

    protected $casts = [
        'price' => MoneyCast::class,
        'discount' => MoneyCast::class,
    ];
}
OrderItem::create([
    'name' => 'Order Item',
    'price' => makeMoney(1000),
    'discount' => makeMoney(15),
]);

Currency columns without Money

<?php

namespace App;

use Andriichuk\Laracash\Casts\CurrencyCast;
use Andriichuk\Laracash\Model\HasCurrency;
use Andriichuk\Laracash\Model\HasCurrencyInterface;
use Illuminate\Database\Eloquent\Model;
use Money\Currency;

/**
 * Class Rate
 *
 * @property Currency $currency
 */
class Rate extends Model implements HasCurrencyInterface
{
    use HasCurrency;

    protected $fillable = ['name', 'price', 'currency', 'native_currency'];

    protected $casts = [
        'currency' => CurrencyCast::class,
        'native_currency' => CurrencyCast::class,
    ];
}
Rate::create([
    'name' => 'Rate #1', 
    'price' => 99, 
    'currency' => new Currency('USD'), 
    'native_currency' => 'UAH',
]);

Multiple Money columns refer to one Currency column

use Andriichuk\Laracash\Casts\CurrencyCast;
use Andriichuk\Laracash\Casts\MoneyCast;
use Andriichuk\Laracash\Model\HasCurrency;
use Andriichuk\Laracash\Model\HasMoneyWithCurrency;
use Andriichuk\Laracash\Model\HasMoneyWithCurrencyInterface;
use Illuminate\Database\Eloquent\Model;
use Money\Currency;
use Money\Money;

/**
 * Class Transaction
 *
 * @property Money $payment_amount
 * @property Money $discount
 * @property Currency $currency
 */
class Transaction extends Model implements HasMoneyWithCurrencyInterface
{
    use HasMoneyWithCurrency;
    use HasCurrency;

    protected $fillable = ['name', 'payment_amount', 'discount', 'currency'];

    protected $casts = [
        'payment_amount' => MoneyCast::class,
        'discount' => MoneyCast::class,
        'currency' => CurrencyCast::class,
    ];

    public function getCurrencyColumnFor(string $field): string
    {
        return 'currency';
    }
}

If the currency is in a related model, just return an empty string ('') in getCurrencyColumnFor().

Money to Currencies columns mapping

use Andriichuk\Laracash\Casts\CurrencyCast;
use Andriichuk\Laracash\Casts\MoneyCast;
use Andriichuk\Laracash\Model\HasCurrency;use Andriichuk\Laracash\Model\HasMoneyWithCurrency;
use Andriichuk\Laracash\Model\HasMoneyWithCurrencyInterface;
use Illuminate\Database\Eloquent\Model;
use Money\Currency;
use Money\Money;

/**
 * Class Product
 *
 * @property Money $payment_amount
 * @property Money $discount
 * @property Currency $currency
 */
class Product extends Model implements HasMoneyWithCurrencyInterface 
{
    use HasMoneyWithCurrency;
    use HasCurrency;

    protected $fillable = ['name', 'price', 'currency', 'book_price', 'native_currency'];

    protected $casts = [
        'price' => MoneyCast::class,
        'currency' => CurrencyCast::class,

        'book_price' => MoneyCast::class,
        'native_currency' => CurrencyCast::class
    ];

    public function getCurrencyColumnFor(string $field): string
    {
        return [
            'price' => 'currency',
            'book_price' => 'native_currency',
        ][$field] ?? '';
    }
}
Product::create([
    'price' => \Money\Money::USD(1000),
    'book_price' => Money::UAH(25000),
]);

If you want to use magic accessors (*_as_currency, *_as_decimal) for money fields then you should add HasMoney trait to your Eloquent Model (accessors will be added automatically)

<?php

namespace App;

use Andriichuk\Laracash\Casts\MoneyCast;
use Andriichuk\Laracash\Model\HasMoney;
use Illuminate\Database\Eloquent\Model;
use Money\Money;

/**
 * Class Product
 *
 * @property Money $price
 * @property-read string $price_as_currency
 * @property-read string $price_as_decimal
 */
class Product extends Model
{
    use HasMoney;

    protected $fillable = ['name', 'price'];

    protected $casts = [
        'price' => MoneyCast::class,
    ];
}

Now you can call magic fields

use App\Product;

$product = Product::find(1);

$product->price_as_decimal; // "10.00"
$product->price_as_currency; // "$10.00"

$product->price = 5000;

$product->price_as_decimal; // "50.00"
$product->price_as_currency; // "$50.00"

Display money data in the form input field

Assign model

use App\Product;
use Illuminate\Support\Facades\Route;

Route::view('/', 'productForm', ['product' => Product::find(1)]);

Present money object as a decimal value

<input type="number" name="price" value="{{ formatMoneyAsDecimal($product->price) }}">

{{-- or with magic syntax --}}
<input type="number" name="price" value="{{ $product->price_as_decimal }}">

Parse money from request field

use App\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('products/{product}', function (Product $product, Request $request) {
    $product->price = parseMoneyDecimal($request->get('price')); // 55.99 => Money::USD(5599)
});

Using in API resources

Define model resource

use App\Product;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * Class ProductResource
 *
 * @mixin Product
 */
final class ProductResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'price' => $this->price,
            'price_as_currency' => $this->price_as_currency, // or formatMoneyAsCurrency($this->price)
        ];
    }
}

Apply resource to the model

use App\Product;
use App\Http\Resources\ProductResource;

Route::get('products/{product}', function (Product $product) {
    return new ProductResource($product);
});

Output

{
  "data": {
    "id": 1,
    "name": "Product name",
    "price": {
      "amount": "1000",
      "currency": "USD"
    },
    "price_as_currency": "$10.00"
  }
}

Model Creation

Using scalar values (int|string)

use App\Product;

Product::create([
    'name' => 'The First Product',
    'price' => 100,
]);

Using Money\Money object:

use App\Product;
use Money\Money;

Product::create([
    'name' => 'The Second Product',
    'price' => Money::USD(100),
]);

Using facade:

use Andriichuk\Laracash\Facades\Laracash;
use App\Product;

Product::create([
    'name' => 'The Third Product',
    'price' => Laracash::factory()->make(100)
]);

Using helper function:

use App\Product;

Product::create([
    'name' => 'The Fourth Product',
    'price' => makeMoney(100)
]);

Bitcoin creation

use Andriichuk\Laracash\Facades\Laracash;
use Money\Money;

// Using Facade
Laracash::factory()->makeBitcoin(1000000000);

// Using helper
makeBitcoin(1000000000);

// Using native library factory call
Money::XBT(1000000000);

Retrieving data

use App\Product;

$product = Product::find(1);

dd($product->price);
Money\Money {#403 â–ŧ
  -amount: "1000"
  -currency: Money\Currency {#404 â–ŧ
    -code: "USD"
  }
}

Operations

Check original library docs for more information

use Andriichuk\Laracash\Facades\Laracash;
use App\Product;

$product = Product::find(1);

$product->price = $product->price->add(Laracash::factory()->make(2000));

$product->save();

API

Creation

Money instance creation using Laracash facade.

*If you do not pass the second argument currency, then it will take from config file

use \Andriichuk\Laracash\Facades\Laracash;

Laracash::factory()->make(1000);
Laracash::factory()->make('10000000000000');

Specify currency

use \Andriichuk\Laracash\Facades\Laracash;
use \Money\Currency;

Laracash::factory()->make(1000, 'USD');
Laracash::factory()->make(1000, new Currency('USD'));

// Or use native method Money::USD(100)
Money\Money {#403 â–ŧ
  -amount: "1000"
  -currency: Money\Currency {#404 â–ŧ
    -code: "USD"
  }
}

Formatting

Money instance formatting. More info

Decimal

use \Andriichuk\Laracash\Facades\Laracash;
use Money\Money;

Laracash::formatter()->formatAsDecimal(Money::USD(100)); // "1.00"
formatMoneyAsDecimal(Money::USD(100)); // "1.00"

Using Intl extension

use \Andriichuk\Laracash\Facades\Laracash;
use Money\Money;

Laracash::formatter()->formatAsIntlDecimal(Money::USD(100)); // "1"
Laracash::formatter()->formatAsIntlDecimal(Money::USD(100), 'uk_UA'); // "1"

Intl currency

use \Andriichuk\Laracash\Facades\Laracash;
use Money\Money;

Laracash::formatter()->formatAsIntlCurrency(Money::USD(100)); // "$1.00"
Laracash::formatter()->formatAsIntlCurrency(Money::USD(100), 'uk_UA'); // "1,00 USD"
formatMoneyAsCurrency(Money::USD(100)); // "$1.00"
formatMoneyAsCurrency(Money::XBT(1000000000)); // "Ƀ10.00"

Specify custom Intl formatting style

use \Andriichuk\Laracash\Facades\Laracash;
use Money\Money;
use NumberFormatter;

Laracash::formatter()->formatIntlWithStyle(Money::USD(100), 'en_US', NumberFormatter::SPELLOUT); // "one"
Laracash::formatter()->formatIntlWithStyle(Money::USD(100), 'en_US', NumberFormatter::SCIENTIFIC); // "1E0"

Bitcoin

use \Andriichuk\Laracash\Facades\Laracash;
use Money\Money;

Laracash::formatter()->formatBitcoin(Money::XBT(1000000000)); // "Ƀ10.00"

// or use helper function
formatMoneyAsCurrency(makeBitcoin(1000000000)); // "Ƀ10.00"

Bitcoin as decimal

use \Andriichuk\Laracash\Facades\Laracash;
use Money\Money;

Laracash::formatter()->formatBitcoinAsDecimal(Money::XBT(1000000000)); // "10.00000000"

// or use helper function
formatMoneyAsDecimal(makeBitcoin(1000000000)); // "10.00000000"

Parsing

More info

Intl parse money string with currency

use Andriichuk\Laracash\Facades\Laracash;

Laracash::parser()->parseIntlCurrency('$1.00');

Result

Money\Money {#369 â–ŧ
    -amount: "100"
    -currency: Money\Currency {#368 â–ŧ
      -code: "USD"
    }
  }

Parse decimal

use Andriichuk\Laracash\Facades\Laracash;

Laracash::parser()->parseDecimal('1.30');
parseMoneyDecimal('1.30');

Result

Money\Money {#368 â–ŧ
  -amount: "130"
  -currency: Money\Currency {#367 â–ŧ
    -code: "USD"
  }
}

Tests

Run features and unit tests:

./vendor/bin/phpunit

Credits

License

Laracash is an open-sourced software licensed under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].