Completed
Push — master ( 56fb42...c01525 )
by Alexey
04:50
created

Cart::deliverySum()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 14
rs 8.8571
cc 5
eloc 10
nc 3
nop 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 extends \Model
15
{
16
    public static $objectName = 'Корзины';
17
18
    public static function indexes()
19
    {
20
        return [
21
            'ecommerce_cartStatusBlock' => [
22
                'type' => 'INDEX',
23
                'cols' => [
24
                    'cart_cart_status_id',
25
                    'cart_warehouse_block'
26
                ]
27
            ],
28
            'ecommerce_cartStats' => [
29
                'type' => 'INDEX',
30
                'cols' => [
31
                    'cart_cart_status_id',
32
                ]
33
            ],
34
            'ecommerce_cartBlock' => [
35
                'type' => 'INDEX',
36
                'cols' => [
37
                    'cart_warehouse_block'
38
                ]
39
            ],
40
        ];
41
    }
42
43
    public static function relations()
44
    {
45
        return [
46
            'user' => [
47
                'model' => 'Users\User',
48
                'col' => 'user_id'
49
            ],
50
            'cartItems' => [
51
                'type' => 'many',
52
                'model' => 'Ecommerce\Cart\Item',
53
                'col' => 'cart_id',
54
            ],
55
            'events' => [
56
                'type' => 'many',
57
                'model' => 'Ecommerce\Cart\Event',
58
                'col' => 'cart_id',
59
            ],
60
            'status' => [
61
                'model' => 'Ecommerce\Cart\Status',
62
                'col' => 'cart_status_id'
63
            ],
64
            'delivery' => [
65
                'model' => 'Ecommerce\Delivery',
66
                'col' => 'delivery_id'
67
            ],
68
            'payType' => [
69
                'model' => 'Ecommerce\PayType',
70
                'col' => 'paytype_id'
71
            ],
72
            'infos' => [
73
                'type' => 'many',
74
                'model' => 'Ecommerce\Cart\Info',
75
                'col' => 'cart_id'
76
            ],
77
            'deliveryInfos' => [
78
                'type' => 'many',
79
                'model' => 'Ecommerce\Cart\DeliveryInfo',
80
                'col' => 'cart_id'
81
            ],
82
            'extras' => [
83
                'type' => 'many',
84
                'model' => 'Ecommerce\Cart\Extra',
85
                'col' => 'cart_id'
86
            ],
87
            'card' => [
88
                'model' => 'Ecommerce\Card\Item',
89
                'col' => 'card_item_id'
90
            ],
91
            'pays' => [
92
                'type' => 'many',
93
                'model' => 'Money\Pay',
94
                'col' => 'data'
95
            ],
96
            'discounts' => [
97
                'type' => 'relModel',
98
                'relModel' => 'Ecommerce\Cart\Discount',
99
                'model' => 'Ecommerce\Discount',
100
            ]
101
        ];
102
    }
103
104
    public function beforeDelete()
105
    {
106
        foreach ($this->cartItems as $cartItem) {
107
            $cartItem->delete();
108
        }
109
        foreach ($this->infos as $info) {
110
            $info->delete();
111
        }
112
        foreach ($this->extras as $extra) {
113
            $extra->delete();
114
        }
115
        foreach ($this->events as $event) {
116
            $event->delete();
117
        }
118
    }
119
120
    public static $labels = [
121
        'user_id' => 'Пользователь',
122
        'cart_status_id' => 'Статус',
123
        'delivery_id' => 'Доставка',
124
        'comment' => 'Комментарий',
125
        'bonus_used' => 'Выгодные рубли',
126
        'complete_data' => 'Время заказа',
127
        'info' => 'Информация',
128
        'items' => 'Товары',
129
        'paytype_id' => 'Способ оплаты',
130
        'payed' => 'Оплачен',
131
        'exported' => 'Выгружено',
132
        'warehouse_block' => 'Блокировка товаров',
133
        'extra' => 'Доп.',
134
        'card_item_id' => 'Дисконтная карта',
135
        'info' => 'Информация',
136
        'contacts' => 'Информация',
137
        'pay' => 'Счета',
138
        'sums' => 'Суммы',
139
        'deliveryInfo' => 'Для доставки',
140
        'discount' => 'Скидки',
141
    ];
142
    public static $cols = [
143
        //Основные параметры
144
        'user_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'user'],
145
        'cart_status_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'status'],
146
        'delivery_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'delivery'],
147
        'paytype_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'payType'],
148
        'card_item_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'card'],
149
        'warehouse_block' => ['type' => 'bool'],
150
        'payed' => ['type' => 'bool'],
151
        'comment' => ['type' => 'textarea'],
152
        //Системные
153
        'exported' => ['type' => 'bool'],
154
        'complete_data' => ['type' => 'dateTime'],
155
        'date_status' => ['type' => 'dateTime'],
156
        'date_last_activ' => ['type' => 'dateTime'],
157
        'date_create' => ['type' => 'dateTime'],
158
        //Виджеты
159
        'sums' => [
160
            'type' => 'void',
161
            'view' => [
162
                'type' => 'widget',
163
                'widget' => 'Ecommerce\adminSums',
164
            ],
165
        ],
166
        'contacts' => [
167
            'type' => 'void',
168
            'view' => [
169
                'type' => 'widget',
170
                'widget' => 'Ecommerce\admin/contacts',
171
            ],
172
        ],
173
        //Менеджеры
174
        'extra' => ['type' => 'dataManager', 'relation' => 'extras'],
175
        'pay' => ['type' => 'dataManager', 'relation' => 'pays'],
176
        'items' => ['type' => 'dataManager', 'relation' => 'cartItems'],
177
        'info' => ['type' => 'dataManager', 'relation' => 'infos'],
178
        'deliveryInfo' => ['type' => 'dataManager', 'relation' => 'deliveryInfos'],
179
        'discount' => ['type' => 'dataManager', 'relation' => 'discounts'],
180
    ];
181
    public static $dataManagers = [
182
        'manager' => [
183
            'cols' => [
184
                'contacts',
185
                'items',
186
                'extra',
187
                'discount',
188
                'sums',
189
                'cart_status_id',
190
                'delivery_id',
191
                'deliveryInfo',
192
                'payed',
193
                'pay',
194
                'complete_data',
195
            ],
196
            'sortable' => [
197
                'cart_status_id',
198
                'delivery_id',
199
                'payed',
200
                'complete_data',
201
            ],
202
            'filters' => [
203
                'cart_status_id',
204
                'delivery_id',
205
                'payed',
206
                'complete_data',
207
            ],
208
            'preSort' => [
209
                'complete_data' => 'desc'
210
            ],
211
            'actions' => [
212
                'Ecommerce\CloseCartBtn', 'Open', 'Edit', 'Delete'
213
            ]
214
        ]
215
    ];
216
217
    public static function itemName($item)
218
    {
219
        return $item->pk() . '. ' . $item->name();
220
    }
221
222
    public static $forms = [
223
        'manager' => [
224
            'inputs' => [
225
                'userSearch' => [
226
                    'type' => 'search',
227
                    'source' => 'relation',
228
                    'relation' => 'user',
229
                    'label' => 'Покупатель',
230
                    'cols' => [
231
                        'info:first_name',
232
                        'info:last_name',
233
                        'info:middle_name',
234
                        'mail'
235
                    ],
236
                    'col' => 'user_id',
237
                    'required' => true,
238
                    'showCol' => [
239
                        'type' => 'staticMethod',
240
                        'class' => 'Ecommerce\Cart',
241
                        'method' => 'itemName',
242
                    ],
243
                ],
244
                'cardSearch' => [
245
                    'type' => 'search',
246
                    'source' => 'relation',
247
                    'relation' => 'card',
248
                    'label' => 'Дисконтная карта',
249
                    'cols' => [
250
                        'code',
251
                        'user:info:first_name',
252
                        'user:info:last_name',
253
                        'user:info:middle_name',
254
                        'user:mail'
255
                    ],
256
                    'col' => 'card_item_id',
257
                ],
258
            ],
259
            'map' => [
260
                ['userSearch', 'cart_status_id'],
261
                ['paytype_id', 'delivery_id'],
262
                ['cardSearch', 'comment'],
263
                ['warehouse_block', 'complete_data'],
264
                ['payed'],
265
                ['items'],
266
                ['extra'],
267
                ['pay'],
268
                ['info'],
269
                ['deliveryInfo']
270
            ]
271
        ],
272
    ];
273
274
    public function checkStage()
275
    {
276
        $sum = $this->itemsSum();
277
        $stages = Cart\Stage::getList(['order' => ['sum', 'asc']]);
278
        $groups = [];
279
        foreach ($stages as $stage) {
280
            if ($sum->greater(new \Money\Sums([$stage->currency_id => $stage->sum])) || $sum->equal(new \Money\Sums([$stage->currency_id => $stage->sum]))) {
281
                $groups[$stage->group] = $stage;
282
            }
283
        }
284
        $discounts = Cart\Discount::getList(['where'=>['cart_id',$this->id]]);
285
        foreach ($discounts as $discount) {
286
            if (!isset($groups[$discount->group]) && $discount->auto) {
287
                $discount->delete();
288
            }
289
            if (isset($groups[$discount->group]) && $groups[$discount->group]->type == 'discount') {
290
                $discount->discount_id = $groups[$discount->group]->value;
291
                $discount->save();
292
                unset($groups[$discount->group]);
293
            }
294
        }
295
        foreach ($groups as $group) {
296
            if ($group && $group->type == 'discount') {
297
                $rel = $this->addRelation('discounts', $group->value);
298
                $rel->auto = true;
299
                $rel->group = 'discount';
300
                $rel->save();
0 ignored issues
show
Bug introduced by
The method save cannot be called on $rel (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
301
            }
302
        }
303
    }
304
305
    public function needDelivery()
306
    {
307
        foreach ($this->cartItems as $cartItem) {
308
            if ($cartItem->item->type && $cartItem->item->type->delivery) {
309
                return true;
310
            }
311
        }
312
        return false;
313
    }
314
315
    public function deliverySum()
316
    {
317
        $sum = new \Money\Sums([]);
318
        if ($this->delivery && $this->needDelivery()) {
319
            $sums = new \Money\Sums($this->itemsSum());
320
            $deliveryPrice = new \Money\Sums([$this->delivery->currency_id => $this->delivery->max_cart_price]);
321
            if ($sums->greater($deliveryPrice) || $sums->equal($deliveryPrice)) {
322
                $sum->sums = [$this->delivery->currency_id => 0];
323
            } else {
324
                $sum->sums = [$this->delivery->currency_id => $this->delivery->price];
325
            }
326
        }
327
        return $sum;
328
    }
329
330
    public function hasDiscount()
331
    {
332
        return (bool) $this->card || $this->discounts;
333
    }
334
335
    public function discountSum()
336
    {
337
        $sums = [];
338
        foreach ($this->cartItems as $cartItem) {
339
            $sums[$cartItem->price->currency_id] = isset($sums[$cartItem->price->currency_id]) ? $sums[$cartItem->price->currency_id] + $cartItem->discount() : $cartItem->discount();
340
        }
341
        return new \Money\Sums($sums);
342
    }
343
344
    public function finalSum()
345
    {
346
        $sums = $this->itemsSum();
347
        $sums = $sums->minus($this->discountSum());
348
        $sums = $sums->plus($this->deliverySum());
349
        return $sums;
350
    }
351
352
    public function itemsSum()
353
    {
354
        $cart = Cart::get($this->id);
355
        $sums = [];
356
        foreach ($cart->cartItems as $cartItem) {
357
            if (!$cartItem->price) {
358
                continue;
359
            }
360
            $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;
361
        }
362
        return new \Money\Sums($sums);
363
    }
364
365
    public function addItem($offer_price_id, $count = 1, $final_price = 0)
366
    {
367
        $price = Item\Offer\Price::get((int) $offer_price_id);
368
369
        if (!$price) {
370
            return false;
371
        }
372
373
        if ($count <= 0) {
374
            $count = 1;
375
        }
376
377
        $cartItem = new Cart\Item();
378
        $cartItem->cart_id = $this->id;
379
        $cartItem->item_id = $price->offer->item->id;
380
        $cartItem->count = $count;
381
        $cartItem->item_offer_price_id = $price->id;
382
        $cartItem->final_price = $final_price ? $final_price : $price->price;
383
        $cartItem->save();
384
        return true;
385
    }
386
387
    public function calc($save = true)
388
    {
389
        if ($save) {
390
            $this->save();
391
        }
392
    }
393
394
}
395