Billing::getCalculator()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
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\order;
12
13
use DateTimeImmutable;
14
use hiqdev\php\billing\bill\BillInterface;
15
use hiqdev\php\billing\bill\BillRepositoryInterface;
16
use hiqdev\php\billing\tools\AggregatorInterface;
17
use hiqdev\php\billing\tools\DbMergingAggregator;
18
use hiqdev\php\billing\tools\MergerInterface;
19
20
/**
21
 * Billing calculates and saves bills for given order.
22
 *
23
 * @author Andrii Vasyliev <[email protected]>
24
 */
25
class Billing implements BillingInterface
26
{
27
    /**
28
     * @var CalculatorInterface
29
     */
30
    protected $calculator;
31
    /**
32
     * @var AggregatorInterface
33
     */
34
    protected $aggregator;
35
    /**
36
     * @var AggregatorInterface
37
     */
38
    protected $repoAggregator;
39
    /**
40
     * @var MergerInterface
41
     */
42
    protected $merger;
43
    /**
44
     * @var BillRepositoryInterface
45
     */
46
    protected $repository;
47
    /**
48
     * @var CollectorInterface
49
     */
50
    protected $collector;
51
52
    public function __construct(
53
        CalculatorInterface $calculator,
54
        AggregatorInterface $aggregator,
55
        MergerInterface $merger,
56
        ?BillRepositoryInterface $repository,
57
        ?CollectorInterface $collector
58
    ) {
59
        $this->calculator = $calculator;
60
        $this->aggregator = $aggregator;
61
        $this->merger = $merger;
62
        $this->repository = $repository;
63
        $this->collector = $collector ?? new Collector();
64
    }
65
66
    public function calculate($source, DateTimeImmutable $time = null): array
67
    {
68
        $charges = $this->calculateCharges($source, $time);
69
        $bills = $this->aggregator->aggregateCharges($charges);
70
71
        return $this->merger->mergeBills($bills);
72
    }
73
74
    public function perform($source, DateTimeImmutable $time = null): array
75
    {
76
        $charges = $this->calculateCharges($source, $time);
77
        $bills = $this->getRepoAggregator()->aggregateCharges($charges);
78
79
        return $this->saveBills($bills);
80
    }
81
82
    public function calculateCharges($source, DateTimeImmutable $time = null): array
83
    {
84
        $order = $this->collector->collect($source, $time);
85
86
        return $this->calculator->calculateOrder($order);
87
    }
88
89
    private function getRepoAggregator(): AggregatorInterface
90
    {
91
        if ($this->repoAggregator === null) {
92
            $this->repoAggregator = new DbMergingAggregator($this->aggregator, $this->repository, $this->merger);
93
        }
94
95
        return $this->repoAggregator;
96
    }
97
98
    /**
99
     * @param BillInterface[] $bills
100
     * @return BillInterface[]
101
     */
102
    private function saveBills(array $bills): array
103
    {
104
        $res = [];
105
        foreach ($bills as $key => $bill) {
106
            $res[$key] = $this->repository->save($bill);
107
        }
108
109
        return $res;
110
    }
111
112
    /**
113
     * @return CalculatorInterface
114
     */
115
    public function getCalculator(): CalculatorInterface
116
    {
117
        return $this->calculator;
118
    }
119
}
120