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\tools; |
||
12 | |||
13 | use hiqdev\php\billing\bill\Bill; |
||
14 | use hiqdev\php\billing\bill\BillInterface; |
||
15 | use hiqdev\php\billing\charge\ChargeInterface; |
||
16 | use hiqdev\php\billing\charge\GeneralizerInterface; |
||
17 | use hiqdev\php\units\QuantityInterface; |
||
18 | use Money\Money; |
||
19 | |||
20 | /** |
||
21 | * @author Andrii Vasyliev <[email protected]> |
||
22 | */ |
||
23 | class Aggregator implements AggregatorInterface |
||
24 | { |
||
25 | /** |
||
26 | * @var GeneralizerInterface |
||
27 | */ |
||
28 | protected $generalizer; |
||
29 | |||
30 | 1 | public function __construct(GeneralizerInterface $generalizer) |
|
31 | { |
||
32 | 1 | $this->generalizer = $generalizer; |
|
33 | 1 | } |
|
34 | |||
35 | /** |
||
36 | * Aggregates given Charges to Bills. Then aggregates them again with DB. |
||
37 | * @param ChargeInterface[]|ChargeInterface[][] $charges |
||
38 | * @return BillInterface[] |
||
39 | */ |
||
40 | 1 | public function aggregateCharges(array $charges): array |
|
41 | { |
||
42 | 1 | $bills = []; |
|
43 | 1 | foreach ($charges as $charge) { |
|
44 | 1 | if (is_array($charge)) { |
|
45 | 1 | $others = $this->aggregateCharges($charge); |
|
46 | 1 | } elseif ($charge instanceof ChargeInterface) { |
|
47 | 1 | $others = [$this->generalizer->createBill($charge)]; |
|
48 | } else { |
||
49 | var_dump($charge);die; |
||
0 ignored issues
–
show
Security
Debugging Code
introduced
by
Loading history...
In this branch, the function will implicitly return
null which is incompatible with the type-hinted return array . Consider adding a return statement or allowing null as return value.
For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example: interface ReturnsInt {
public function returnsIntHinted(): int;
}
class MyClass implements ReturnsInt {
public function returnsIntHinted(): int
{
if (foo()) {
return 123;
}
// here: null is implicitly returned
}
}
Loading history...
|
|||
50 | throw new \Exception('not a Charge given to Aggregator'); |
||
0 ignored issues
–
show
ThrowNode is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last
Loading history...
|
|||
51 | } |
||
52 | |||
53 | $bills = $this->aggregateBills($bills, $others); |
||
54 | 1 | } |
|
55 | |||
56 | return $bills; |
||
57 | 1 | } |
|
58 | |||
59 | /** |
||
60 | * Aggregate arrays of bills. |
||
61 | * @param BillInterface[] $bills |
||
62 | * @param BillInterface[] $others |
||
63 | * @return BillInterface[] |
||
64 | */ |
||
65 | protected function aggregateBills(array $bills, array $others): array |
||
66 | 1 | { |
|
67 | foreach ($others as $bill) { |
||
68 | 1 | $uid = $bill->getUniqueString(); |
|
69 | 1 | if (empty($bills[$uid])) { |
|
70 | 1 | $bills[$uid] = $bill; |
|
71 | 1 | } else { |
|
72 | $bills[$uid] = $this->aggregateBill($bills[$uid], $bill); |
||
73 | 1 | } |
|
74 | } |
||
75 | |||
76 | return $bills; |
||
77 | 1 | } |
|
78 | |||
79 | /** |
||
80 | * @param BillInterface $first |
||
81 | * @param BillInterface $other |
||
82 | * @return BillInterface |
||
83 | */ |
||
84 | protected function aggregateBill(BillInterface $first, BillInterface $other): BillInterface |
||
85 | 1 | { |
|
86 | return new Bill( |
||
87 | 1 | $this->aggregateId($first, $other), |
|
88 | 1 | $first->getType(), |
|
89 | 1 | $first->getTime(), |
|
90 | 1 | $this->aggregateSum($first, $other), |
|
91 | 1 | $this->aggregateQuantity($first, $other), |
|
92 | 1 | $first->getCustomer(), |
|
93 | 1 | $first->getTarget(), |
|
94 | 1 | $first->getPlan(), |
|
95 | 1 | array_merge($first->getCharges(), $other->getCharges()) |
|
96 | 1 | ); |
|
97 | } |
||
98 | |||
99 | /** |
||
100 | * @param BillInterface $first |
||
101 | * @param BillInterface $other |
||
102 | * @return string|int|null |
||
103 | */ |
||
104 | protected function aggregateId(BillInterface $first, BillInterface $other) |
||
105 | 1 | { |
|
106 | if ($first->getId() === null) { |
||
107 | 1 | return $other->getId(); |
|
108 | 1 | } |
|
109 | if ($other->getId() === null) { |
||
110 | return $first->getId(); |
||
111 | } |
||
112 | if ($first->getId() === $other->getId()) { |
||
113 | return $other->getId(); |
||
114 | } |
||
115 | |||
116 | throw new AggregationException('cannot aggregate bills with different IDs'); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * @param BillInterface $first |
||
121 | * @param BillInterface $other |
||
122 | * @param ChargeInterface[] $charges |
||
123 | * @return Money |
||
124 | */ |
||
125 | protected function aggregateSum(BillInterface $first, BillInterface $other): Money |
||
126 | 1 | { |
|
127 | return $first->getSum()->add($other->getSum()); |
||
128 | 1 | } |
|
129 | |||
130 | /** |
||
131 | * @param BillInterface $first |
||
132 | * @param BillInterface $other |
||
133 | * @param ChargeInterface[] $charges |
||
134 | * @return QuantityInterface |
||
135 | */ |
||
136 | protected function aggregateQuantity(BillInterface $first, BillInterface $other): QuantityInterface |
||
137 | 1 | { |
|
138 | return $first->getQuantity()->add($other->getQuantity()); |
||
139 | 1 | } |
|
140 | } |
||
141 |