1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* PHP Billing Library |
4
|
|
|
* |
5
|
|
|
* @link https://github.com/hiqdev/php-billing |
6
|
|
|
* @package php-billing |
7
|
|
|
* @license BSD-3-Clause |
8
|
|
|
* @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/) |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace hiqdev\php\billing\charge; |
12
|
|
|
|
13
|
|
|
use DateTimeImmutable; |
14
|
|
|
use hiqdev\php\billing\bill\Bill; |
15
|
|
|
use hiqdev\php\billing\bill\BillInterface; |
16
|
|
|
use hiqdev\php\units\QuantityInterface; |
17
|
|
|
use Money\Money; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @author Andrii Vasyliev <[email protected]> |
21
|
|
|
*/ |
22
|
|
|
class Aggregator implements AggregatorInterface |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var BillInterface[] |
26
|
|
|
*/ |
27
|
|
|
protected $bills = []; |
28
|
|
|
|
29
|
1 |
|
public function aggregateCharges(array $charges) |
30
|
|
|
{ |
31
|
1 |
|
$bills = []; |
32
|
1 |
|
foreach ($charges as $charge) { |
33
|
1 |
|
if (is_array($charge)) { |
34
|
1 |
|
$others = $this->aggregateCharges($charge); |
35
|
1 |
|
$bills = $this->aggregateBills($bills, $others); |
36
|
1 |
|
} elseif ($charge instanceof ChargeInterface) { |
37
|
1 |
|
$bill = $this->createBill($charge); |
38
|
1 |
|
$bills = $this->aggregateBills($bills, [$bill]); |
39
|
|
|
} else { |
40
|
1 |
|
throw new \Exception('not a Charge given to Aggregator'); |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
|
44
|
1 |
|
return $bills; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Aggregate arrays of bills. |
49
|
|
|
* @param BillInterface[] $bills |
50
|
|
|
* @param BillInterface[] $others |
51
|
|
|
* @return BillInterface[] |
52
|
|
|
*/ |
53
|
1 |
|
public function aggregateBills(array $bills, array $others) |
54
|
|
|
{ |
55
|
1 |
|
foreach ($others as $bill) { |
56
|
1 |
|
$uid = $bill->getUniqueString(); |
57
|
1 |
|
if (empty($bills[$uid])) { |
58
|
1 |
|
$bills[$uid] = $bill; |
59
|
|
|
} else { |
60
|
1 |
|
$bills[$uid] = $this->aggregateBill($bills[$uid], $bill); |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
|
64
|
1 |
|
return $bills; |
65
|
|
|
} |
66
|
|
|
|
67
|
1 |
|
public function aggregateBill(BillInterface $first, BillInterface $other) |
68
|
|
|
{ |
69
|
1 |
|
return new Bill( |
70
|
1 |
|
null, |
71
|
1 |
|
$first->getType(), |
72
|
1 |
|
$first->getTime(), |
73
|
1 |
|
$this->aggregateSum($first->getSum(), $other->getSum()), |
74
|
1 |
|
$this->aggregateQuantity($first->getQuantity(), $other->getQuantity()), |
75
|
1 |
|
$first->getCustomer(), |
76
|
1 |
|
$first->getTarget(), |
77
|
1 |
|
$first->getPlan(), |
78
|
1 |
|
array_merge($first->getCharges(), $other->getCharges()) |
79
|
|
|
); |
80
|
|
|
} |
81
|
|
|
|
82
|
1 |
|
public function aggregateSum(Money $first, Money $other) |
83
|
|
|
{ |
84
|
1 |
|
return $first->add($other); |
85
|
|
|
} |
86
|
|
|
|
87
|
1 |
|
public function aggregateQuantity(QuantityInterface $first, QuantityInterface $other) |
88
|
|
|
{ |
89
|
1 |
|
return $first->add($other); |
90
|
|
|
} |
91
|
|
|
|
92
|
1 |
|
public function createBill(ChargeInterface $charge) |
93
|
|
|
{ |
94
|
1 |
|
return new Bill( |
95
|
1 |
|
null, |
96
|
1 |
|
$this->generalizeType($charge), |
97
|
1 |
|
$this->generalizeTime($charge), |
98
|
1 |
|
$this->generalizeSum($charge), |
99
|
1 |
|
$this->generalizeQuantity($charge), |
100
|
1 |
|
$this->generalizeCustomer($charge), |
101
|
1 |
|
$this->generalizeTarget($charge), |
102
|
1 |
|
$this->generalizePlan($charge), |
103
|
1 |
|
[$charge] |
104
|
|
|
); |
105
|
|
|
} |
106
|
|
|
|
107
|
1 |
|
public function generalizeType(ChargeInterface $charge) |
108
|
|
|
{ |
109
|
1 |
|
return $charge->getPrice()->getType(); |
110
|
|
|
} |
111
|
|
|
|
112
|
1 |
|
public function generalizeTime(ChargeInterface $charge) |
113
|
|
|
{ |
114
|
1 |
|
$date = new DateTimeImmutable($charge->getTime()); |
115
|
|
|
|
116
|
1 |
|
return $date->modify('first day of this month midnight'); |
117
|
|
|
} |
118
|
|
|
|
119
|
1 |
|
public function generalizeSum(ChargeInterface $charge) |
120
|
|
|
{ |
121
|
1 |
|
return $charge->getSum(); |
122
|
|
|
} |
123
|
|
|
|
124
|
1 |
|
public function generalizeQuantity(ChargeInterface $charge) |
125
|
|
|
{ |
126
|
1 |
|
return $charge->getUsage(); |
127
|
|
|
} |
128
|
|
|
|
129
|
1 |
|
public function generalizeCustomer(ChargeInterface $charge) |
130
|
|
|
{ |
131
|
1 |
|
return $charge->getAction()->getCustomer(); |
132
|
|
|
} |
133
|
|
|
|
134
|
1 |
|
public function generalizeTarget(ChargeInterface $charge) |
135
|
|
|
{ |
136
|
1 |
|
$priceTarget = $charge->getPrice()->getTarget(); |
137
|
|
|
|
138
|
1 |
|
return $priceTarget->getId() ? $priceTarget : $charge->getTarget(); |
139
|
|
|
|
140
|
|
|
/// think of this way |
141
|
|
|
/// return $priceTarget->getId() ? $priceTarget : new Target($charge->getSale()->getPlan()->getId(), 'plan'); |
|
|
|
|
142
|
|
|
} |
143
|
|
|
|
144
|
1 |
|
public function generalizePlan(ChargeInterface $charge) |
145
|
|
|
{ |
146
|
1 |
|
return $charge->getPrice()->getPlan(); |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.