Completed
Push — master ( a4f70a...5b7a0f )
by Andrii
05:16
created

Aggregator::generalizeTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 5
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 2
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
    public function aggregateCharges(array $charges)
30
    {
31
        $bills = [];
32
        foreach ($charges as $charge) {
33
            if (is_array($charge)) {
34
                $others = $this->aggregateCharges($charge);
35
                $bills = $this->aggregateBills($bills, $others);
36
            } elseif ($charge instanceof ChargeInterface) {
37
                $bill = $this->createBill($charge);
38
                $bills = $this->aggregateBills($bills, [$bill]);
39
            } else {
40
                throw new \Exception('not a Charge given to Aggregator');
41
            }
42
        }
43
44
        return $bills;
45
    }
46
47
    /**
48
     * Aggregate arrays of bills.
49
     * @param BillInterface[] $bills
50
     * @param BillInterface[] $others
51
     * @return BillInterface[]
52
     */
53
    public function aggregateBills(array $bills, array $others)
54
    {
55
        foreach ($others as $bill) {
56
            $uid = $bill->getUniqueString();
57
            if (empty($bills[$uid])) {
58
                $bills[$uid] = $bill;
59
            } else {
60
                $bills[$uid] = $this->aggregateBill($bills[$uid], $bill);
61
            }
62
        }
63
64
        return $bills;
65
    }
66
67
    public function aggregateBill(BillInterface $first, BillInterface $other)
68
    {
69
        return new Bill(
70
            null,
71
            $first->getType(),
72
            $first->getTime(),
73
            $this->aggregateSum($first->getSum(), $other->getSum()),
74
            $this->aggregateQuantity($first->getQuantity(), $other->getQuantity()),
75
            $first->getCustomer(),
76
            $first->getTarget(),
77
            $first->getPlan(),
78
            array_merge($first->getCharges(), $other->getCharges())
79
        );
80
    }
81
82
    public function aggregateSum(Money $first, Money $other)
83
    {
84
        return $first->add($other);
85
    }
86
87
    public function aggregateQuantity(QuantityInterface $first, QuantityInterface $other)
88
    {
89
        return $first->add($other);
90
    }
91
92
    public function createBill(ChargeInterface $charge)
93
    {
94
        return new Bill(
95
            null,
96
            $this->generalizeType($charge),
97
            $this->generalizeTime($charge),
98
            $this->generalizeSum($charge),
99
            $this->generalizeQuantity($charge),
100
            $this->generalizeCustomer($charge),
101
            $this->generalizeTarget($charge),
102
            $this->generalizePlan($charge),
103
            [$charge]
104
        );
105
    }
106
107
    public function generalizeType(ChargeInterface $charge)
108
    {
109
        return $charge->getPrice()->getType();
110
    }
111
112
    public function generalizeTime(ChargeInterface $charge)
113
    {
114
        $date = new DateTimeImmutable($charge->getTime());
115
116
        return $date->modify('first day of this month midnight');
117
    }
118
119
    public function generalizeSum(ChargeInterface $charge)
120
    {
121
        return $charge->getSum();
122
    }
123
124
    public function generalizeQuantity(ChargeInterface $charge)
125
    {
126
        return $charge->getUsage();
127
    }
128
129
    public function generalizeCustomer(ChargeInterface $charge)
130
    {
131
        return $charge->getAction()->getCustomer();
132
    }
133
134
    public function generalizeTarget(ChargeInterface $charge)
135
    {
136
        return $charge->getPrice()->getTarget();
137
    }
138
139
    public function generalizePlan(ChargeInterface $charge)
140
    {
141
        return $charge->getPrice()->getPlan();
142
    }
143
}
144