2017 © Pedro Peláez
 

symfony-bundle money-bundle

A series of money related utility classes wrapping integer math and money fractional allocation.

image

matmar10/money-bundle

A series of money related utility classes wrapping integer math and money fractional allocation.

  • Wednesday, May 18, 2016
  • by matmar10
  • Repository
  • 1 Watchers
  • 1 Stars
  • 21 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 1 Forks
  • 0 Open issues
  • 4 Versions
  • 0 % Grown

The README.md

Money Bundle

MAINTAINER WANTER - issue reports and pull requests will not be actively investigated. I am happy to advise, but I'm not longer actively using/maintaing this library. Please let me know if you're interested in taking over ownership of the repo., (*1)

Overview

Symfony2 Bundle wrapping common Money and Currency related needs such as integer-based math, currency codes, and money conversion., (*2)

Installation

Add the package to your composer.json file:, (*3)

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/matmar10/money-bundle
        }
    ],
    "require": {
        "matmar10/money-bundle": "dev-master"
    }
}

Creating Objects

Currencies are identified by a currency code and have a calculation and display precision:, (*4)


$eur = new Currency('EUR', 2, 2); $euros = new Money($eur); $euros->setAmountFloat(1.99);

Basic Math

The Money object wraps all basic math functions using underlying integer math to avoid the (problems with floating point math)[http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency]., (*5)

All amounts are stored as integer values internally using the calculation precision as the scale., (*6)


// must use a valid iso4217 currency code // with the exception of BTC for Bitcoin, as specified in the override configuration $usd = new Currency('USD', 5, 2); $usdAmount1 = new Money($usd); $usdAmount1->setAmountFloat(1.2345); $usdAmount2 = new Money($usd); $usdAmount2->setAmountFloat(1.2345); $usdAmount1->isEqual($usdAmount2); // true $resultAmount1 = $usdAmount1->add($usdAmount2); echo $resultAmount1->getAmountDisplay(); // 2.47 $resultAmount2 = $usdAmount1->subtract($usdAmount2); echo $resultAmount2->getAmountFloat(); // 0 $resultAmount3 = $usdAmount1->multiply(3); echo $resultAmount3->getAmountFloat(); // 3.7035 echo $resultAmount3->getAmountDisplay(); // 3.70 $resultAmount4 = $usdAmount1->divide(2); echo $resultAmount3->getAmountFloat(); // 0.61725 echo $resultAmount3->getAmountDisplay(); // 0.62

Dealing with Fractional Cents

How do you divide $10 evenly amongst three people? In reality, you can't divide fractional cents., (*7)

Really, you want to end up with three equal-ish shares:, (*8)

  • $3.34
  • $3.33
  • $3.33

$eurAmount = new Money(new Currency('EUR', 2, 2)); $eurAmount->setAmountFloat(10); // split the 10 euros into three equal parts using euro cents as the smallest unit $shares = $eurAmount->allocate(array(1, 1, 1), 2); $shares[0]->getAmountFloat(); // 3.34 $shares[1]->getAmountFloat(); // 3.33 $shares[2]->getAmountFloat(); // 3.33

Converting Between Currencies

Use the CurrencyPair object to convert between disparate currencies using an exchange rate:, (*9)

Note that the rate works bi-directionally:, (*10)


$gbp = new Currency('GBP', 2, 2); $usd = new Currency('USD', 2, 2); $gbpAmount = new Money($gbp); $gbpAmount->setAmountFloat(10); // 1 GBP = 1.5 USD $gbpToUsd = new CurrencyPair($gbp, $usd, 1.5); $usdAmount = $gbpToUsd->convert($gbpAmount); echo $usdAmount->getDisplay(); // 15.00 $gbpAmount2 = $gbpToUsd->convert($usdAmount); echo $gbpAmount2->getDisplay(); // 10.00

Currency Manager Service

Instead of building up currencies and money objects manually all the time, consider using the lmh_money.currency_manager service that is registered into Symfony's dependency injection container., (*11)

