Passed
Push — master ( f7cf63...077070 )
by Mr
02:14
created

Money   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Test Coverage

Coverage 86.79%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 36
dl 0
loc 129
ccs 46
cts 53
cp 0.8679
rs 10
c 2
b 0
f 0
wmc 20

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getAmount() 0 3 1
A equals() 0 4 1
A getCurrency() 0 3 1
A isNegative() 0 3 1
A percentage() 0 3 1
A asBaseMoney() 0 3 1
A isZero() 0 3 1
A multiply() 0 5 1
A isLessThanOrEqual() 0 4 1
A subtract() 0 6 1
A add() 0 6 1
A divide() 0 5 1
A isPositive() 0 3 1
A __toString() 0 3 1
A zero() 0 4 1
A __construct() 0 3 1
A isGreaterThanOrEqual() 0 4 1
A fromNative() 0 8 2
A toNative() 0 3 1
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/money-interop project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Daikon\Money\ValueObject;
10
11
use Daikon\Interop\Assertion;
12
use Daikon\Interop\InvalidArgumentException;
13
use Daikon\Money\ValueObject\MoneyInterface;
14
use Money\Currency as PhpCurrency;
15
use Money\Money as PhpMoney;
16
17
class Money implements MoneyInterface
18
{
19
    protected PhpMoney $money;
20
21
    /** @param static $comparator */
22 1
    public function equals($comparator): bool
23
    {
24 1
        Assertion::isInstanceOf($comparator, static::class);
25 1
        return $this->toNative() === $comparator->toNative();
26
    }
27
28 10
    public function getAmount(): string
29
    {
30 10
        return $this->money->getAmount();
31
    }
32
33 10
    public function getCurrency(): string
34
    {
35 10
        return $this->money->getCurrency()->getCode();
36
    }
37
38
    /** @return static */
39 1
    public function multiply($multiplier, int $roundingMode = self::ROUND_HALF_UP): self
40
    {
41 1
        Assertion::numeric($multiplier, 'Multipler must be numeric.');
42 1
        $multiplied = $this->money->multiply($multiplier, $roundingMode);
43 1
        return new static($multiplied);
44
    }
45
46
    /** @return static */
47 1
    public function divide($divisor, int $roundingMode = self::ROUND_HALF_UP): self
48
    {
49 1
        Assertion::numeric($divisor, 'Divider must be numeric.');
50 1
        $divided = $this->money->divide($divisor, $roundingMode);
51 1
        return new static($divided);
52
    }
53
54
    /** @return static */
55 1
    public function percentage($percentage, int $roundingMode = self::ROUND_HALF_UP): self
56
    {
57 1
        return $this->multiply($percentage)->divide(100, $roundingMode);
58
    }
59
60
    /** @return static */
61 2
    public function add(MoneyInterface $money): self
62
    {
63 2
        $added = $this->money->add(
64 2
            static::asBaseMoney($money->getAmount(), $money->getCurrency())
65
        );
66 2
        return new static($added);
67
    }
68
69
    /** @return static */
70 1
    public function subtract(MoneyInterface $money): self
71
    {
72 1
        $subtracted = $this->money->subtract(
73 1
            static::asBaseMoney($money->getAmount(), $money->getCurrency())
74
        );
75 1
        return new static($subtracted);
76
    }
77
78 1
    public function isZero(): bool
79
    {
80 1
        return $this->money->isZero();
81
    }
82
83
    public function isPositive(): bool
84
    {
85
        return $this->money->isPositive();
86
    }
87
88
    public function isNegative(): bool
89
    {
90
        return $this->money->isNegative();
91
    }
92
93
    public function isLessThanOrEqual(MoneyInterface $money): bool
94
    {
95
        return $this->money->lessThanOrEqual(
96
            static::asBaseMoney($money->getAmount(), $money->getCurrency())
97
        );
98
    }
99
100 1
    public function isGreaterThanOrEqual(MoneyInterface $money): bool
101
    {
102 1
        return $this->money->greaterThanOrEqual(
103 1
            static::asBaseMoney($money->getAmount(), $money->getCurrency())
104
        );
105
    }
106
107
    /**
108
     * @param string $value
109
     * @return static
110
     */
111 13
    public static function fromNative($value): self
112
    {
113 13
        Assertion::string($value, 'Must be a string.');
114 13
        if (!preg_match('/^(?<amount>-?\d+)\s?(?<currency>[a-z][a-z0-9]*)$/i', $value, $matches)) {
115 1
            throw new InvalidArgumentException('Invalid amount.');
116
        }
117
118 13
        return new static(static::asBaseMoney($matches['amount'], $matches['currency']));
119
    }
120
121
    /** @return static */
122 7
    public static function zero($currency = null): self
123
    {
124 7
        Assertion::regex($currency, '/^[a-z][a-z0-9]*$/i', 'Invalid currency.');
125 7
        return static::fromNative('0'.(string)$currency);
126
    }
127
128 7
    public function toNative(): string
129
    {
130 7
        return $this->getAmount().$this->getCurrency();
131
    }
132
133 4
    public function __toString(): string
134
    {
135 4
        return $this->toNative();
136
    }
137
138 13
    protected static function asBaseMoney(string $amount, string $currency): PhpMoney
139
    {
140 13
        return new PhpMoney($amount, new PhpCurrency($currency));
141
    }
142
143 13
    final protected function __construct(PhpMoney $money)
144
    {
145 13
        $this->money = $money;
146 13
    }
147
}
148