Test Failed
Push — master ( 61f61c...455e4b )
by Alexey
04:03
created

Cart::itemsSum()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 0
dl 0
loc 11
rs 9.2
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 extends \Model {
15
16
    public static $objectName = 'Корзины';
17
18
    public static function indexes() {
19
        return [
20
            'ecommerce_cartStatusBlock' => [
21
                'type' => 'INDEX',
22
                'cols' => [
23
                    'cart_cart_status_id',
24
                    'cart_warehouse_block'
25
                ]
26
            ],
27
            'ecommerce_cartStats' => [
28
                'type' => 'INDEX',
29
                'cols' => [
30
                    'cart_cart_status_id',
31
                ]
32
            ],
33
            'ecommerce_cartBlock' => [
34
                'type' => 'INDEX',
35
                'cols' => [
36
                    'cart_warehouse_block'
37
                ]
38
            ],
39
        ];
40
    }
41
42
    public static function relations() {
43
        return [
44
            'user' => [
45
                'model' => 'Users\User',
46
                'col' => 'user_id'
47
            ],
48
            'cartItems' => [
49
                'type' => 'many',
50
                'model' => 'Ecommerce\Cart\Item',
51
                'col' => 'cart_id',
52
            ],
53
            'events' => [
54
                'type' => 'many',
55
                'model' => 'Ecommerce\Cart\Event',
56
                'col' => 'cart_id',
57
            ],
58
            'status' => [
59
                'model' => 'Ecommerce\Cart\Status',
60
                'col' => 'cart_status_id'
61
            ],
62
            'delivery' => [
63
                'model' => 'Ecommerce\Delivery',
64
                'col' => 'delivery_id'
65
            ],
66
            'payType' => [
67
                'model' => 'Ecommerce\PayType',
68
                'col' => 'paytype_id'
69
            ],
70
            'infos' => [
71
                'type' => 'many',
72
                'model' => 'Ecommerce\Cart\Info',
73
                'col' => 'cart_id'
74
            ],
75
            'deliveryInfos' => [
76
                'type' => 'many',
77
                'model' => 'Ecommerce\Cart\DeliveryInfo',
78
                'col' => 'cart_id'
79
            ],
80
            'extras' => [
81
                'type' => 'many',
82
                'model' => 'Ecommerce\Cart\Extra',
83
                'col' => 'cart_id'
84
            ],
85
            'card' => [
86
                'model' => 'Ecommerce\Card\Item',
87
                'col' => 'card_item_id'
88
            ],
89
            'pays' => [
90
                'type' => 'many',
91
                'model' => 'Money\Pay',
92
                'col' => 'data'
93
            ],
94
            'discounts' => [
95
                'type' => 'relModel',
96
                'relModel' => 'Ecommerce\Cart\Discount',
97
                'model' => 'Ecommerce\Discount',
98
            ]
99
        ];
100
    }
101
102
    public function beforeDelete() {
103
        foreach ($this->cartItems as $cartItem) {
104
            $cartItem->delete();
105
        }
106
        foreach ($this->infos as $info) {
107
            $info->delete();
108
        }
109
        foreach ($this->extras as $extra) {
110
            $extra->delete();
111
        }
112
        foreach ($this->events as $event) {
113
            $event->delete();
114
        }
115
    }
116
117
    public static $labels = [
118
        'user_id' => 'Пользователь',
119
        'cart_status_id' => 'Статус',
120
        'delivery_id' => 'Доставка',
121
        'comment' => 'Комментарий',
122
        'bonus_used' => 'Выгодные рубли',
123
        'complete_data' => 'Время заказа',
124
        'info' => 'Информация',
125
        'items' => 'Товары',
126
        'paytype_id' => 'Способ оплаты',
127
        'payed' => 'Оплачен',
128
        'exported' => 'Выгружено',
129
        'warehouse_block' => 'Блокировка товаров',
130
        'extra' => 'Доп.',
131
        'card_item_id' => 'Дисконтная карта',
132
        'info' => 'Информация',
133
        'contacts' => 'Информация',
134
        'pay' => 'Счета',
135
        'sums' => 'Суммы',
136
        'deliveryInfo' => 'Для доставки',
137
        'discount' => 'Скидки',
138
    ];
139
    public static $cols = [
140
        //Основные параметры
141
        'user_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'user'],
142
        'cart_status_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'status'],
143
        'delivery_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'delivery'],
144
        'paytype_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'payType'],
145
        'card_item_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'card'],
146
        'warehouse_block' => ['type' => 'bool'],
147
        'payed' => ['type' => 'bool'],
148
        'comment' => ['type' => 'textarea'],
149
        //Системные
150
        'exported' => ['type' => 'bool'],
151
        'complete_data' => ['type' => 'dateTime', 'null' => true, 'emptyValue' => null],
152
        'date_status' => ['type' => 'dateTime', 'null' => true, 'emptyValue' => null],
153
        'date_last_activ' => ['type' => 'dateTime', 'null' => true, 'emptyValue' => null],
154
        'date_create' => ['type' => 'dateTime'],
155
        //Виджеты
156
        'sums' => [
157
            'type' => 'void',
158
            'view' => [
159
                'type' => 'widget',
160
                'widget' => 'Ecommerce\adminSums',
161
            ],
162
        ],
163
        'contacts' => [
164
            'type' => 'void',
165
            'view' => [
166
                'type' => 'widget',
167
                'widget' => 'Ecommerce\admin/contacts',
168
            ],
169
        ],
170
        //Менеджеры
171
        'extra' => ['type' => 'dataManager', 'relation' => 'extras'],
172
        'pay' => ['type' => 'dataManager', 'relation' => 'pays'],
173
        'items' => ['type' => 'dataManager', 'relation' => 'cartItems'],
174
        'info' => ['type' => 'dataManager', 'relation' => 'infos'],
175
        'deliveryInfo' => ['type' => 'dataManager', 'relation' => 'deliveryInfos'],
176
        'discount' => ['type' => 'dataManager', 'relation' => 'discounts'],
177
    ];
178
    public static $dataManagers = [
179
        'manager' => [
180
            'cols' => [
181
                'contacts',
182
                'items',
183
                'extra',
184
                'discount',
185
                'sums',
186
                'cart_status_id',
187
                'delivery_id',
188
                'deliveryInfo',
189
                'payed',
190
                'pay',
191
                'complete_data',
192
            ],
193
            'sortable' => [
194
                'cart_status_id',
195
                'delivery_id',
196
                'payed',
197
                'complete_data',
198
            ],
199
            'filters' => [
200
                'cart_status_id',
201
                'delivery_id',
202
                'payed',
203
                'complete_data',
204
            ],
205
            'preSort' => [
206
                'complete_data' => 'desc'
207
            ],
208
            'actions' => [
209
                'Ecommerce\CloseCartBtn', 'Open', 'Edit', 'Delete'
210
            ]
211
        ]
212
    ];
213
214
    public static function itemName($item) {
215
        return $item->pk() . '. ' . $item->name();
216
    }
217
218
    public static $forms = [
219
        'manager' => [
220
            'inputs' => [
221
                'userSearch' => [
222
                    'type' => 'search',
223
                    'source' => 'relation',
224
                    'relation' => 'user',
225
                    'label' => 'Покупатель',
226
                    'cols' => [
227
                        'info:first_name',
228
                        'info:last_name',
229
                        'info:middle_name',
230
                        'mail'
231
                    ],
232
                    'col' => 'user_id',
233
                    'required' => true,
234
                    'showCol' => [
235
                        'type' => 'staticMethod',
236
                        'class' => 'Ecommerce\Cart',
237
                        'method' => 'itemName',
238
                    ],
239
                ],
240
                'cardSearch' => [
241
                    'type' => 'search',
242
                    'source' => 'relation',
243
                    'relation' => 'card',
244
                    'label' => 'Дисконтная карта',
245
                    'cols' => [
246
                        'code',
247
                        'user:info:first_name',
248
                        'user:info:last_name',
249
                        'user:info:middle_name',
250
                        'user:mail'
251
                    ],
252
                    'col' => 'card_item_id',
253
                ],
254
            ],
255
            'map' => [
256
                ['userSearch', 'cart_status_id'],
257
                ['paytype_id', 'delivery_id'],
258
                ['cardSearch', 'comment'],
259
                ['warehouse_block', 'complete_data'],
260
                ['payed'],
261
                ['items'],
262
                ['extra'],
263
                ['pay'],
264
                ['info'],
265
                ['deliveryInfo']
266
            ]
267
        ],
268
    ];
269
270
    public function checkStage() {
271
        $sum = $this->itemsSum();
272
        $stages = Cart\Stage::getList(['order' => ['sum', 'asc']]);
273
        $groups = [];
274
        foreach ($stages as $stage) {
275
            if ($sum->greater(new \Money\Sums([$stage->currency_id => $stage->sum])) || $sum->equal(new \Money\Sums([$stage->currency_id => $stage->sum]))) {
276
                $groups[$stage->group] = $stage;
277
            }
278
        }
279
        $discounts = Cart\Discount::getList(['where' => ['cart_id', $this->id]]);
280
        foreach ($discounts as $discount) {
281
            if (!isset($groups[$discount->group]) && $discount->auto) {
282
                $discount->delete();
283
            }
284
            if (isset($groups[$discount->group]) && $groups[$discount->group]->type == 'discount') {
285
                $discount->discount_id = $groups[$discount->group]->value;
286
                $discount->save();
287
                unset($groups[$discount->group]);
288
            }
289
        }
290
        foreach ($groups as $group) {
291
            if ($group && $group->type == 'discount') {
292
                $rel = $this->addRelation('discounts', $group->value);
293
                $rel->auto = true;
294
                $rel->group = 'discount';
295
                $rel->save();
296
            }
297
        }
298
    }
299
300
    public function needDelivery() {
301
        foreach ($this->cartItems as $cartItem) {
302
            if ($cartItem->item->type && $cartItem->item->type->delivery) {
303
                return true;
304
            }
305
        }
306
        return false;
307
    }
308
309
    public function deliverySum() {
310
        $sum = new \Money\Sums([]);
311
        if ($this->delivery && $this->needDelivery()) {
312
            $sums = $this->itemsSum();
313
            $deliveryPrice = new \Money\Sums([$this->delivery->currency_id => $this->delivery->max_cart_price]);
314
            if ($this->delivery->max_cart_price && $sums->greater($deliveryPrice) || $sums->equal($deliveryPrice)) {
315
                $sum->sums = [$this->delivery->currency_id => 0];
316
            } else if ($this->delivery->prices) {
317
                foreach ($this->delivery->prices(['order' => ['cart_price', 'asc']]) as $delPrice) {
318
                    $deliveryPrice = new \Money\Sums([$delPrice->currency_id => $delPrice->cart_price]);
319
                    if ($sums->greater($deliveryPrice) || $sums->equal($deliveryPrice)) {
320
                        $sum->sums = [$delPrice->currency_id => $delPrice->price];
321
                    }
322
                }
323
                if (!$sum->sums) {
324
                    $sum->sums = [$this->delivery->currency_id => $this->delivery->price];
325
                }
326
            } else {
327
                $sum->sums = [$this->delivery->currency_id => $this->delivery->price];
328
            }
329
        }
330
        return $sum;
331
    }
332
333
    public function hasDiscount() {
334
        return (bool) $this->card || $this->discounts;
335
    }
336
337
    public function discountSum() {
338
        $sums = [];
339
        foreach ($this->cartItems as $cartItem) {
340
            $sums[$cartItem->price->currency_id] = isset($sums[$cartItem->price->currency_id]) ? $sums[$cartItem->price->currency_id] + $cartItem->discount() * $cartItem->count : $cartItem->discount() * $cartItem->count;
341
        }
342
        return new \Money\Sums($sums);
343
    }
344
345
    public function finalSum() {
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
        $cart = Cart::get($this->id);
354
        $sums = [];
355
        foreach ($cart->cartItems as $cartItem) {
356
            if (!$cartItem->price) {
357
                continue;
358
            }
359
            $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;
360
        }
361
        return new \Money\Sums($sums);
362
    }
363
364
    public function addItem($offer_price_id, $count = 1, $final_price = 0) {
365
        $price = Item\Offer\Price::get((int) $offer_price_id);
366
367
        if (!$price) {
368
            return false;
369
        }
370
371
        if ($count <= 0) {
372
            $count = 1;
373
        }
374
375
        $cartItem = new Cart\Item();
376
        $cartItem->cart_id = $this->id;
377
        $cartItem->item_id = $price->offer->item->id;
378
        $cartItem->count = $count;
379
        $cartItem->item_offer_price_id = $price->id;
380
        $cartItem->final_price = $final_price ? $final_price : $price->price;
381
        $cartItem->save();
382
        return true;
383
    }
384
385
    public function calc($save = true) {
386
        if ($save) {
387
            $this->save();
388
        }
389
    }
390
391
}
392