Completed
Push — master ( 6cd982...18aa30 )
by Alexey
05:03
created

Cart::indexes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 0
dl 0
loc 23
rs 9.0856
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'],
152
      'date_status' => ['type' => 'dateTime'],
153
      'date_last_activ' => ['type' => 'dateTime'],
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