Passed
Push — master ( 4b3210...ce7ac7 )
by Mr
06:36
created

Money::multiply()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
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 Assert\Assertion;
12
use Daikon\Money\ValueObject\MoneyInterface;
13
use InvalidArgumentException;
14
use Money\Currency as PhpCurrency;
15
use Money\Money as PhpMoney;
16
17
final class Money implements MoneyInterface
18
{
19
    private PhpMoney $money;
20
21
    /** @param self $comparator */
22 1
    public function equals($comparator): bool
23
    {
24 1
        Assertion::isInstanceOf($comparator, self::class);
25 1
        return $this->toNative() === $comparator->toNative();
26
    }
27
28 8
    public function getAmount(): string
29
    {
30 8
        return $this->money->getAmount();
31
    }
32
33 8
    public function getCurrency(): string
34
    {
35 8
        return $this->money->getCurrency()->getCode();
36
    }
37
38
    /** @param float|int|string $multiplier */
39
    public function multiply($multiplier, int $roundingMode = self::ROUND_HALF_UP): self
40
    {
41
        Assertion::numeric($multiplier, 'Multipler must be numeric.');
42
        $multiplied = $this->money->multiply($multiplier, $roundingMode);
43
        return new self($multiplied);
44
    }
45
46
    /** @param float|int|string $divisor */
47
    public function divide($divisor, int $roundingMode = self::ROUND_HALF_UP): self
48
    {
49
        Assertion::numeric($divisor, 'Divider must be numeric.');
50
        $divided = $this->money->divide($divisor, $roundingMode);
51
        return new self($divided);
52
    }
53
54 3
    public function add(MoneyInterface $money): self
55
    {
56 3
        $added = $this->money->add(
57 3
            self::asBaseMoney($money->getAmount(), $money->getCurrency())
58
        );
59 3
        return new self($added);
60
    }
61
62 1
    public function subtract(MoneyInterface $money): self
63
    {
64 1
        $subtracted = $this->money->subtract(
65 1
            self::asBaseMoney($money->getAmount(), $money->getCurrency())
66
        );
67 1
        return new self($subtracted);
68
    }
69
70 1
    public function isZero(): bool
71
    {
72 1
        return $this->money->isZero();
73
    }
74
75
    public function isPositive(): bool
76
    {
77
        return $this->money->isPositive();
78
    }
79
80
    public function isNegative(): bool
81
    {
82
        return $this->money->isNegative();
83
    }
84
85
    public function isLessThanOrEqual(MoneyInterface $money): bool
86
    {
87
        return $this->money->lessThanOrEqual(
88
            self::asBaseMoney($money->getAmount(), $money->getCurrency())
89
        );
90
    }
91
92
    public function isGreaterThanOrEqual(MoneyInterface $money): bool
93
    {
94
        return $this->money->greaterThanOrEqual(
95
            self::asBaseMoney($money->getAmount(), $money->getCurrency())
96
        );
97
    }
98
99
    /** @param string $value */
100 8
    public static function fromNative($value): self
101
    {
102 8
        Assertion::string($value, 'Must be a string.');
103 8
        if (!preg_match('#^(?<amount>-?[0-9]+)(?<currency>[A-Z][A-Z0-9]*)$#', $value, $matches)) {
104 1
            throw new InvalidArgumentException('Invalid amount.');
105
        }
106
107 8
        return new self(self::asBaseMoney($matches['amount'], $matches['currency']));
108
    }
109
110 5
    public static function zero($currency = null): self
111
    {
112 5
        Assertion::regex($currency, '#^[A-Z][A-Z0-9]*$#', 'Invalid currency.');
113 5
        return self::fromNative('0'.(string)$currency);
114
    }
115
116 7
    public function toNative(): string
117
    {
118 7
        return $this->getAmount().$this->getCurrency();
119
    }
120
121 4
    public function __toString(): string
122
    {
123 4
        return $this->toNative();
124
    }
125
126 8
    private static function asBaseMoney(string $amount, string $currency): PhpMoney
127
    {
128 8
        return new PhpMoney($amount, new PhpCurrency($currency));
129
    }
130
131 8
    private function __construct(PhpMoney $money)
132
    {
133 8
        $this->money = $money;
134 8
    }
135
}
136