Passed
Push — master ( c6d69a...dbe157 )
by Mr
02:16
created

Money::asBaseMoney()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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