Completed
Push — master ( 00bad6...c7c8a3 )
by Dmitry
06:29
created

PlanInternalsGrouper::groupDomainPrices()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 10
cp 0
rs 9.7
c 0
b 0
f 0
cc 4
nc 4
nop 0
crap 20
1
<?php
2
3
namespace hipanel\modules\finance\helpers;
4
5
use hipanel\modules\finance\models\CertificatePrice;
6
use hipanel\modules\finance\models\DomainServicePrice;
7
use hipanel\modules\finance\models\DomainZonePrice;
8
use hipanel\modules\finance\models\FakeSale;
9
use hipanel\modules\finance\models\Plan;
10
use hipanel\modules\finance\models\Price;
11
use hipanel\modules\finance\models\Sale;
12
use Tuck\Sort\Sort;
13
use Yii;
14
15
/**
16
 * Class PlanInternalsGrouper can be used to group prices inside $plan depending on
17
 * different factors.
18
 *
19
 * @author Dmytro Naumenko <[email protected]>
20
 */
21
class PlanInternalsGrouper
22
{
23
    /**
24
     * @var Plan
25
     */
26
    private $plan;
27
28
    public function __construct(Plan $plan)
29
    {
30
        $this->plan = $plan;
31
    }
32
33
    /**
34
     * Should be used to group prices of [[Plan]] with the following types:
35
     * - server
36
     * - sVDS
37
     * - oVDS
38
     * - certificate
39
     * @return array
40
     */
41
    public function group()
42
    {
43
        switch ($this->plan->type) {
44
            case Plan::TYPE_CERTIFICATE:
45
                return $this->groupCertificatePrices();
46
            case Plan::TYPE_DOMAIN:
47
                return $this->groupDomainPrices();
48
            default:
49
                return $this->groupServerPrices();
50
        }
51
    }
52
53
    /**
54
     * @return array of two elements:
55
     * 0: sales, grouped by sold object
56
     * 1: prices, grouped by sold object
57
     */
58
    private function groupServerPrices()
59
    {
60
        $model = $this->plan;
61
        /** @var Sale[] $salesByObject */
62
        $salesByObject = [];
63
        /** @var Price[][] $pricesByMainObject */
64
        $pricesByMainObject = [];
65
66
        foreach ($model->prices as $price) {
67
            $pricesByMainObject[$price->main_object_id ?? $model->id][$price->id] = $price;
68
        }
69
70
        if (isset($pricesByMainObject[null])) {
71
            $salesByObject[null] = new FakeSale([
72
                'object' => Yii::t('hipanel.finance.price', 'Applicable for all objects'),
73
                'tariff_id' => $model->id,
74
            ]);
75
        }
76
        if (isset($pricesByMainObject[$model->id])) {
77
            $salesByObject[$model->id] = new FakeSale([
78
                'object' => Yii::t('hipanel.finance.price', 'For the whole tariff'),
79
                'tariff_id' => $model->id,
80
                'object_id' => $model->id,
81
            ]);
82
        }
83
        foreach ($model->sales as $sale) {
84
            $salesByObject[$sale->object_id] = $sale;
85
        }
86
87
        foreach ($pricesByMainObject as $id => $prices) {
88
            if (isset($salesByObject[$id])) {
89
                continue;
90
            }
91
92
            foreach ($prices as $price) {
93
                if ((int)$price->object_id === (int)$id) {
94
                    $salesByObject[$id] = new FakeSale([
95
                        'object' => $price->object->name,
96
                        'tariff_id' => $model->id,
97
                        'object_id' => $price->object_id,
98
                        'tariff_type' => $model->type,
99
                    ]);
100
                    continue 2;
101
                }
102
            }
103
104
            $salesByObject[$id] = new FakeSale([
105
                'object' => Yii::t('hipanel.finance.price', 'Unknown object name - no direct object prices exist'),
106
                'tariff_id' => $model->id,
107
                'object_id' => $id,
108
                'tariff_type' => $model->type,
109
            ]);
110
        }
111
112
        foreach ($pricesByMainObject as &$objPrices) {
113
            $objPrices = PriceSort::anyPrices()->values($objPrices, true);
114
        }
115
116
        return [$salesByObject, $pricesByMainObject];
117
    }
118
119
    /**
120
     * @return array of certificate prices
121
     * every element of array consist of two elements:
122
     * certificate,certificate_purchase: CertificatePrice
123
     * certificate,certificate_renewal: CertificatePrice
124
     */
125
    private function groupCertificatePrices(): array
126
    {
127
        $result = [];
128
129
        foreach ($this->plan->prices as $price) {
130
            /** @var CertificatePrice $price */
131
            $result[$price->object_id][$price->type] = $price;
132
        }
133
134
        return $result;
135
    }
136
137
    /**
138
     * @return array[] of domain prices
139
     */
140
    private function groupDomainPrices(): array
141
    {
142
        $zonePrices = [];
143
        $servicePrices = [];
144
145
        foreach ($this->plan->prices as $price) {
146
            if ($price instanceof DomainZonePrice) {
147
                /** @var DomainZonePrice $price */
148
                $zonePrices[$price->object_id][$price->type] = $price;
149
            } elseif ($price instanceof DomainServicePrice) {
150
                /** @var DomainServicePrice $price */
151
                $servicePrices[$price->type] = $price;
152
            }
153
        }
154
155
        return [$zonePrices, $servicePrices];
156
    }
157
}
158