1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Assimtech\Money; |
4
|
|
|
|
5
|
|
|
use InvalidArgumentException; |
6
|
|
|
|
7
|
|
|
class Accountant |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* @param Money $money1 |
11
|
|
|
* @param Money $money2 |
12
|
|
|
* @throws InvalidArgumentException |
13
|
|
|
*/ |
14
|
4 |
|
protected function checkCurrenciesMatch(Money $money1, Money $money2) |
15
|
|
|
{ |
16
|
4 |
|
if ($money1->getCurrency()->getCode() !== $money2->getCurrency()->getCode()) { |
17
|
1 |
|
throw new InvalidArgumentException(sprintf( |
18
|
1 |
|
'Cannot work with monies of differing currencies (%s, %s)', |
19
|
1 |
|
$money1, |
20
|
|
|
$money2 |
21
|
1 |
|
)); |
22
|
|
|
} |
23
|
3 |
|
} |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* $money1 + $money2 |
27
|
|
|
* |
28
|
|
|
* @param Money $money1 |
29
|
|
|
* @param Money $money2 |
30
|
|
|
* @return Money |
31
|
|
|
*/ |
32
|
3 |
View Code Duplication |
public function add(Money $money1, Money $money2) |
|
|
|
|
33
|
|
|
{ |
34
|
3 |
|
$this->checkCurrenciesMatch($money1, $money2); |
35
|
|
|
|
36
|
2 |
|
return new Money( |
37
|
2 |
|
$money1->getAmount() + $money2->getAmount(), |
38
|
2 |
|
$money1->getCurrency() |
39
|
2 |
|
); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* $money1 - $money2 |
44
|
|
|
* |
45
|
|
|
* @param Money $money1 |
46
|
|
|
* @param Money $money2 |
47
|
|
|
* @return Money |
48
|
|
|
*/ |
49
|
1 |
View Code Duplication |
public function subtract(Money $money1, Money $money2) |
|
|
|
|
50
|
|
|
{ |
51
|
1 |
|
$this->checkCurrenciesMatch($money1, $money2); |
52
|
|
|
|
53
|
1 |
|
return new Money( |
54
|
1 |
|
$money1->getAmount() - $money2->getAmount(), |
55
|
1 |
|
$money1->getCurrency() |
56
|
1 |
|
); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* $money * $fraction |
61
|
|
|
* |
62
|
|
|
* @param Money $money |
63
|
|
|
* @param float|integer $fraction |
64
|
|
|
* @return Money |
65
|
|
|
*/ |
66
|
1 |
|
public function multiply(Money $money, $fraction) |
67
|
|
|
{ |
68
|
1 |
|
return new Money( |
69
|
1 |
|
$money->getAmount() * $fraction, |
70
|
1 |
|
$money->getCurrency() |
71
|
1 |
|
); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* $money / $fraction |
76
|
|
|
* |
77
|
|
|
* @param Money $money |
78
|
|
|
* @param float|integer $fraction |
79
|
|
|
* @return Money |
80
|
|
|
*/ |
81
|
1 |
|
public function divide(Money $money, $fraction) |
82
|
|
|
{ |
83
|
1 |
|
return new Money( |
84
|
1 |
|
$money->getAmount() / $fraction, |
85
|
1 |
|
$money->getCurrency() |
86
|
1 |
|
); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @param Money[] $monies |
91
|
|
|
* @return Money|null |
92
|
|
|
*/ |
93
|
2 |
|
public function sum(array $monies) |
94
|
|
|
{ |
95
|
2 |
|
$totalMoney = null; |
96
|
|
|
|
97
|
2 |
|
foreach ($monies as $money) { |
98
|
2 |
|
if (!$money instanceof Money) { |
99
|
1 |
|
throw new InvalidArgumentException('$monies must be an array of Money'); |
100
|
|
|
} |
101
|
|
|
|
102
|
1 |
|
if ($totalMoney === null) { |
103
|
1 |
|
$totalMoney = clone $money; |
104
|
|
|
|
105
|
1 |
|
continue; |
106
|
|
|
} |
107
|
|
|
|
108
|
1 |
|
$totalMoney = $this->add($totalMoney, $money); |
109
|
1 |
|
} |
110
|
|
|
|
111
|
1 |
|
return $totalMoney; |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.