The manager supports providing an ISO country or currency code:, (*12)


// inside a Symfony controller, for example $manager = $this->getContainer()->get('lmh_money.currency_manager'); $amount = $manager->getMoney('ES'); echo $amount->getCurrency(); // EUR $amount->setAmountFloat(100); // 1 USD = 0.75 EUR $pair = $manager->getPair('US', 'ES', 0.75); $converted = $pair->convert($amount); echo $converted->getAmountDisplay(); // 75.00

Adding New Currencies

You can add new currencies that are not supported by default. This is useful, for example to add alternative currencies such as Litecoin and Ripple, (*13)


// inside a config file, such as app/config/config.yml matmar10_money: currencies: LTC: { displayPrecision: 5, calculationPrecision: 8, symbol: 'Ł' } XRP: { displayPrecision: 8, calculationPrecision: 8 }

Currency Alias

Alias handling for currencies, to set the currency settings "Euro" equel to "EUR", extend the config like this:, (*14)

matmar10_money:
    currencies:
        Euro:
            alias: EUR

Currency Validator

The Bundle also includes a Symfony validator for use in validating an entity's attribute is a valid currency code using (Symfony's Validator component)[https://github.com/symfony/Validator]., (*15)

Example use of the annotation:, (*16)

<?php

// inside an entity file, such as src/Bundle/AcmeBundle/Entity/Purchase.php

namespace Acme\Bundle\AcmeBundle\Entity;

use Lmh\Bundle\MoneyBundle\Validator\Constraints as Assert;

class Purchase
{
    /**
     * @Assert\CurrencyCode()
     */
    public $currency;

}

Using in the validator (see (Validator Component docs for details)[https://github.com/symfony/Validator] ):, (*17)

<?php

use Acme\Bundle\AcmeBundle;
use Symfony\Component\Validator\Validation;

$validator = Validation::createValidatorBuilder()
    ->enableAnnotationMapping()
    ->getValidator();

$purchase = new Purchase()
$purchase->currency = 'invalid-this-is-not-a-code';
$violations = $validator->validate($purchase);

Embedded Money object in a Doctrine Entity

Money object is prepared to handle doctrine embedded style: http://doctrine-orm.readthedocs.org/en/latest/tutorials/embeddables.html, (*18)

Add this to your config:, (*19)

doctrine:
    orm:
        mappings:
            Matmar10MoneyBundle:
                type: annotation
                dir: %kernel.root_dir%/../vendor/matmar10/lib-money/src/Matmar10/Money/Entity
                is_bundle: false
                prefix: 'Matmar10\Money\Entity'

Inside your entity:, (*20)

<?php

namespace foo\bar;

use Doctrine\ORM\Mapping as ORM;

class Invoice {

    /**
     * @var \Matmar10\Money\Entity\Money
     * @ORM\Embedded(columnPrefix="price_", class="Matmar10\Money\Entity\Money")
     */
    private $price;

}

your table should now these two new columns:, (*21)

  • price_amount // price as INTEGER value
  • price_currency // currency code like "EUR"

The Versions

18/05 2016

dev-master

9999999-dev

A series of money related utility classes wrapping integer math and money fractional allocation.

  Sources   Download

Apache

The Requires

 

The Development Requires

validator currency money currency code integer math iso4217

13/07 2014

2.0.0

2.0.0.0

A series of money related utility classes wrapping integer math and money fractional allocation.

  Sources   Download

Apache

The Requires

 

The Development Requires

validator currency money currency code integer math iso4217

22/12 2013

dev-composite

dev-composite

A series of money related utility classes wrapping integer math and money fractional allocation.

  Sources   Download

Apache

The Requires

 

validator currency money currency code integer math iso4217

13/10 2013

dev-exchange-rate-entity

dev-exchange-rate-entity

A series of money related utility classes wrapping integer math and money fractional allocation.

  Sources   Download

Apache

The Requires

 

validator currency money currency code integer math iso4217