QuoteItem.php 21.3 KB
Newer Older
_
__FresHmaN 已提交
1 2 3 4 5 6 7 8 9 10 11
<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */

namespace fecshop\services\cart;

12
//use fecshop\models\mysqldb\cart\Item as MyCartItem;
_
__FresHmaN 已提交
13 14 15 16
use fecshop\services\Service;
use Yii;

/**
T
Terry 已提交
17
 * Cart services. 对购物车产品操作的具体实现部分。
_
__FresHmaN 已提交
18 19 20 21 22
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class QuoteItem extends Service
{
23 24 25 26
    public $itemDefaultActiveStatus = 1;
    public $activeStatus = 1;
    public $noActiveStatus = 2;
    
_
__FresHmaN 已提交
27 28
    protected $_my_cart_item;    // 购物车cart item 对象
    protected $_cart_product_info;
29 30 31 32
    
    protected $_itemModelName = '\fecshop\models\mysqldb\cart\Item';
    protected $_itemModel;
    
T
Terry 已提交
33 34
    public function init(){
        parent::init();
35 36 37
        list($this->_itemModelName,$this->_itemModel) = Yii::mapGet($this->_itemModelName);  
    }
    
_
__FresHmaN 已提交
38 39 40 41 42 43
    /**
     * @property $item | Array, example:
     * $item = [
     *		'product_id' 		=> 22222,
     *		'custom_option_sku' => red-xxl,
     *		'qty' 				=> 22,
44
     *      'sku' 				=> 'xxxx',
_
__FresHmaN 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
     * ];
     * 将某个产品加入到购物车中。在添加到cart_item表后,更新
     * 购物车中产品的总数。
     */
    public function addItem($item)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        if (!$cart_id) {
            Yii::$service->cart->quote->createCart();
            $cart_id = Yii::$service->cart->quote->getCartId();
        }
        // 查看是否存在此产品,如果存在,则相加个数
        if (!isset($item['product_id']) || empty($item['product_id'])) {
            Yii::$service->helper->errors->add('add to cart error,product id is empty');

            return false;
        }
        $where = [
            'cart_id'    => $cart_id,
T
Terry 已提交
64
            'product_id' => $item['product_id'],
_
__FresHmaN 已提交
65 66 67 68
        ];
        if (isset($item['custom_option_sku']) && !empty($item['custom_option_sku'])) {
            $where['custom_option_sku'] = $item['custom_option_sku'];
        }
T
Terry 已提交
69
        $item_one = $this->_itemModel->find()->where($where)->one();
_
__FresHmaN 已提交
70
        if ($item_one['cart_id']) {
71
            $item_one->active       = $this->itemDefaultActiveStatus;
_
__FresHmaN 已提交
72 73 74 75 76
            $item_one->qty = $item['qty'] + $item_one['qty'];
            $item_one->save();
            // 重新计算购物车的数量
            Yii::$service->cart->quote->computeCartInfo();
        } else {
77
            $item_one = new $this->_itemModelName;
T
Terry 已提交
78 79 80 81 82 83
            $item_one->store        = Yii::$service->store->currentStore;
            $item_one->cart_id      = $cart_id;
            $item_one->created_at   = time();
            $item_one->updated_at   = time();
            $item_one->product_id   = $item['product_id'];
            $item_one->qty          = $item['qty'];
84
            $item_one->active       = $this->itemDefaultActiveStatus;
_
__FresHmaN 已提交
85 86
            $item_one->custom_option_sku = ($item['custom_option_sku'] ? $item['custom_option_sku'] : '');
            $item_one->save();
T
Terry 已提交
87
            // 重新计算购物车的数量,并写入sales_flat_cart表存储
_
__FresHmaN 已提交
88 89
            Yii::$service->cart->quote->computeCartInfo();
        }
T
Terry 已提交
90 91 92
        
        $item['afterAddQty'] = $item_one->qty;
        $this->sendTraceAddToCartInfoByApi($item);
