Test Failed
Push — master ( 8d6371...123ab3 )
by Alexey
09:12 queued 04:24
created

Cart::itemName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
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) {
0 ignored issues
show
Bug introduced by
The property provider does not seem to exist. Did you mean delivery_provider_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...
358
                    $sum->sums = [$this->delivery->currency_id => $this->delivery->price];
359
                } else {
360
                    $className = 'Ecommerce\DeliveryProvider\\' . $this->delivery->provider->object;
0 ignored issues
show
Bug introduced by
The property provider does not seem to exist. Did you mean delivery_provider_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...
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