Test Failed
Push — master ( 455e4b...89dfd0 )
by Alexey
07:06 queued 02:50
created

Cart::hasDiscount()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Cart
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2015 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
12
namespace Ecommerce;
13
/**
14
 * Class Cart
15
 *
16
 * @property int $id
17
 * @property int $user_id
18
 * @property int $cart_status_id
19
 * @property int $delivery_id
20
 * @property int $paytype_id
21
 * @property int $card_item_id
22
 * @property bool $warehouse_block
23
 * @property bool $payed
24
 * @property string $comment
25
 * @property bool $exported
26
 * @property string $complete_data
27
 * @property string $date_status
28
 * @property string $date_last_activ
29
 * @property string $date_create
30
 *
31
 * @property \Users\User $user
32
 * @property \Ecommerce\Cart\Item[] $cartItems
33
 * @property \Ecommerce\Cart\Event[] $events
34
 * @property \Ecommerce\Cart\Status $status
35
 * @property \Ecommerce\Delivery $delivery
36
 * @property \Ecommerce\PayType $payType
37
 * @property \Ecommerce\Cart\Info[] $infos
38
 * @property \Ecommerce\Cart\DeliveryInfo[] $deliveryInfos
39
 * @property \Ecommerce\Cart\Extra[] $extras
40
 * @property \Ecommerce\Card\Item $card
41
 * @property \Money\Pay[] $pays
42
 * @property \Ecommerce\Cart\Discount[] $discounts
43
 */
