CurrencyPair::getRatio()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 2
eloc 2
nc 2
nop 1
crap 2
1
<?php namespace Keios\MoneyRight;
2
3
/**
4
 * This file is part of the arbitrary precision arithmetic-based
5
 * money value object Keios\MoneyRight package. Keios\MoneyRight
6
 * is heavily inspired by Mathias Verroes' Money library and was
7
 * designed to be a drop-in replacement (only some use statement
8
 * tweaking required) for mentioned library. Public APIs are
9
 * identical, functionality is extended with additional methods
10
 * and parameters.
11
 *
12
 *
13
 * Copyright (c) 2015 Łukasz Biały
14
 *
15
 * For the full copyright and license information, please view the
16
 * LICENSE file that was distributed with this source code.
17
 */
18
19
use Keios\MoneyRight\Exceptions\InvalidArgumentException;
20
21
/**
22
 * Class CurrencyPair
23
 *
24
 * @package Keios\MoneyRight
25
 * @see http://en.wikipedia.org/wiki/Currency_pair
26
 */
27
class CurrencyPair
28
{
29
    /** @var Currency */
30
    private $baseCurrency;
31
32
    /** @var Currency */
33
    private $counterCurrency;
34
35
    /** @var string */
36
    private $ratio;
37
38
    /**
39
     * @param \Keios\MoneyRight\Currency $baseCurrency
40
     * @param \Keios\MoneyRight\Currency $counterCurrency
41
     * @param float                      $ratio
42
     *
43
     * @throws \Keios\MoneyRight\Exceptions\InvalidArgumentException
44
     */
45 33
    public function __construct(Currency $baseCurrency, Currency $counterCurrency, $ratio)
46
    {
47 33
        if (!is_numeric($ratio)) {
48 9
            throw new InvalidArgumentException(
49 9
                sprintf('Ratio must be numeric, %s of value %s given.', gettype($ratio), (string) $ratio)
50 9
            );
51
        }
52
53 24
        $this->counterCurrency = $counterCurrency;
54 24
        $this->baseCurrency = $baseCurrency;
55 24
        $this->ratio = Math::bcround((string) $ratio, Money::GAAP_PRECISION);
56 24
    }
57
58
    /**
59
     * @param string $iso String representation of the form "EUR/USD 1.2500"
60
     *
61
     * @throws \Exception
62
     * @return \Keios\MoneyRight\CurrencyPair
63
     */
64 6
    public static function createFromIso($iso)
65
    {
66 6
        $currency = "([A-Z]{2,3})";
67 6
        $ratio = "([0-9]*\.?[0-9]+)"; // @see http://www.regular-expressions.info/floatingpoint.html
68 6
        $pattern = '/'.$currency.'\/'.$currency.' '.$ratio.'/';
69
70 6
        $matches = [];
71 6
        if (!preg_match($pattern, $iso, $matches)) {
72 3
            throw new InvalidArgumentException(
73 3
                sprintf(
74 3
                    "Can't create currency pair from ISO string '%s', format of string is invalid",
75
                    $iso
76 3
                )
77 3
            );
78
        }
79
80 3
        return new static(new Currency($matches[1]), new Currency($matches[2]), $matches[3]);
81
    }
82
83
    /**
84
     * @param \Keios\MoneyRight\Money $money
85
     * @param mixed                   $roundingMode
86
     *
87
     * @throws \Keios\MoneyRight\Exceptions\InvalidArgumentException
88
     * @return \Keios\MoneyRight\Money
89
     */
90 9
    public function convert(Money $money, $roundingMode = Money::ROUND_HALF_UP)
91
    {
92 9
        if (!$money->getCurrency()->equals($this->baseCurrency)) {
93 3
            throw new InvalidArgumentException(
94 3
                sprintf('Currencies must match: Money to convert has currency %s, while CurrencyPair has base currency %s.',
95 3
                    $money->getCurrency()->getIsoCode(),
96 3
                    $this->baseCurrency->getIsoCode()
97 3
                )
98 3
            );
99
        }
100
101 6
        return new Money(
102 6
            Math::bcround(
103 6
                bcmul($money->getAmountString(), $this->ratio, Money::GAAP_PRECISION + 1),
104 6
                Money::GAAP_PRECISION,
105
                $roundingMode
106 6
            ),
107 6
            $this->counterCurrency
108 6
        );
109
    }
110
111
    /**
112
     * @return \Keios\MoneyRight\Currency
113
     */
114 3
    public function getCounterCurrency()
115
    {
116 3
        return $this->counterCurrency;
117
    }
118
119
    /**
120
     * @return \Keios\MoneyRight\Currency
121
     */
122 3
    public function getBaseCurrency()
123
    {
124 3
        return $this->baseCurrency;
125
    }
126
127
    /**
128
     * @param bool $usePrecision
129
     *
130
     * @return float
131
     */
132 6
    public function getRatio($usePrecision = false)
133
    {
134 6
        return $usePrecision ? bcadd($this->ratio, '0', Money::GAAP_PRECISION) : (float) $this->ratio;
135
    }
136
}