Completed
Push — master ( f79ff7...908aca )
by Dmitry
15:25 queued 10:35
created

src/tools/Merger.php (1 issue)

Labels
Severity
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\units\QuantityInterface;
17
use Money\Money;
18
19
/**
20
 * @author Andrii Vasyliev <[email protected]>
21
 */
22
class Merger implements MergerInterface
23
{
24
    /**
25
     * {@inheritdoc}
26
     */
27
    public function mergeBills(array $bills): array
28
    {
29
        $res = [];
30
        foreach ($bills as $bill) {
31
            $uid = $bill->getUniqueString();
32
            if (empty($res[$uid])) {
33
                $res[$uid] = $bill;
34
            } else {
35
                $res[$uid] = $this->mergeBill($res[$uid], $bill);
36
            }
37
        }
38
39
        return $res;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function mergeBill(BillInterface $first, BillInterface $other): BillInterface
46
    {
47
        $charges = $this->mergeCharges(array_merge($first->getCharges(), $other->getCharges()));
48
49
        return new Bill(
50
            $this->mergeId($first, $other),
51
            $first->getType(),
52
            $first->getTime(),
53
            $this->mergeSum($first, $other, $charges),
54
            $this->mergeQuantity($first, $other, $charges),
55
            $first->getCustomer(),
56
            $first->getTarget(),
57
            $first->getPlan(),
58
            $charges
59
        );
60
    }
61
62
    /**
63
     * Merge
64
     * @param ChargeInterface[] $charges
65
     * @return ChargeInterface[]
66
     */
67
    protected function mergeCharges(array $charges): array
68
    {
69
        $res = [];
70
        foreach ($charges as $charge) {
71
            $uid = $charge->getUniqueString();
72
            if (empty($res[$uid])) {
73
                $res[$uid] = $charge;
74
            } else {
75
                $res[$uid] = $this->mergeCharge($res[$uid], $charge);
76
            }
77
        }
78
79
        //var_dump(array_keys($res));die;
80
        return $res;
81
    }
82
83
    /**
84
     * Merges two charges.
85
     * Simple implementation just returns latest charge.
86
     * @param ChargeInterface $first
87
     * @param ChargeInterface $other
88
     * @return ChargeInterface
89
     */
90
    protected function mergeCharge(ChargeInterface $first, ChargeInterface $other): ChargeInterface
91
    {
92
        if (!$first->hasId()) {
93
            $first->setId($other->getId());
94
        }
95
96
        return $first;
97
    }
98
99
    /**
100
     * @param BillInterface $first
101
     * @param BillInterface $other
102
     * @return string|int|null
103
     */
104
    protected function mergeId(BillInterface $first, BillInterface $other)
105
    {
106
        if ($first->getId() === null) {
107
            return $other->getId();
108
        }
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 merge bills with different IDs');
0 ignored issues
show
The type hiqdev\php\billing\tools\AggregationException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
117
    }
118
119
    /**
120
     * @param BillInterface $first
121
     * @param BillInterface $other
122
     * @param ChargeInterface[] $charges
123
     * @return Money
124
     */
125
    protected function mergeSum(BillInterface $first, BillInterface $other, array $charges): Money
126
    {
127
        $sum = array_shift($charges)->getSum();
128
        foreach ($charges as $charge) {
129
            $sum = $sum->add($charge->getSum());
130
        }
131
132
        return $sum->negative();
133
    }
134
135
    /**
136
     * @param BillInterface $first
137
     * @param BillInterface $other
138
     * @param ChargeInterface[] $charges
139
     * @return QuantityInterface
140
     */
141
    protected function mergeQuantity(BillInterface $first, BillInterface $other, array $charges): QuantityInterface
142
    {
143
        $usage = array_shift($charges)->getUsage();
144
        foreach ($charges as $charge) {
145
            $usage = $usage->add($charge->getUsage());
146
        }
147
148
        return $usage;
149
    }
150
}
151