DbMergingAggregator::mergeBills()   A
last analyzed

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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 0
cts 6
cp 0
crap 2
rs 10
c 1
b 0
f 0
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-2020, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\tools;
12
13
use hiqdev\php\billing\bill\BillInterface;
14
use hiqdev\php\billing\bill\BillRepositoryInterface;
15
use hiqdev\php\billing\charge\Charge;
16
use hiqdev\php\billing\charge\ChargeInterface;
17
18
/**
19
 * @author Andrii Vasyliev <[email protected]>
20
 */
21
class DbMergingAggregator implements AggregatorInterface, MergerInterface
22
{
23
    protected BillRepositoryInterface $billRepository;
24
    protected MergerInterface $merger;
25
    private AggregatorInterface $localAggregator;
26
27
    public function __construct(
28
        AggregatorInterface $localAggregator,
29
        BillRepositoryInterface $billRepository,
30
        MergerInterface $merger
31
    ) {
32
        $this->billRepository = $billRepository;
33
        $this->merger = $merger;
34
        $this->localAggregator = $localAggregator;
35
    }
36
37
    public function mergeBills(array $bills): array
38
    {
39
        $dbBills = $this->billRepository->findByUniqueness($bills);
40
        $filteredLocalBills = $this->excludeLocalOnlyZeroBills($bills, $dbBills);
41
42
        return $this->merger->mergeBills(array_merge($filteredLocalBills, $dbBills));
43
    }
44
45
    public function mergeBill(BillInterface $first, BillInterface $other): BillInterface
46
    {
47
        return $this->merger->mergeBill($first, $other);
48
    }
49
50
    /**
51
     * Aggregates given Charges to Bills.
52
     * Then merges them with Bills from DB.
53
     *
54
     * @param ChargeInterface[]|ChargeInterface[][] $charges
55
     * @return BillInterface[]
56
     * @throws \Exception
57
     */
58
    public function aggregateCharges(array $charges): array
59
    {
60
        $localBills = $this->localAggregator->aggregateCharges($charges);
61
        $bills = $this->mergeBills($localBills);
62
63
        return $bills;
64
    }
65
66
    /**
67
     * When a new Zero bill is being produced, it should not be persisted
68
     * unless there is already a bill of this uniqueness in the DBMS.
69
     *
70
     * @param BillInterface[] $localBills
71
     * @param BillInterface[] $dbBills
72
     * @return BillInterface[]
73
     */
74
    private function excludeLocalOnlyZeroBills(array $localBills, array $dbBills): array
75
    {
76
        foreach ($localBills as $i => $localBill) {
77
            foreach ($localBill->getCharges() as $charge) {
78
                /** @var Charge $charge */
79
                if ($charge->hasEvents()) {
80
                    continue 2;
81
                }
82
            }
83
            $isZeroSum = $localBill->getSum()->getAmount() === "0";
84
            if (!$isZeroSum) {
85
                continue;
86
            }
87
88
            $localUniqueString = $localBill->getUniqueString();
89
            foreach ($dbBills as $dbBill) {
90
                if ($dbBill->getUniqueString() === $localUniqueString) {
91
                    continue 2;
92
                }
93
            }
94
95
            unset($localBills[$i]);
96
        }
97
98
        return $localBills;
99
    }
100
101
}
102