93 94 95 96 97 98 99
        
    }
    /**
     * @property $item | Array, example:
     * $item = [
     *		'product_id' 		=> 22222,
     *		'custom_option_sku' => red-xxl,
T
Terry 已提交
100
     *		'qty' 				=> 22,    // 添加购物车的产品个数
101
     *      'sku' 				=> 'xxxx',
T
Terry 已提交
102
     *      'afterAddQty'       => 33,  // 添加后,该产品在sku中的个数,这个个数是为了计算购物车中产品的价格
103 104 105 106 107
     * ];
     * 将加入购物车的操作,加入trace 
     */
    public function sendTraceAddToCartInfoByApi($item){
        if (Yii::$service->page->trace->traceJsEnable) {
T
Terry 已提交
108
            $product_price_arr  = Yii::$service->product->price->getCartPriceByProductId($item['product_id'], $item['afterAddQty'], $item['custom_option_sku'], 2);
109
            $base_product_price = isset($product_price_arr['base_price']) ? $product_price_arr['base_price'] : 0;
T
Terry 已提交
110
            // $price = $base_product_price * $item['qty'];
111 112 113
            $trace_cart_info = [
                [
                    'sku'   => $item['sku'],
T
Terry 已提交
114
                    'price' => $base_product_price,
115 116 117 118 119
                    'qty'   => $item['qty'],
                ]
            ];
            Yii::$service->page->trace->sendTraceAddToCartInfoByApi($trace_cart_info);
        }
_
__FresHmaN 已提交
120 121 122 123 124 125 126 127 128 129 130 131
    }

    /**
     * @property $item | Array, example:
     * $item = [
     *		'product_id' 		=> 22222,
     *		'custom_option_sku' => red-xxl,
     *		'qty' 				=> 22,
     * ];
     * @return boolean;
     *                  将购物车中的某个产品更改个数,更改后的个数就是上面qty的值。
     */
T
Terry 已提交
132
    /** 该函数已经被遗弃
_
__FresHmaN 已提交
133 134 135 136
    public function changeItemQty($item)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        // 查看是否存在此产品,如果存在,则更改
T
Terry 已提交
137
        $item_one = $this->_itemModel->find()->where([
T
Terry 已提交
138 139 140
            'cart_id'           => $cart_id,
            'product_id'        => $item['product_id'],
            'custom_option_sku' => $item['custom_option_sku'],
_
__FresHmaN 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154
        ])->one();
        if ($item_one['cart_id']) {
            $item_one->qty = $item['qty'];
            $item_one->save();
            // 重新计算购物车的数量
            Yii::$service->cart->quote->computeCartInfo();

            return true;
        } else {
            Yii::$service->helper->errors->add('This product is not available in the shopping cart');

            return false;
        }
    }
T
Terry 已提交
155
    */
_
__FresHmaN 已提交
156 157 158 159 160 161 162 163 164 165 166 167

    /**
     * 通过quoteItem表,计算得到所有产品的总数
     * 得到购物车中产品的总数,不要使用这个函数,这个函数的作用:
     * 在购物车中产品有变动后,使用这个函数得到产品总数,更新购物车中
     * 的产品总数。
     */
    public function getItemQty()
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        $item_qty = 0;
        if ($cart_id) {
T
Terry 已提交
168
            $data = $this->_itemModel->find()->asArray()->where([
_
__FresHmaN 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181
                'cart_id' => $cart_id,
            ])->all();
            if (is_array($data) && !empty($data)) {
                foreach ($data as $one) {
                    $item_qty += $one['qty'];
                }
            }
        }

        return $item_qty;
    }

    /**
182
     * @property $activeProduct | boolean , 是否只要active的产品
_
__FresHmaN 已提交
183 184 185 186 187 188 189 190 191
     * @return array , foramt:
     *               [
     *               'products' 		=> $products, 				# 产品详细信息,详情参看代码中的$products。
     *               'product_total' => $product_total, 			# 产品的当前货币总额
     *               'base_product_total' => $base_product_total,# 产品的基础货币总额
     *               'product_weight'=> $product_weight,			# 蟾皮的总重量、
     *               ]
     *               得到当前购物车的产品信息,具体参看上面的example array。
     */
192
    public function getCartProductInfo($activeProduct = true)
