PriceChargesEstimator::groupCalculationsByTarget()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 44
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 6
eloc 26
nc 5
nop 0
dl 0
loc 44
rs 8.8817
c 1
b 0
f 1
1
<?php
2
3
/**
4
 * PHP Billing Library
5
 *
6
 * @link      https://github.com/hiqdev/php-billing
7
 * @package   php-billing
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2017-2020, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\php\billing\helpers;
13
14
use Money\Currencies\ISOCurrencies;
15
use Money\Currency;
16
use Money\Formatter\DecimalMoneyFormatter;
17
use Money\Money;
18
19
/**
20
 * Class PriceChargesEstimator.
21
 *
22
 * @author Dmytro Naumenko <[email protected]>
23
 */
24
25
class PriceChargesEstimator
26
{
27
    /**
28
     * @var array
29
     */
30
    protected $calculations = [];
31
32
    /**
33
     * @var string[] array of strings compatible with `strtotime()`, e.g. `first day of next month`
34
     */
35
    private $periods = [];
36
37
    public function __construct(array $calculations)
38
    {
39
        $this->calculations = $calculations;
40
    }
41
42
    public function __invoke($periods)
43
    {
44
        $this->calculateForPeriods($periods);
45
    }
46
47
    /**
48
     * @var string[] array of strings compatible with `strtotime()`, e.g. `first day of next month`
49
     * @return array
50
     */
51
    public function calculateForPeriods($periods): array
52
    {
53
        $this->periods = $periods;
54
55
        return $this->groupCalculationsByTarget();
56
    }
57
58
    private function groupCalculationsByTarget()
59
    {
60
        $result = [];
61
62
        foreach ($this->calculations as $period => $charges) {
63
            $chargesByTargetAndAction = [];
64
65
            foreach ($charges as $charge) {
66
                $action = $charge['action'];
67
68
                $targetId = $action['target']['id'];
69
                $actionType = $action['type']['name'];
70
                $priceType = $charge['price']['type']['name'];
71
                $sum = $charge['sum'];
72
73
                $chargesByTargetAndAction['targets'][$targetId][$actionType]['charges'][] = [
74
                    'sum' => $sum['amount'],
75
                    'type' => $priceType,
76
                    'currency' => $sum['currency'],
77
                    'comment' => $charge['comment'] ?? null,
78
                ];
79
80
                $chargesByTargetAndAction['targets'][$targetId][$actionType]['quantity'] = max(
81
                    $charge['action']['quantity']['quantity'],
82
                    $chargesByTargetAndAction['targets'][$targetId][$actionType]['quantity'] ?? 0
83
                );
84
85
                $chargesByTargetAndAction['currency'] = $sum['currency'];
86
            }
87
            unset($action);
88
89
            if (!empty($chargesByTargetAndAction['targets'])) {
90
                foreach ($chargesByTargetAndAction['targets'] as &$actions) {
91
                    foreach ($actions as &$action) {
92
                        $this->decorateAction($action);
93
                    }
94
                }
95
            }
96
            unset($action, $actions);
97
98
            $result[date("Y-m-d", strtotime($period))] = $chargesByTargetAndAction;
99
        }
100
101
        return $result;
102
    }
103
104
    private function decorateAction(&$action)
105
    {
106
        $action['currency'] = reset($action['charges'])['currency'];
107
    }
108
}
109