44
class Cart extends \Model {
45
46
    public static $objectName = 'Корзины';
47
48
    public static function indexes() {
49
        return [
50
            'ecommerce_cartStatusBlock' => [
51
                'type' => 'INDEX',
52
                'cols' => [
53
                    'cart_cart_status_id',
54
                    'cart_warehouse_block'
55
                ]
56
            ],
57
            'ecommerce_cartStats' => [
58
                'type' => 'INDEX',
59
                'cols' => [
60
                    'cart_cart_status_id',
61
                ]
62
            ],
63
            'ecommerce_cartBlock' => [
64
                'type' => 'INDEX',
65
                'cols' => [
66
                    'cart_warehouse_block'
67
                ]
68
            ],
69
        ];
70
    }
71
72
    public static function relations() {
73
        return [
74
            'user' => [
75
                'model' => 'Users\User',
76
                'col' => 'user_id'
77
            ],
78
            'cartItems' => [
79
                'type' => 'many',
80
                'model' => 'Ecommerce\Cart\Item',
81
                'col' => 'cart_id',
82
            ],
83
            'events' => [
84
                'type' => 'many',
85
                'model' => 'Ecommerce\Cart\Event',
86
                'col' => 'cart_id',
87
            ],
88
            'status' => [
89
                'model' => 'Ecommerce\Cart\Status',
90
                'col' => 'cart_status_id'
91
            ],
92
            'delivery' => [
93
                'model' => 'Ecommerce\Delivery',
94
                'col' => 'delivery_id'
95
            ],
96
            'payType' => [
97
                'model' => 'Ecommerce\PayType',
98
                'col' => 'paytype_id'
99
            ],
100
            'infos' => [
101
                'type' => 'many',
102
                'model' => 'Ecommerce\Cart\Info',
103
                'col' => 'cart_id'
104
            ],
105
            'deliveryInfos' => [
106
                'type' => 'many',
107
                'model' => 'Ecommerce\Cart\DeliveryInfo',
108
                'col' => 'cart_id'
109
            ],
110
            'extras' => [
111
                'type' => 'many',
112
                'model' => 'Ecommerce\Cart\Extra',
113
                'col' => 'cart_id'
114
            ],
115
            'card' => [
116
                'model' => 'Ecommerce\Card\Item',
117
                'col' => 'card_item_id'
118
            ],
119
            'pays' => [
120
                'type' => 'many',
121
                'model' => 'Money\Pay',
122
                'col' => 'data'
123
            ],
124
            'discounts' => [
125
                'type' => 'relModel',
126
                'relModel' => 'Ecommerce\Cart\Discount',
127
                'model' => 'Ecommerce\Discount',
128
            ]
129
        ];
130
    }
131
132
    public function beforeDelete() {
133
        foreach ($this->cartItems as $cartItem) {
134
            $cartItem->delete();
135
        }
136
        foreach ($this->infos as $info) {
137
            $info->delete();
138
        }
139
        foreach ($this->extras as $extra) {
140
            $extra->delete();
141
        }
142
        foreach ($this->events as $event) {
143
            $event->delete();
144
        }
145
    }
146
147
    public static $labels = [
148
        'user_id' => 'Пользователь',
149
        'cart_status_id' => 'Статус',
150
        'delivery_id' => 'Доставка',
151
        'comment' => 'Комментарий',
152
        'bonus_used' => 'Выгодные рубли',
153
        'complete_data' => 'Время заказа',
154
        'info' => 'Информация',
155
        'items' => 'Товары',
156
        'paytype_id' => 'Способ оплаты',
157
        'payed' => 'Оплачен',
158
        'exported' => 'Выгружено',
159
        'warehouse_block' => 'Блокировка товаров',
160
        'extra' => 'Доп.',
161
        'card_item_id' => 'Дисконтная карта',
162
        'info' => 'Информация',
163
        'contacts' => 'Информация',
164
        'pay' => 'Счета',
165
        'sums' => 'Суммы',
166
        'deliveryInfo' => 'Для доставки',
167
        'discount' => 'Скидки',
168
    ];
169
    public static $cols = [
170
        //Основные параметры
171
        'user_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'user'],
172
        'cart_status_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'status'],
173
        'delivery_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'delivery'],
174
        'paytype_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'payType'],
175
        'card_item_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'card'],
176
        'warehouse_block' => ['type' => 'bool'],
177
        'payed' => ['type' => 'bool'],
178
        'comment' => ['type' => 'textarea'],
179
        //Системные
180
        'exported' => ['type' => 'bool'],
181
        'complete_data' => ['type' => 'dateTime', 'null' => true, 'emptyValue' => null],
182
        'date_status' => ['type' => 'dateTime', 'null' => true, 'emptyValue' => null],
183
        'date_last_activ' => ['type' => 'dateTime', 'null' => true, 'emptyValue' => null],
184
        'date_create' => ['type' => 'dateTime'],
185
        //Виджеты
186
        'sums' => [
187
            'type' => 'void',
188
            'view' => [
189
                'type' => 'widget',
190
                'widget' => 'Ecommerce\adminSums',
191
            ],
192
        ],
193
        'contacts' => [
194
            'type' => 'void',
195
            'view' => [
196
                'type' => 'widget',
197
                'widget' => 'Ecommerce\admin/contacts',
198
            ],
199
        ],
200
        //Менеджеры
201
        'extra' => ['type' => 'dataManager', 'relation' => 'extras'],
202
        'pay' => ['type' => 'dataManager', 'relation' => 'pays'],
203
        'items' => ['type' => 'dataManager', 'relation' => 'cartItems'],
204
        'info' => ['type' => 'dataManager', 'relation' => 'infos'],
205
        'deliveryInfo' => ['type' => 'dataManager', 'relation' => 'deliveryInfos'],
206
        'discount' => ['type' => 'dataManager', 'relation' => 'discounts'],
207
    ];
208
    public static $dataManagers = [
209
        'manager' => [
210
            'cols' => [
211
                'contacts',
212
                'items',
213
                'extra',
214
                'discount',
215
                'sums',
216
                'cart_status_id',
217
                'delivery_id',
218
                'deliveryInfo',
219
                'payed',
220
                'pay',
221
                'complete_data',
222
            ],
223
            'sortable' => [
224
                'cart_status_id',
225
                'delivery_id',
226
                'payed',
227
                'complete_data',
228
            ],
229
            'filters' => [
230
                'cart_status_id',
231
                'delivery_id',
232
                'payed',
233
                'complete_data',
234
            ],
235
            'preSort' => [
236
                'complete_data' => 'desc'
237
            ],
238
            'actions' => [
239
                'Ecommerce\CloseCartBtn', 'Open', 'Edit', 'Delete'
240
            ]
241
        ]
242
    ];
243
244
    public static function itemName($item) {
245
        return $item->pk() . '. ' . $item->name();
246
    }
247
248
    public static $forms = [
249
        'manager' => [
250
            'inputs' => [
251
                'userSearch' => [
252
                    'type' => 'search',
253
                    'source' => 'relation',
254
                    'relation' => 'user',
255
                    'label' => 'Покупатель',
256
                    'cols' => [
257
                        'info:first_name',
258
                        'info:last_name',
259
                        'info:middle_name',
260
                        'mail'
261
                    ],
262
                    'col' => 'user_id',
263
                    'required' => true,
264
                    'showCol' => [
265
                        'type' => 'staticMethod',
266
                        'class' => 'Ecommerce\Cart',
267
                        'method' => 'itemName',
268
                    ],
269
                ],
270
                'cardSearch' => [
271
                    'type' => 'search',
272
                    'source' => 'relation',
273
                    'relation' => 'card',
274
                    'label' => 'Дисконтная карта',
275
                    'cols' => [
276
                        'code',
277
                        'user:info:first_name',
278
                        'user:info:last_name',
279
                        'user:info:middle_name',
280
                        'user:mail'
281
                    ],
282
                    'col' => 'card_item_id',
283
                ],
284
            ],
285
            'map' => [
286
                ['userSearch', 'cart_status_id'],
287
                ['paytype_id', 'delivery_id'],
288
                ['cardSearch', 'comment'],
289
                ['warehouse_block', 'complete_data'],
290
                ['payed'],
291
                ['items'],
292
                ['extra'],
293
                ['pay'],
294
                ['info'],
295
                ['deliveryInfo']
296
            ]
297
        ],
298
    ];
299
300
    public function checkStage() {
301
        $sum = $this->itemsSum();
302
        $stages = Cart\Stage::getList(['order' => ['sum', 'asc']]);
303
        $groups = [];
304
        foreach ($stages as $stage) {
305
            if ($sum->greater(new \Money\Sums([$stage->currency_id => $stage->sum])) || $sum->equal(new \Money\Sums([$stage->currency_id => $stage->sum]))) {
306
                $groups[$stage->group] = $stage;
307
            }
308
        }
309
        $discounts = Cart\Discount::getList(['where' => ['cart_id', $this->id]]);
310
        foreach ($discounts as $discount) {
311
            if (!isset($groups[$discount->group]) && $discount->auto) {
312
                $discount->delete();
313
            }
314
            if (isset($groups[$discount->group]) && $groups[$discount->group]->type == 'discount') {
315
                $discount->discount_id = $groups[$discount->group]->value;
316
                $discount->save();
317
                unset($groups[$discount->group]);
318
            }
319
        }
320
        foreach ($groups as $group) {
321
            if ($group && $group->type == 'discount') {
322
                $rel = $this->addRelation('discounts', $group->value);
323
                $rel->auto = true;
324
                $rel->group = 'discount';
325
                $rel->save();
326
            }
327
        }
328
    }
329
330
    public function needDelivery() {
331
        foreach ($this->cartItems as $cartItem) {
332
            if ((!$cartItem->item->type && !empty(\App::$cur->ecommerce->config['defaultNeedDelivery'])) || ($cartItem->item->type && $cartItem->item->type->delivery)) {
333
                return true;
334
            }
335
        }
336
        return false;
337
    }
338
339
    public function deliverySum() {
340
        $sum = new \Money\Sums([]);
341
        if ($this->delivery && $this->needDelivery()) {
342
            $sums = $this->itemsSum();
343
            $deliveryPrice = new \Money\Sums([$this->delivery->currency_id => $this->delivery->max_cart_price]);
344
            if ($this->delivery->max_cart_price && $sums->greater($deliveryPrice) || $sums->equal($deliveryPrice)) {
345
                $sum->sums = [$this->delivery->currency_id => 0];
346
            } else if ($this->delivery->prices) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->delivery->prices of type Ecommerce\Delivery\Price[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
347
                foreach ($this->delivery->prices(['order' => ['cart_price', 'asc']]) as $delPrice) {
348
                    $deliveryPrice = new \Money\Sums([$delPrice->currency_id => $delPrice->cart_price]);
349
                    if ($sums->greater($deliveryPrice) || $sums->equal($deliveryPrice)) {
350
                        $sum->sums = [$delPrice->currency_id => $delPrice->price];
351
                    }
352
                }
353
                if (!$sum->sums) {
354
                    $sum->sums = [$this->delivery->currency_id => $this->delivery->price];
355
                }
356
            } else {
357
                if (!$this->delivery->provider) {
358
                    $sum->sums = [$this->delivery->currency_id => $this->delivery->price];
359
                } else {
360
                    $className = 'Ecommerce\DeliveryProvider\\' . $this->delivery->provider->object;
361
                    $sum = $className::calcPrice($this);
362
                }
363
            }
364
        }
365
        return $sum;
366
    }
367
368
    public function hasDiscount() {
369
        return (bool)$this->card || $this->discounts;
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->discounts of type Ecommerce\Cart\Discount[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
370
    }
371
372
    public function discountSum() {
373
        $sums = [];
374
        foreach ($this->cartItems as $cartItem) {
375
            $sums[$cartItem->price->currency_id] = isset($sums[$cartItem->price->currency_id]) ? $sums[$cartItem->price->currency_id] + $cartItem->discount() * $cartItem->count : $cartItem->discount() * $cartItem->count;
376
        }
377
        return new \Money\Sums($sums);
378
    }
379
380
    public function finalSum() {
381
        $sums = $this->itemsSum();
382
        $sums = $sums->minus($this->discountSum());
383
        $sums = $sums->plus($this->deliverySum());
384
        return $sums;
385
    }
386
387
    public function itemsSum() {
388
        $cart = Cart::get($this->id);
389
        $sums = [];
390
        foreach ($cart->cartItems as $cartItem) {
391
            if (!$cartItem->price) {
392
                continue;
393
            }
394
            $sums[$cartItem->price->currency_id] = isset($sums[$cartItem->price->currency_id]) ? $sums[$cartItem->price->currency_id] + $cartItem->price->price * $cartItem->count : $cartItem->price->price * $cartItem->count;
395
        }
396
        return new \Money\Sums($sums);
397
    }
398
399
    public function addItem($offer_price_id, $count = 1, $final_price = 0) {
400
        $price = Item\Offer\Price::get((int)$offer_price_id);
401
402
        if (!$price) {
403
            return false;
404
        }
405
406
        if ($count <= 0) {
407
            $count = 1;
408
        }
409
410
        $cartItem = new Cart\Item();
411
        $cartItem->cart_id = $this->id;
412
        $cartItem->item_id = $price->offer->item->id;
413
        $cartItem->count = $count;
414
        $cartItem->item_offer_price_id = $price->id;
415
        $cartItem->final_price = $final_price ? $final_price : $price->price;
416
        $cartItem->save();
417
        return true;
418
    }
419
420
    public function calc($save = true) {
421
        if ($save) {
422
            $this->save();
423
        }
424
    }
425
426
}
427