GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Setup Failed
Push — filters ( 98448a...15591c )
by
unknown
10:46
created

PriceHandlers   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 264
Duplicated Lines 15.15 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 34
c 1
b 1
f 0
lcom 1
cbo 9
dl 40
loc 264
rs 9.2

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getFinalDeliveryPrice() 0 11 3
A getCurrencyPriceProduct() 0 8 1
B getDiscountPriceProduct() 0 29 6
A getDiscountPriceOrder() 22 22 2
A getDeliveryPriceOrder() 18 18 2
B getDiscountsByAppliance() 0 24 6
C handleSaveDiscounts() 0 61 10
B handleSaveDelivery() 0 33 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace app\modules\shop\helpers;
3
4
use app\modules\shop\events\OrderCalculateEvent;
5
use app\modules\shop\models\AbstractDiscountType;
6
use app\modules\shop\models\Currency;
7
use app\modules\shop\models\Discount;
8
use app\modules\shop\models\Order;
9
use app\modules\shop\models\Product;
10
use app\modules\shop\models\SpecialPriceList;
11
use app\modules\shop\models\SpecialPriceObject;
12
use Yii;
13
14
class PriceHandlers
15
{
16
    /**
17
     * @var array|null
18
     */
19
    static protected $discountsByAppliance = null;
20
21
    /**
22
     * @param Order $order
23
     * @return float
24
     */
25
    static public function getFinalDeliveryPrice(Order $order)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
26
    {
27
        $finalCost = $order->shippingOption->cost;
28
        foreach ($order->specialPriceObjects as $spo) {
29
            if ($spo->isDiscount()) {
30
                $finalCost += $spo->price;
31
            }
32
        }
33
34
        return $finalCost;
35
    }
36
37
    /**
38
     * @param Product $product
39
     * @param Order|null $order
40
     * @param SpecialPriceList $specialPrice
41
     * @param $price
42
     * @return float
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
43
     */
44
    static public function getCurrencyPriceProduct(
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
45
        Product $product,
46
        Order $order = null,
47
        SpecialPriceList $specialPrice,
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
48
        $price
49
    ) {
50
        return CurrencyHelper::convertToMainCurrency($price, $product->currency);
0 ignored issues
show
Bug introduced by
The property currency does not seem to exist. Did you mean currency_id?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
51
    }
52
53
54
    /***
55
     * @param Product $product
56
     * @param null|Order $order
57
     * @param SpecialPriceList $specialPrice
58
     * @param $price
59
     * @return mixed
60
     */
61
    static public function getDiscountPriceProduct(
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
62
        Product $product,
63
        Order $order = null,
64
        SpecialPriceList $specialPrice,
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
65
        $price
66
    ) {
67
        static $discounts = null;
68
        if (null === $discounts) {
69
            $discounts = self::getDiscountsByAppliance(['products']);
70
        }
71
72
        foreach ($discounts as $discount) {
0 ignored issues
show
Bug introduced by
The expression $discounts of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
73
            /** @var Discount $discount */
74
            $discountFlag = 0;
75
            foreach (Discount::getTypeObjects() as $discountTypeObject) {
76
                /** @var AbstractDiscountType $discountTypeObject */
77
                if (true === $discountTypeObject->checkDiscount($discount, $product, $order)) {
78
                    $discountFlag++;
79
                }
80
            }
81
82
            if ($discountFlag > 0) {
83
                $oldPrice = $price;
84
                $price = $discount->getDiscountPrice($oldPrice);
85
            }
86
        }
87
88
        return $price;
89
    }
90
91
    /**
92
     * @param Order $order
93
     * @param SpecialPriceList $specialPrice
94
     * @param $price
95
     * @return float
0 ignored issues
show
Documentation introduced by
Should the return type not be integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
96
     */
97 View Code Duplication
    static public function getDiscountPriceOrder(
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
98
        Order $order,
99
        SpecialPriceList $specialPrice,
100
        $price
101
    ) {
102
103
        $discountPrice = 0;
104
105
        $discountObjects = SpecialPriceObject::findAll(
106
            [
107
                'special_price_list_id' => $specialPrice->id,
108
                'object_model_id' => $order->id
109
            ]
110
        );
111
112
        foreach ($discountObjects as $object) {
113
            $discountPrice += $object->price;
114
        }
115
116
117
        return $price + $discountPrice;
118
    }
119
120
    /**
121
     * @param Order $order
122
     * @param SpecialPriceList $specialPrice
123
     * @param $price
124
     * @return float
0 ignored issues
show
Documentation introduced by
Should the return type not be integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
125
     */
126 View Code Duplication
    static public function getDeliveryPriceOrder(
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
127
        Order $order,
128
        SpecialPriceList $specialPrice,
129
        $price
130
    ) {
131
        $deliveryPrice = 0;
132
133
        $deliveryObjects = SpecialPriceObject::findAll([
134
            'special_price_list_id' => $specialPrice->id,
135
            'object_model_id' => $order->id
136
        ]);
137
138
        foreach ($deliveryObjects as $object) {
139
            $deliveryPrice += $object->price;
140
        }
141
142
        return $price + $deliveryPrice;
143
    }
144
145
    /**
146
     * @param array $types
147
     * @return array
148
     */
149
    static protected function getDiscountsByAppliance($types = [])
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
150
    {
151
        if (true === empty($types)) {
152
            return [];
153
        }
154
155
        if (null === static::$discountsByAppliance) {
156
            static::$discountsByAppliance = [];
157
            foreach (Discount::find()->all() as $model) {
158
                /** @var Discount $model */
159
                static::$discountsByAppliance[$model->appliance][$model->id] = $model;
160
            }
161
        }
162
163
        $result = [];
164
165
        foreach ($types as $type) {
166
            if (true === isset(static::$discountsByAppliance[$type])) {
167
                $result = array_merge($result, static::$discountsByAppliance[$type]);
168
            }
169
        }
170
171
        return $result;
172
    }
173
174
    /**
175
     * @param OrderCalculateEvent $event
176
     * @return null
177
     */
178
    static public function handleSaveDiscounts(OrderCalculateEvent $event)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
179
    {
180
        if (OrderCalculateEvent::BEFORE_CALCULATE !== $event->state) {
181
            return null;
182
        }
183
184
        static $discounts = null;
185
        if (null === $discounts) {
186
            $discounts = self::getDiscountsByAppliance(['order_without_delivery', 'order_with_delivery', 'delivery']);
187
        }
188
189
        foreach ($discounts as $discount) {
0 ignored issues
show
Bug introduced by
The expression $discounts of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
190
            /** @var Discount $discount */
191
            $discountFlag = 0;
192
            foreach (Discount::getTypeObjects() as $discountTypeObject) {
193
                /** @var AbstractDiscountType $discountTypeObject */
194
                if (true === $discountTypeObject->checkDiscount($discount, null, $event->order)) {
195
                    $discountFlag++;
196
                }
197
            }
198
199
            $special_price_list_id = SpecialPriceList::find()
200
            ->where([
201
                'handler' => 'getDiscountPriceOrder',
202
                'object_id' => $event->order->object->id
0 ignored issues
show
Bug introduced by
The property object does not seem to exist. Did you mean specialPriceObjects?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
203
            ])
204
            ->one()
205
            ->id;
206
207
            if ($discountFlag > 0
208
                && $event->price > 0
209
                && (
210
                    $discount->apply_order_price_lg !== -1
211
                    && $event->order->total_price > $discount->apply_order_price_lg
212
                )
213
            ) {
214
                $oldPrice = $event->price;
215
                $deliveryPrice = SpecialPriceObject::getSumPrice(
216
                    $event->order->id,
217
                    SpecialPriceList::TYPE_DELIVERY
218
                );
219
                $price = $discount->getDiscountPrice($oldPrice, $deliveryPrice);
220
                $discountPrice = $price - $oldPrice;
221
222
                SpecialPriceObject::setObject(
223
                    $special_price_list_id,
224
                    $event->order->id,
225
                    $discountPrice,
226
                    $discount->name
227
                );
228
229
            }
230
            /** Данный кусок удаляет все объекты, если одна из скидок не применилась! */
231
            /* else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
232
                SpecialPriceObject::deleteAll([
233
                    'special_price_list_id' => $special_price_list_id,
234
                    'object_model_id' => $event->order->id
235
                ]);
236
            } */
237
        }
238
    }
239
240
    /**
241
     * @param OrderCalculateEvent $event
242
     * @return null
243
     */
244
    static public function handleSaveDelivery(OrderCalculateEvent $event)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
245
    {
246
        if (OrderCalculateEvent::BEFORE_CALCULATE !== $event->state) {
247
            return null;
248
        }
249
250
        $deliveryInformation = $event->order->orderDeliveryInformation;
251
        $shippingOption = $event->order->shippingOption;
252
        $special_price_list = SpecialPriceList::find()->where(
253
            [
254
                'handler' => 'getDeliveryPriceOrder',
255
                'object_id' => $event->order->object->id
0 ignored issues
show
Bug introduced by
The property object does not seem to exist. Did you mean specialPriceObjects?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
256
            ]
257
        )->one();
258
259
        if (null !== $deliveryInformation && null !== $shippingOption) {
260
            SpecialPriceObject::setObject(
261
                $special_price_list->id,
262
                $event->order->id,
263
                $shippingOption->cost,
264
                $shippingOption->name
265
            );
266
        }
267
        /** Сомнительно! */
268
        /* else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
269
            SpecialPriceObject::deleteAll(
270
                [
271
                    'special_price_list_id' => $special_price_list->id,
272
                    'object_model_id' => $event->order->id
273
                ]
274
            );
275
        } */
276
    }
277
}
278