_
__FresHmaN 已提交
193
    {
T
Terry 已提交
194 195 196
        $cart_id        = Yii::$service->cart->quote->getCartId();
        $products       = [];
        $product_total  = 0;
_
__FresHmaN 已提交
197
        $product_weight = 0;
198
        $product_volume_weight = 0;
_
__FresHmaN 已提交
199 200
        if ($cart_id) {
            if (!isset($this->_cart_product_info[$cart_id])) {
T
Terry 已提交
201
                $data = $this->_itemModel->find()->where([
_
__FresHmaN 已提交
202 203 204 205
                    'cart_id' => $cart_id,
                ])->all();
                if (is_array($data) && !empty($data)) {
                    foreach ($data as $one) {
206 207 208 209
                        $active             = $one['active'];
                        if ($activeProduct && ($active != $this->activeStatus)) {
                            continue;
                        }
T
Terry 已提交
210 211
                        $product_id     = $one['product_id'];
                        $product_one    = Yii::$service->product->getByPrimaryKey($product_id);
_
__FresHmaN 已提交
212
                        if ($product_one['_id']) {
T
Terry 已提交
213
                            $qty                = $one['qty'];
214
                            
T
Terry 已提交
215 216
                            $custom_option_sku  = $one['custom_option_sku'];
                            $product_price_arr  = Yii::$service->product->price->getCartPriceByProductId($product_id, $qty, $custom_option_sku, 2);
_
__FresHmaN 已提交
217 218
                            $curr_product_price = isset($product_price_arr['curr_price']) ? $product_price_arr['curr_price'] : 0;
                            $base_product_price = isset($product_price_arr['base_price']) ? $product_price_arr['base_price'] : 0;
T
Terry 已提交
219
                            $product_price      = isset($curr_product_price['value']) ? $curr_product_price['value'] : 0;
_
__FresHmaN 已提交
220

T
Terry 已提交
221
                            $product_row_price  = $product_price * $qty;
_
__FresHmaN 已提交
222
                            $base_product_row_price = $base_product_price * $qty;
223
                            
224
                            $volume = Yii::$service->shipping->getVolume($product_one['long'], $product_one['width'], $product_one['high']);
225
                            $p_pv               = $volume * $qty;
T
Terry 已提交
226
                            $p_wt               = $product_one['weight'] * $qty;
227
                            $p_vwt              = $product_one['volume_weight'] * $qty;
228 229 230 231 232 233 234 235
                            
                            if ($active == $this->activeStatus) {
                                $product_total      += $product_row_price;
                                $base_product_total     += $base_product_row_price;
                                $product_weight         += $p_wt;
                                $product_volume_weight  += $p_vwt;
                                $product_volume         += $p_pv;
                            }
T
Terry 已提交
236
                            $productSpuOptions  = $this->getProductSpuOptions($product_one);
_
__FresHmaN 已提交
237
                            $products[] = [
T
Terry 已提交
238
                                'item_id'           => $one['item_id'],
239
                                'active'            => $active,
_
__FresHmaN 已提交
240
                                'product_id'        => $product_id,
T
Terry 已提交
241 242 243
                                'sku'               => $product_one['sku'],
                                'name'              => Yii::$service->store->getStoreAttrVal($product_one['name'], 'name'),
                                'qty'               => $qty,
_
__FresHmaN 已提交
244
                                'custom_option_sku' => $custom_option_sku,
T
Terry 已提交
245
                                'product_price'     => $product_price,
_
__FresHmaN 已提交
246 247 248
                                'product_row_price' => $product_row_price,

                                'base_product_price'    => $base_product_price,
T
Terry 已提交
249
                                'base_product_row_price'=> $base_product_row_price,
_
__FresHmaN 已提交
250

T
Terry 已提交
251
                                'product_name'      => $product_one['name'],
_
__FresHmaN 已提交
252 253
                                'product_weight'    => $product_one['weight'],
                                'product_row_weight'=> $p_wt,
254 255 256 257
                                'product_volume_weight'     => $product_one['volume_weight'],
                                'product_row_volume_weight' => $p_vwt,
                                'product_volume'        => $volume,
                                'product_row_volume'    => $p_pv,
T
Terry 已提交
258 259 260 261
                                'product_url'       => $product_one['url_key'],
                                'product_image'     => $product_one['image'],
                                'custom_option'     => $product_one['custom_option'],
                                'spu_options'       => $productSpuOptions,
_
__FresHmaN 已提交
262 263 264 265
                            ];
                        }
                    }
                    $this->_cart_product_info[$cart_id] = [
T
Terry 已提交
266 267 268 269
                        'products'          => $products,
                        'product_total'     => $product_total,
                        'base_product_total'=> $base_product_total,
                        'product_weight'    => $product_weight,
270 271 272
                        'product_volume_weight'    => $product_volume_weight,
                        'product_volume'    => $product_volume,
                        
_
__FresHmaN 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
                    ];
                }
            }

            return $this->_cart_product_info[$cart_id];
        }
    }

    /**
     * @property $productOb | Object,类型:\fecshop\models\mongodb\Product
     * 得到产品的spu对应的属性以及值。
     * 概念 - spu options:当多个产品是同一个spu,但是不同的sku的时候,他们的产品表里面的
     * spu attr 的值是不同的,譬如对应鞋子,size 和 color 就是spu attr,对于同一款鞋子,他们
     * 是同一个spu,对于尺码,颜色不同的鞋子,是不同的sku,他们的spu attr 就是 color 和 size。
     */
    protected function getProductSpuOptions($productOb)
    {
        $custom_option_info_arr = [];
        if (isset($productOb['attr_group']) && !empty($productOb['attr_group'])) {
            $productAttrGroup = $productOb['attr_group'];
            Yii::$service->product->addGroupAttrs($productAttrGroup);
T
Terry 已提交
294 295
            $productOb  = Yii::$service->product->getByPrimaryKey((string) $productOb['_id']);
            $spuArr     = Yii::$service->product->getSpuAttr($productAttrGroup);
_
__FresHmaN 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
            if (is_array($spuArr) && !empty($spuArr)) {
                foreach ($spuArr as $spu_attr) {
                    if (isset($productOb[$spu_attr]) && !empty($productOb[$spu_attr])) {
                        $custom_option_info_arr[$spu_attr] = $productOb[$spu_attr];
                    }
                }
            }
        }

        return $custom_option_info_arr;
    }

    /**
     * @property $item_id | Int , quoteItem表的id
     * @return bool
     *              将这个item_id对应的产品个数+1.
     */
    public function addOneItem($item_id)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        if ($cart_id) {
T
Terry 已提交
317
            $one = $this->_itemModel->find()->where([
_
__FresHmaN 已提交
318 319 320
                'cart_id' => $cart_id,
                'item_id' => $item_id,
            ])->one();
T
Terry 已提交
321 322 323 324 325
            $product_id = $one['product_id'];
            if ($one['item_id'] && $product_id) {
                $product = Yii::$service->product->getByPrimaryKey($product_id);
                $changeQty = Yii::$service->cart->getCartQty($product['package_number'], 1);
                $one['qty'] = $one['qty'] + $changeQty;
_
__FresHmaN 已提交
326 327 328
                $one->save();
                // 重新计算购物车的数量
                Yii::$service->cart->quote->computeCartInfo();
329 330 331 332 333
                $item = [
                    'product_id' 		=> $product_id,
                    'custom_option_sku' => $one['custom_option_sku'],
                    'qty' 				=> $changeQty,
                    'sku' 				=> $product['sku'],
T
Terry 已提交
334
                    'afterAddQty'       => $one['qty'],
335 336
                ];
                // 购物车数据加1
T
Terry 已提交
337
                $this->sendTraceAddToCartInfoByApi($item);
_
__FresHmaN 已提交
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
                return true;
            }
        }

        return false;
    }

    /**
     * @property $item_id | Int , quoteItem表的id
     * @return bool
     *              将这个item_id对应的产品个数-1.
     */
    public function lessOneItem($item_id)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        if ($cart_id) {
T
Terry 已提交
354
            $one = $this->_itemModel->find()->where([
_
__FresHmaN 已提交
355 356 357
                'cart_id' => $cart_id,
                'item_id' => $item_id,
            ])->one();
T
Terry 已提交
358
            $product_id = $one['product_id'];
359
            $product = Yii::$service->product->getByPrimaryKey($one['product_id']);
T
Terry 已提交
360 361 362 363 364
            $changeQty = Yii::$service->cart->getCartQty($product['package_number'], 1);
            $lessedQty = $one['qty'] - $changeQty;
            $min_sales_qty = 1;
            if ($product['min_sales_qty'] && $product['min_sales_qty'] >= 2) {
                $min_sales_qty = $product['min_sales_qty'];
365
            }
T
Terry 已提交
366 367 368 369 370 371
            if($lessedQty < $min_sales_qty){
                Yii::$service->helper->errors->add('product less buy qty is '.$product['min_sales_qty']);
                
                return false;
            }
            
_
__FresHmaN 已提交
372 373
            if ($one['item_id']) {
                if ($one['qty'] > 1) {
374
                    $one['qty'] = $lessedQty;
_
__FresHmaN 已提交
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
                    $one->save();
                    // 重新计算购物车的数量
                    Yii::$service->cart->quote->computeCartInfo();

                    return true;
                }
            }
        }

        return false;
    }

    /**
     * @property $item_id | Int , quoteItem表的id
     * @return bool
     *              将这个item_id对应的产品删除
     */
    public function removeItem($item_id)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        if ($cart_id) {
T
Terry 已提交
396
            $one = $this->_itemModel->find()->where([
_
__FresHmaN 已提交
397 398 399 400 401 402 403 404 405 406 407 408 409 410
                'cart_id' => $cart_id,
                'item_id' => $item_id,
            ])->one();
            if ($one['item_id']) {
                $one->delete();
                // 重新计算购物车的数量
                Yii::$service->cart->quote->computeCartInfo();

                return true;
            }
        }

        return false;
    }
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
    
    /**
     * @property $item_id | Int , quoteItem表的id
     * @return bool
     *              将这个item_id对应的产品个数+1.
     */
    public function selectOneItem($item_id, $checked)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        if ($cart_id) {
            $one = $this->_itemModel->find()->where([
                'cart_id' => $cart_id,
                'item_id' => $item_id,
            ])->one();
            $product_id = $one['product_id'];
            if ($one['item_id'] && $product_id) {
                //$product = Yii::$service->product->getByPrimaryKey($product_id);
                //$changeQty = Yii::$service->cart->getCartQty($product['package_number'], 1);
                //$one['qty'] = $one['qty'] + $changeQty;
                if ($checked == true) {
                    $one->active = $this->activeStatus;
                } else {
                    $one->active = $this->noActiveStatus;
                }
                $one->save();
                // 重新计算购物车的数量
                Yii::$service->cart->quote->computeCartInfo();

                return true;
            }
        }

        return false;
    }
    
    /**
     * @property $item_id | Int , quoteItem表的id
     * @return bool
     *              将这个item_id对应的产品个数+1.
     */
    public function selectAllItem($checked)
    {
        $cart_id = Yii::$service->cart->quote->getCartId();
        if ($cart_id) {
            $active = $this->noActiveStatus;
            if ($checked == true) {
                $active = $this->activeStatus;
            }
            $updateCount = $this->_itemModel->updateAll(
                ['active'  => $active],
                ['cart_id' => $cart_id]
            ); 
            if ($updateCount > 0) {
                Yii::$service->cart->quote->computeCartInfo();
            }
            
            return true;
        }

        return false;
    }
    
    
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
    /** 
     * @property $cart_id | int 购物车id
     * 删除购物车中的所有的active产品。对于noActive产品保留
     * 注意:清空购物车并不是清空所有信息,仅仅是清空用户购物车中的产品。
     * 另外,购物车的数目更改后,需要更新cart中产品个数的信息。
     */
    public function removeNoActiveItemsByCartId($cart_id = '')
    {
        if (!$cart_id) {
            $cart_id = Yii::$service->cart->quote->getCartId();
        }
        if ($cart_id) {
            $columns = $this->_itemModel->deleteAll([
                'cart_id' => $cart_id,
                'active'  => $this->activeStatus,
            ]);
            if ($columns > 0) {
                // 重新计算购物车的数量
                Yii::$service->cart->quote->computeCartInfo();
_
__FresHmaN 已提交
493

494 495 496 497 498 499 500
                return true;
            }
        }
        
    }

    /** 废弃,改为 removeNoActiveItemsByCartId(),因为购物车改为勾选下单方式。
_
__FresHmaN 已提交
501 502 503 504 505 506 507 508 509 510 511
     * @property $cart_id | int 购物车id
     * 删除购物车中的所有产品。
     * 注意:清空购物车并不是清空所有信息,仅仅是清空用户购物车中的产品。
     * 另外,购物车的数目更改后,需要更新cart中产品个数的信息。
     */
    public function removeItemByCartId($cart_id = '')
    {
        if (!$cart_id) {
            $cart_id = Yii::$service->cart->quote->getCartId();
        }
        if ($cart_id) {
T
Terry 已提交
512
            $items = $this->_itemModel->deleteAll([
_
__FresHmaN 已提交
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
                'cart_id' => $cart_id,
                //'item_id' => $item_id,
            ]);
            // 重新计算购物车的数量
            Yii::$service->cart->quote->computeCartInfo(0);
        }

        return true;
    }

    /**
     * @property $new_cart_id | int 更新后的cart_id
     * @property $cart_id | int 更新前的cart_id
     * 删除购物车中的所有产品。
     * 这里仅仅更改cart表的cart_id, 而不会做其他任何事情。
     */
    public function updateCartId($new_cart_id, $cart_id)
    {
        if ($cart_id && $new_cart_id) {
T
Terry 已提交
532
            $this->_itemModel->updateAll(
533 534
                ['cart_id' => $new_cart_id],  // $attributes
                ['cart_id' => $cart_id]       // $condition
_
__FresHmaN 已提交
535 536 537 538 539 540 541 542 543
            );
            // 重新计算购物车的数量
            //Yii::$service->cart->quote->computeCartInfo();
            return true;
        }

        return false;
    }
}