Completed
Push — master ( 383c20...21c91d )
by Dmitry
13:09
created

PriceChargesEstimator::fetchCalculations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 10
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 0
crap 2
1
<?php
2
3
namespace hipanel\modules\finance\helpers;
4
5
use hipanel\modules\finance\models\Plan;
6
use hipanel\modules\finance\widgets\PriceChargesEstimationTable;
7
use Money\Currencies\ISOCurrencies;
8
use Money\Currency;
9
use Money\Formatter\DecimalMoneyFormatter;
10
use Money\Money;
11
use Yii;
12
13
class PriceChargesEstimator
14
{
15
    /**
16
     * @var \yii\i18n\Formatter
17
     */
18
    protected $yiiFormatter;
19
    /**
20
     * @var DecimalMoneyFormatter
21
     */
22
    protected $moneyFormatter;
23
    /**
24
     * @var array
25
     */
26
    protected $calculations = [];
27
28
    private $actions;
29
    private $prices;
30
    private $periods;
31
32
    public function __construct($actions, $prices)
33
    {
34
        $this->actions = $actions;
35
        $this->prices = $prices;
36
        $this->yiiFormatter = Yii::$app->formatter;
37
        $this->moneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies());
38
    }
39
40
    public function __invoke($periods)
41
    {
42
        $this->calculateForPeriods($periods);
43
    }
44
45
    public function calculateForPeriods($periods): array
46
    {
47
        $this->periods = $periods;
48
        $this->calculations = $this->fetchCalculations();
49
50
        return $this->groupCalculationsByTarget();
51
    }
52
53
    private function fetchCalculations(): array
54
    {
55
        return Plan::perform('calculate-charges', [
56
            'actions' => $this->actions,
57
            'prices' => $this->prices,
58
            'times' => [
59
                'now',
60
                'first day of +1 month',
61
                'first day of +2 month',
62
            ],
63
        ]);
64
    }
65
66
    private function groupCalculationsByTarget()
67
    {
68
        $result = [];
69
        $response = $this->calculations;
70
71
        foreach ($response as $period => $charges) {
72
            $actionsByTarget = [];
73
74
            foreach ($charges as $charge) {
75
                $action = $charge['action'];
76
77
                $targetId = $action['target']['id'];
78
                $actionType = $action['type']['name'];
79
                $priceType = $charge['price']['type']['name'];
80
                $sum = $charge['sum'];
81
82
                $money = new Money($sum['amount'], new Currency($sum['currency']));
83
                $price = $this->moneyFormatter->format($money);
84
85
                $actionsByTarget[$targetId][$actionType]['charges'][] = [
86
                    'type' => $priceType,
87
                    'price' => $price,
88
                    'currency' => $sum['currency'],
89
                    'comment' => $charge['comment'],
90
                    'formattedPrice' => $this->yiiFormatter->asCurrency($price, $sum['currency']),
91
                ];
92
            }
93
94
            foreach ($actionsByTarget as &$actions) {
95
                foreach ($actions as &$action) {
96
                    $this->decorateAction($action);
97
                }
98
            }
99
            unset($action, $actions);
100
101
            $result[$this->yiiFormatter->asDate(strtotime($period), 'php:M Y')] = $actionsByTarget;
102
        }
103
104
        return $result;
105
    }
106
107
    private function decorateAction(&$action)
108
    {
109
        $action['sum'] = array_sum(array_column($action['charges'], 'price'));
110
        $action['sumFormatted'] = $this->yiiFormatter->asCurrency($action['sum'],
111
            reset($action['charges'])['currency']);
112
        $action['detailsTable'] = PriceChargesEstimationTable::widget(['charges' => $action['charges']]);
113
    }
114
}
115