<?php
namespace Business\Cart;
use Our\ApiConst;
use Our\DbNameConst;

/**
 * User: liuyuzhen
 * Date: 2018/6/20
 * Time: 14:26
 * Description:
 */

class CartServiceModel extends \Business\AbstractModel{

    /**
     * 商品加入购物车
     * @param $data 前台数据
     * @param $memberId 会员ID
     * @param null $pBundling 组合销售商品
     * @return mixed
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function addCart($data,$memberId,$pBundling = null){
        $validReturnData = $this->validAddCart($data,$memberId,$pBundling);
        $cartArray = $this->getFormattedCartData($data,$memberId,$pBundling,$validReturnData);
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        /*if(isset($cartArray['cartId'])&&$cartArray['cartId']){
            $result = $cartDao->update($cartArray['cart'],array('cart_id'=>$cartArray['cartId']));
        }else{
            $result = $cartDao->insert($cartArray['cart']);
        }*/
        $result = $cartDao->insertAllOrUpdate($cartArray['newCarts']);
        if(!$result){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::addCartFailed);
        }

        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $memberCartKey = \Our\NameConst::memberCartStorePrefix.$memberId;
        $cartRedis->tableDel($memberCartKey);
        foreach($cartArray['storeIds'] as $storeId){
            $memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$storeId;
            $cartRedis->tableDel($memberStoreCartsKey);
        }
        return $result;
    }



    /**
     * 编辑购物车
     * @param $data
     * @param $memberId
     * @param $pBundlind
     */
    public function editCart($data,$cart,$memberId,$pBundlind=null){
        $validReturnData = $this->validEditCart($data,$cart,$memberId,$pBundlind);
        if(isset($validReturnData['existCartFlag'])&&$validReturnData['existCartFlag']==\Our\ApiConst::one){
            return $this->editDelCart($cart,$memberId);
        }
        $cartArray = $this->getFormattedCartDataForEdit($data,$cart,$memberId,$pBundlind,$validReturnData);
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $result = $cartDao->update($cartArray['newCarts'][0],array('cart_id'=>$data['cartId']));
        if(!$result){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::editCartFailed);
        }
        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $memberCartKey = \Our\NameConst::memberCartStorePrefix.$memberId;
        $cartRedis->tableDel($memberCartKey);
        foreach($cartArray['storeIds'] as $storeId){
            $memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$storeId;
            $cartRedis->tableDel($memberStoreCartsKey);
        }
        /*$memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$cartArray['cart']['store_id'];
        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $cartRedis->tableDel($memberStoreCartsKey);*/
        return $result;
    }

    /**
     * 编辑规格时出现当前规格已经在购物车时,删除当前购物车
     * @param $cart
     * @param $memberId
     * @return mixed
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function editDelCart($cart,$memberId){
        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $result = $cartDao->del(array('cart_id'=>$cart['cart_id']));
        if(!$result){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::editDelCartFailed);
        }
        $updateResult = $cartDao->update(array('gmt_update'=>TIMESTAMP),array('goods_id'=>$cart['goods_id'],'buyer_id'=>$memberId));
        if($updateResult===false){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::editCartUploadCartFailed);
        }
        $memberCartKey = \Our\NameConst::memberCartStorePrefix.$memberId;
        $cartRedis->tableDel($memberCartKey);
        $memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$cart['store_id'];
        $cartRedis->tableDel($memberStoreCartsKey);
        return $result;
    }

    /**
     * 批量删除购物车
     * @param $data
     * @param $memberId
     * @return mixed
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function delCarts($data,$memberId){

        $cartList = $this->getCartList($data,$memberId);
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $cartIds = explode(',',$data['cartIds']);
        $cartIds = array_filter($cartIds);
        $sql = \Our\Common::format(' cart_id in({0}) and buyer_id={1}',implode(',',$cartIds),$memberId);
        $result = $cartDao->del($sql);
        if(!$result){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::editCartFailed);
        }

        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $memberCartKey = \Our\NameConst::memberCartStorePrefix.$memberId;
        $cartRedis->tableDel($memberCartKey);
        foreach($cartList as $cart){
            $memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$cart['store_id'];
            $cartRedis->tableDel($memberStoreCartsKey);
        }
        return $result;
    }

    public function getCartList($data,$memberId){
        if(!$data['cartIds']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartIdsForDel);
        }
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $cartIds = explode(',',$data['cartIds']);
        $cartIds = array_filter($cartIds);
        if(!$cartIds){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartIdsForDel);
        }
        $sql = \Our\Common::format(' cart_id in({0}) and buyer_id={1}',implode(',',$cartIds),$memberId);
        $cartList = $cartDao->getList($sql);
        if(!($cartList&&count($cartIds)==count($cartList))){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongCartIdsForDel);
        }
        return $cartList;
    }

    /**
     * 删除购物车
     * @param $data
     * @param $memberId
     */
    public function delCart($data,$memberId){
        $cart = $this->getOneCart($data,$memberId);
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $result = $cartDao->del(array('cart_id'=>$data['cartId'],'buyer_id'=>$memberId));
        if(!$result){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::editCartFailed);
        }
        $memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$cart['store_id'];
        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $cartRedis->tableDel($memberStoreCartsKey);

        $memberCartKey = \Our\NameConst::memberCartStorePrefix.$memberId;
        $cartRedis->tableDel($memberCartKey);
        return $result;
    }

    /**
     * 获取加入购物车数据内容
     * @param $data
     * @param $memberId
     * @param null $pBundling
     * @return array
     * @throws \Our\Exception
     */
    public function getFormattedCartDataForEdit($data,$cart,$memberId,$pBundling = null,$validReturnData){
        if($cart['type'] == \Our\ApiConst::addGoodsToCart){
            $newCart = $this->getCommonGoodsCartData($data['goodsId'],$data['goodsNum'],$memberId,$validReturnData);
        }else if($cart['type'] == \Our\ApiConst::addBundingToCart){
            $newCart = $this->getPBundlingGoodsCartData($data['goodsNum'],$memberId,$pBundling);
        }
        unset($newCart['newCarts'][0]['gmt_update']);
        return $newCart;
    }


    /**
     * 获取加入购物车数据内容
     * @param $data
     * @param $memberId
     * @param null $pBundling
     * @return array
     * @throws \Our\Exception
     */
    public function getFormattedCartData($data,$memberId,$pBundling = null,$validReturnData){
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $cartId = null;
        if($data['type'] == \Our\ApiConst::addGoodsToCart){
            $goodsNum = isset($data['goodsNum'])?$data['goodsNum']:\Our\ApiConst::zero;
            $newCarts = $this->getCommonGoodsCartData($data['goodsId'],$goodsNum,$memberId,$validReturnData);
            /*$conCart['store_id'] = $newCart['store_id'];
            $conCart['goods_id'] = $newCart['goods_id'];
            $conCart['goods_commonid'] = $newCart['goods_commonid'];
            $conCart['type'] = \Our\ApiConst::addGoodsToCart;
            $conCart['buyer_id'] = $memberId;
            $oldCart = $cartDao->find($conCart);
            if($oldCart){
                $newCart['goods_num'] = $oldCart['goods_num'] + $data['goodsNum'];
                $cartId = $oldCart['cart_id'];
            }*/
        }else if($data['type'] == \Our\ApiConst::addBundingToCart){
            $newCarts = $this->getPBundlingGoodsCartData($data['blNum'],$memberId,$pBundling);
            /*$conCart['store_id'] = $newCart['store_id'];
            $conCart['goods_id'] = $newCart['blId'];
            $conCart['type'] = \Our\ApiConst::addBundingToCart;
            $conCart['buyer_id'] = $memberId;
            $oldCart = $cartDao->find($conCart);
            if($oldCart){
                $newCart['goods_num'] = $oldCart['goods_num'] + $data['blNum'];
                $cartId = $oldCart['cart_id'];
            }*/
        }
        return $newCarts;
        //return array('cart'=>$newCart,'cartId'=>$cartId);
    }


    public function getCommonGoodsCartData($goodsId,$goodsNum,$memberId,$validReturnData){
        $storeDao = \DAO\StoreModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $storeIds = array();
        $returnCart = array();
        if(substr( $goodsId, 0, 1 )==\Our\NameConst::leftBracket&&substr( $goodsId, -1, 1 )==\Our\NameConst::rightBracket){
            foreach($validReturnData as $goods){
                $newCart = array();
                $store = $storeDao->get($goods['store_id'],false);
                if(!($storeIds&&in_array($goods['store_id'],$storeIds))){
                    $storeIds[]=$goods['store_id'];
                }
                $newCart['store_id'] = $goods['store_id'];
                $newCart['goods_id'] = $goods['goods_id'];
                $newCart['goods_commonid'] = $goods['goods_commonid'];
                $newCart['type'] = \Our\ApiConst::addGoodsToCart;
                $newCart['store_name'] = $store['store_name'];
                $newCart['goods_name'] = $goods['goods_name'];
                $newCart['goods_price'] = \Goods\GoodsUtil::getInstance()->getRealPrice($goods['goods_id'],$memberId,null,\Our\ApiConst::addGoodsToCart,\Our\DbNameConst::masterDBConnectName);
                $newCart['goods_original_price'] = $newCart['goods_price'];
                $newCart['goods_image'] = $goods['goods_image'];
                $newCart['goods_spec'] = $goods['goods_spec'];
                $newCart['goods_mid'] = $store['member_id'];
                $newCart['gmt_update'] = time();
                $newCart['goods_num'] = \Our\ApiConst::one;
                $newCart['buyer_id'] = $memberId;
                $newCart['snapshot_id'] = $goods['snapshot_id'];
                $returnCart[] = $newCart;
            }
        }else{
            $goods = $validReturnData;
            $store = $storeDao->get($goods['store_id'],false);
            $storeIds[]=$goods['store_id'];
            $newCart['store_id'] = $goods['store_id'];
            $newCart['goods_id'] = $goods['goods_id'];
            $newCart['goods_commonid'] = $goods['goods_commonid'];
            $newCart['type'] = \Our\ApiConst::addGoodsToCart;
            $newCart['store_name'] = $store['store_name'];
            $newCart['goods_name'] = $goods['goods_name'];
            $newCart['goods_price'] = \Goods\GoodsUtil::getInstance()->getRealPrice($goods['goods_id'],$memberId,null,\Our\ApiConst::addGoodsToCart,\Our\DbNameConst::masterDBConnectName);
            $newCart['goods_original_price'] = $newCart['goods_price'];
            $newCart['goods_image'] = $goods['goods_image'];
            $newCart['goods_spec'] = $goods['goods_spec'];
            $newCart['goods_mid'] = $store['member_id'];
            $newCart['gmt_update'] = time();
            $newCart['goods_num'] = $goodsNum;
            $newCart['buyer_id'] = $memberId;
            $newCart['snapshot_id'] = $goods['snapshot_id'];
            $returnCart[]= $newCart;
        }
        return array('storeIds'=>$storeIds,'newCarts'=>$returnCart);
    }

    public function getCommonGoodsListCartData($goodsIds,$memberId){

    }

    public function getPBundlingGoodsCartData($blNum,$memberId,$pBundling){
        $storeDao = \DAO\StoreModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $store = $storeDao->get($pBundling['store_id'],false);
        $newCart['store_id'] = $pBundling['store_id'];
        $newCart['goods_id'] = $pBundling['blId'];
        $newCart['goods_commonid'] = \Our\ApiConst::zero;
        $newCart['type'] = \Our\ApiConst::addBundingToCart;
        $newCart['store_name'] = $store['store_name'];
        $newCart['goods_mid'] = $store['member_id'];
        $newCart['goods_name'] =  $pBundling['name'];
        $newCart['goods_price'] = \Goods\GoodsUtil::getInstance()->getRealPrice($pBundling['blId'],null,null,\Our\ApiConst::addBundingToCart,\Our\DbNameConst::masterDBConnectName);
        $newCart['goods_original_price'] = $pBundling['sumPrice'];
        $newCart['goods_image'] = $pBundling['image'];
        $newCart['goods_num'] = $blNum;
        $newCart['gmt_update'] = time();
        $newCart['buyer_id'] = $memberId;
        $newCart['snapshot_id'] = $pBundling['snapshot_id'];
        $newCart['goods_spec'] = serialize(array());
        return array('storeIds'=>array($pBundling['store_id']),'newCarts'=>array($newCart));
    }

    /**
     * 加入购物车数据验证
     * @param $data
     * @param $memberId
     */
    public function validAddCart($data,$memberId,$pBundling = null){
        if(!$memberId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyAddCartMemberId);
        }
        if(!(isset($data['type'])&&in_array($data['type'],array(\Our\ApiConst::addGoodsToCart,\Our\ApiConst::addBundingToCart)))){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongCartType);
        }
        if($data['type'] == \Our\ApiConst::addGoodsToCart){
            if(!$data['goodsId']){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartGoodsId);
            }

            $goodsDao = \DAO\GoodsModel::getInstance(\Our\DbNameConst::masterDBConnectName);
            if(substr( $data['goodsId'], 0, 1 )==\Our\NameConst::leftBracket&&substr( $data['goodsId'], -1, 1 )==\Our\NameConst::rightBracket){
                $goodsIds = json_decode($data['goodsId'],true);
                $goodsValidStatus = $goodsDao->validAddCartGoodsList($goodsIds);
            }else{
                if(!(isset($data['goodsNum'])&&intval($data['goodsNum'])>\Our\ApiConst::zero)){
                    \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartGoodsNum);
                }
                $goodsValidStatus = $goodsDao->validAddCartGoods($data);
            }
            if(!$goodsValidStatus){
                \Error\ErrorModel::throwException($goodsDao->errorCode);
            }
            return $goodsValidStatus;
        }else if($data['type'] == \Our\ApiConst::addBundingToCart){
            if(!$pBundling){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartBundling);
            }
            if(!$data['blId']){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartBlId);
            }
            if(!(isset($data['blNum'])&&intval($data['blNum'])>\Our\ApiConst::zero)){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartBlNum);
            }
            $this->checkBundlingGoods($pBundling,$data['blNum']);
        }
        return true;
    }

    public function  getOneCart($where,$memberId){
        $this->validCartData($where);
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $cart = $cartDao->find(array('cart_id'=>$where['cartId']));
        if(!$cart){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartById);
        }
        if($cart['buyer_id'] != $memberId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::unusaulCartForMember);
        }
        return $cart;
    }

    public function validCartData($where){
        if(!$where['cartId']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartId);
        }
        return true;
    }

    public function validEditCart($data,$cart,$memberId,$pBundling =null){
        if($cart['buyer_id']!= $memberId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMemberIdForEditCart);
        }
        if($cart['type'] == \Our\ApiConst::addGoodsToCart){
            if(!$data['goodsId']){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartGoodsId);
            }
            if(!(isset($data['goodsNum'])&&intval($data['goodsNum'])>\Our\ApiConst::zero)){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartGoodsNum);
            }
            $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
            $existCart = $cartDao->find(array('goods_id'=>$data['goodsId'],'buyer_id'=>$memberId,'cart_id'=>array('neq',$cart['cart_id'])));
            if($existCart){
                return array('existCartFlag'=>\Our\ApiConst::one);
            }
            $goodsDao = \DAO\GoodsModel::getInstance(\Our\DbNameConst::masterDBConnectName);
            $goodsValidStatus = $goodsDao->validEditCartGoods($data,$cart,false);
            if(!$goodsValidStatus){
                \Error\ErrorModel::throwException($goodsDao->errorCode);
            }
            return $goodsValidStatus;
        }else if($cart['type'] == \Our\ApiConst::addBundingToCart){
            if(!$pBundling){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartBundling);
            }
            if(!(isset($data['goodsNum'])&&intval($data['goodsNum'])>\Our\ApiConst::zero)){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartBlNum);
            }
            $this->checkBundlingGoods($pBundling,$data['goodsNum']);
        }
        return true;
    }

    /**
     * 验证组合销售
     * @param $pBundling 组合销售商品
     * @param $blNum 组合销售数量
     * @throws Exception
     * @throws \Error\OurExceptionModel
     */
    public function checkBundlingGoods($pBundling,$blNum,$storageFlag = false){
        if(!$pBundling){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartBundling);
        }
        if(!($pBundling['bl_state'] == \Our\ApiConst::one&&($pBundling['bl_quota_starttime']<time()&&$pBundling['endTime']>=time()))){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::cartClosedBundling);
        }
        if(isset($pBundling['goodsCountFlag'])&&$pBundling['goodsCountFlag']==false){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::bundlingGoodsOffline);
        }
        if($pBundling['bl_storage']<$blNum&&$storageFlag){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::lessBundlingNumForCart);
        }
        if($storageFlag){
            $goodsList = $pBundling['goodsList'];
            foreach($goodsList as $goods){
                if($goods['num']*$blNum>$goods['goodsStorage']){
                    \Error\ErrorModel::throwException(\Error\CodeConfigModel::lessGoodsNumForCart);
                }
            }
        }
    }




    public function getCart($data,$memberId){
        $cartDao = \DAO\Cart\CartModel::getInstance();
        $where['buyer_id'] = $memberId;
        $order = array('gmtupdate'=>\Our\NameConst::desc);
        $field = 'MAX(gmt_update) AS gmtupdate,store_id';
        $group = 'store_id';
        $storeIds = $cartDao->getCartStoreIdsByMemberId($where,$memberId,$field,$group,$order);
        //$cartStores = $cartDao->lists($where,$order,$field,$data['pageIndex'],$data['pageSize'],$group);
        $storeIdList = array_column($storeIds,'store_id');
        $totalCount = count($storeIdList);
        if($totalCount==\Our\ApiConst::zero){
            return array('totalCount'=>\Our\ApiConst::zero,'list'=>array());
        }
        if($data['pageIndex']*$data['pageSize']>$totalCount){
            //\Error\ErrorModel::throwException(\Error\CodeConfigModel::overLimitCartCount);
            return array('totalCount'=>$totalCount,'list'=>array());
        }
        $storeIdArray = array_slice($storeIdList,$data['pageIndex']*$data['pageSize'],$data['pageSize']);
        $cartList =$cartDao->getStoreCartListByMemberId1($storeIdArray,$memberId,\Our\NameConst::allField,array('gmt_update'=>\Our\NameConst::desc));
        return $cartList;

    }


    public function getCartGoodsCommonIdForGoodsAttr($where,$memberId){
        $cart = $this->getOneCart($where,$memberId);
        if(!($cart['type'] == \Our\ApiConst::addGoodsToCart&&$cart['goods_commonid'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::lessGoodsNumForCart);
        }
        return $cart['goods_commonid'];
    }

    public function getCartGoodsAttrData($goodsData){
        unset($goodsData['images']);
        unset($goodsData['commonInfo']);
        unset($goodsData['previewImage']);
        unset($goodsData['goodsMarketPrice']);
        if($goodsData['goods']){
            foreach($goodsData['goods'] as $goods){
                unset($goods['goodsMarketPrice']);
                $goodsList[] = $goods;
            }
            $goodsData['goods'] = $goodsList;
        }
        return $goodsData;
    }

    /**
     * 移入收藏夹功能
     * @param $where
     * @param $memberId
     * @return bool
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function moveToFavorites($where,$memberId){
        $cartList = $this->getCartList($where,$memberId);
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $favoritesDao = \DAO\FavoritesModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $cartDao->db->doTransaction();
        $favList = array();
        foreach($cartList as $cart){
            $fav = array();
            $fav['member_id'] = $memberId;
            if($cart['type'] == \Our\ApiConst::addGoodsToCart){
                $fav['goods_commonid'] = $cart['goods_commonid'];
            }else{
                $fav['goods_commonid'] = $cart['goods_id'];
            }
            $fav['fav_type'] = $cart['type'];
            $favList[] = $fav;
        }
        $favResult = $favoritesDao->insertAllOrUpdate($favList);
        if(!$favResult){
            $cartDao->db->doRollback();
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::moveToFavoritesFailed);
        }
        $cartIds = explode(',',$where['cartIds']);
        $cartIds = array_filter($cartIds);
        $sql = \Our\Common::format(' cart_id in({0}) and buyer_id={1}',implode(',',$cartIds),$memberId);
        $result = $cartDao->del($sql);
        if(!$result){
            $cartDao->db->doRollback();
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::moveToFavoritesDelCartFailed);
        }
        $memberCartKey = \Our\NameConst::memberCartStorePrefix.$memberId;
        $cartRedis = \Redis\Db7\CartRedisModel::getInstance();
        $cartRedis->tableDel($memberCartKey);
        $FavoritesInstance = \DAO\FavoritesModel::getInstance();
        foreach($cartList as $cart){
            $memberStoreCartsKey = \Our\NameConst::memberStoreCartsPrefix.$memberId.\Our\NameConst::underline.$cart['store_id'];
            $cartRedis->tableDel($memberStoreCartsKey);
            \Our\RedisHelper::delCachedFunction(\Redis\Db4\FavoritesRedisModel::getInstance(),array(&$FavoritesInstance, 'getOne'),array('*',array('member_id'=>$memberId,'goods_commonid'=>$cart['goods_commonid'])),array($memberId));
        }
        \Our\RedisHelper::delCachedFunction(\Redis\Db4\FavoritesRedisModel::getInstance(),array(&$FavoritesInstance, 'getList'),array(),array($memberId));
        //更新个人中心首页数量
        //\DAO\MemberModel::getInstance()->_changeNum(\Our\NameConst::goodsCollection,$memberId,count($cartList));
        \Redis\Db1\MemberCenterRedisModel::getInstance()->tableHDel($memberId,\Our\NameConst::goodsCollection);
        $cartDao->db->doCommit();
        return false;
    }

    /**
     * 获取当前地址
     * @param $currentAddress
     * @param $memberId
     * @return bool|mixed
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     * @throws \Our\Exception
     */
    public function checkCurrentAddress($currentAddress,$memberId){
        $addressId = $currentAddress['addressId'];
        if($addressId>\Our\ApiConst::zero){
            $addressDao = \DAO\AddressModel::getInstance();
            $columns = $addressDao->getAddressColumns();
            $condition['address_id'] = $addressId;
            $address = \Our\RedisHelper::cachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'findByWhereWithColumns'),array($condition,$columns),3600,array($addressId));
            if(!$address||($address&&$address['member_id']!=$memberId)){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::addressNotExist);
            }
            $result = array();
            $result['addressId'] = $address['address_id'];
            $result['trueName'] = $address['true_name'];
            $result['mobPhone'] = $address['mob_phone']?$address['mob_phone']:$address['tel_phone'];
            $result['address'] = $address['province'].$address['city'].$address['district'].$address['address'].$address['subaddress'];
            $result['lat'] = $address['lat'];
            $result['lng'] = $address['lng'];
            $result['city_id'] = $address['city_id'];
            return $result;
        }
        return false;
    }

    /**
     * 获取店铺配送方式和支付方式信息
     * @param $address
     * @param $storeCartData
     */
    public function getDeliveryTypeForCart($address,$storeCartData,$dbName = \Our\DbNameConst::salveDBConnectName){
        $storeIds = $storeCartData['storeIds'];
        $storeDao = \DAO\StoreModel::getInstance();
        $deliveryFormulaDao = \DAO\DeliveryFormulaModel::getInstance($dbName);
        foreach($storeIds as $storeId){
            $store = $storeDao->get($storeId,false);
            $storeCarts = $storeCartData['cartList'][$storeId];
            $deliverySetting['onelinePay'] = $store['wx_pay'];//是否支持线上支付
            $deliverySetting['offlinePay'] = $store['offline_pay'];
            if($deliverySetting['offlinePay']){
                $deliverySetting['offlinePayway'] = $store['offline_payway'];
            }
            $deliverySetting['aogPay'] = $store['aog_pay'];
            $deliverySetting['buyerDistribution'] = $store['buyer_distribution'];
            $deliverySetting['sellerDistribution'] = $store['seller_distribution'];
            if($deliverySetting['sellerDistribution']&&$address){
                $str = str_replace('\"','"',$store['store_sales_scope']);
                $store_sales_scope = json_decode($str,true);
                $result = \Our\CommonExtension::isPointInPolygon($store_sales_scope, array('lng'=>$address['lng'],'lat'=>$address['lat']));
                $storeDistance = \Our\CommonExtension::getDistance($address['lat'],$address['lng'],$store['store_latitude'],$store['store_longitude'],\Our\ApiConst::one);

                if($result){
                    $deliverTimeList = $deliveryFormulaDao->getDeliveryFormulaForCart($store,$storeDistance,$storeCarts['deliveryFreeFlag']);
                    if($deliverTimeList){
                        $deliverySetting['deliverTimeList'] =$deliverTimeList;
                        $storeCartData['cartList'][$storeId]['storeDistance'] = $storeDistance;
                    }else{
                        $deliverySetting['sellerDistribution'] = \Our\ApiConst::zero;
                    }
                }else{
                    $deliverySetting['sellerDistribution'] = \Our\ApiConst::zero;
                }
            }else{
                $deliverySetting['sellerDistribution'] = \Our\ApiConst::zero;
            }

            $deliverySetting['expressDistribution'] = $store['express_distribution'];
            //if($deliverySetting['expressDistribution']&&$storeCarts['is_transport']==\Our\ApiConst::one&&$storeCarts['transport_id']){
            if($deliverySetting['expressDistribution']){
                if($storeCarts['goodsFreight']){ //商品免邮
                    $shippingFee = \Our\ApiConst::zero;
                }else{
                    $shippingFee = $this->calcTransport($storeCarts['transport_id'],$storeCarts['storeExpressNum'], $address['city_id']);
                }
                $deliverySetting['shippingFee'] = $shippingFee;
            }else{
                $deliverySetting['expressDistribution'] = \Our\ApiConst::zero;
            }
            $storeCartData['cartList'][$storeId]['deliverySetting'] = $deliverySetting;
        }
        return $storeCartData;
    }



    /**
     * 计算某地区某运费模板ID下的商品总运费，如果运费模板不存在或，按免运费处理
     *
     * @param int $transport_id 运费模板ID
     * @param int $buy_num  购物件数
     * @param int $area_id han_area表的城市Id
     * @return number/boolean
     */
    public function calcTransport($transportId, $buyNum, $areaId) {
        if (empty($transportId) || empty($buyNum) || empty($areaId)) return 0;
        $transportExtendDao = \DAO\Goods\TransportExtendModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $extendList = $transportExtendDao->getList(array('transport_id'=>$transportId));
        if (empty($extendList)) {
            return 0;
        } else {
            $transportDao = \DAO\Goods\TransportModel::getInstance(\Our\DbNameConst::masterDBConnectName);
            return $transportDao->calcUnit($areaId,$buyNum,$extendList);
        }
    }


    /**
     * 检查购物车商品
     * @param $data
     * @param $memberId
     * @return array|bool
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function checkCart($data,$memberId){
        //验证购物车商品信息和总价
        if(!$data['cartIds']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCartIdsForCheckout);
        }
        $cartIds = array_filter(explode(',',$data['cartIds']));
        $cartDao = \DAO\Cart\CartModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $storeCartList = $cartDao->getStoreCartListByCartIds($cartIds,$memberId);
        return $storeCartList;
    }

    public function checkBuynow($data,$memberId){
        if(empty($data['blId'])&&empty($data['goodsId'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyGoodsIdOrBlIdForBuyNow);
        }
        if(!($data['goodsNum']&&intval($data['goodsNum'])>\Our\ApiConst::zero)){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyGoodsNumForBuyNow);
        }
    }

    public function getCartStoreInfo($cartList){

    }

    public function checkout($data,$currentAddress,$memberId){

        $addressDao = \DAO\AddressModel::getInstance();
        //获取当前收货人的地址信息
        $address = $this->checkCurrentAddress($currentAddress,$memberId);

    }

    public function checkCouponForCart($storeCartData,$memberId){
        $goodsIds = $storeCartData['goodsIds'];
        $goodsCommonIds = $storeCartData['goodsCommonIds'];
        $gcIds = $storeCartData['gcIds'];
        if(!($goodsIds&&$goodsCommonIds&&$gcIds)){ //如果当前没有goodsIds 和 goodsCommonIds传进来表示当前商品列表没有优惠券可用
            $storeCartData['couponList'] = array();
            return $storeCartData;
        }
        //第一步:获取购物车可展示优惠券信息
        $memberCouponDao = \DAO\Coupon\MemberCouponModel::getInstance();
        $whereSql = ' coupon_state ='.\Our\ApiConst::couponUnused.' and member_id ='.$memberId.' and out_time > '.time();
        $memberCouponArray = $memberCouponDao->getList($whereSql,'coupon_id');
        if(!$memberCouponArray){
            $storeCartData['couponList'] = array();
            return $storeCartData;
        }
        $couponStoreIds   = $storeCartData['storeIds'];
        $couponStoreIds[] = \Our\ApiConst::zero;
        $couponIds = array_column($memberCouponArray,'coupon_id');
        $couponSql = \Our\Common::format(' id in ({0}) and store_id in({1})',implode(',',$couponIds),implode(',',$couponStoreIds));
        $couponDao = \DAO\Coupon\CouponModel::getInstance();
        $couponList = $couponDao->getCartCouponTitles($couponSql);
        if(!$couponList){
            $storeCartData['couponList'] = array();
            return $storeCartData;
        }
        $storeCouponList = array();
        foreach($couponList as $temp){
            $storeCouponList[$temp['store_id']][] = $temp;
        }
        //echo json_encode($storeCartData);
        $platformCouponList = isset($storeCouponList[\Our\ApiConst::zero])?$storeCouponList[\Our\ApiConst::zero]:array();//平台优惠券列表
        foreach($storeCartData['cartList']  as $key=>$tempStoreCarts){
            if($platformCouponList){
                $tempStoreCarts = $this->calcCouponMoney($platformCouponList,$tempStoreCarts);
            }
            if(isset($storeCouponList[$key])){
                $tempStoreCarts =  $this->calcCouponMoney($storeCouponList[$key],$tempStoreCarts);
            }
            //echo json_encode($tempStoreCarts);
            $storeCartData['cartList'][$key]= $tempStoreCarts;
        }
        /**
         * 计算优惠券可以减免的金额
         */
        return $storeCartData;

    }

    /**
     * 计算每个优惠券对店铺订单而言优惠券的金额
     * @param $tempCoupon
     * @param $storeCarts
     */
    public function calcCouponMoney($tempCoupons,$storeCarts){
        $couponDao = \DAO\Coupon\CouponModel::getInstance();
        $couponList = array();
        foreach($tempCoupons as $tempCoupon){
            $tempCoupon['cash_money'] = $tempCoupon['cash_money']*\Our\ApiConst::hundred;
            $tempCoupon['order_amount'] = $tempCoupon['order_amount']*\Our\ApiConst::hundred;
            $reliefAmount = $this->getOneCouponReliefAmount($tempCoupon,$storeCarts);
            if($reliefAmount!==false){
                $coupon['couponId'] = $tempCoupon['couponId'];
                $coupon['title'] = $tempCoupon['title'];
                $coupon['reliefAmount'] = $reliefAmount;
                $coupon['chooseFlag'] = \Our\ApiConst::zero;
                $couponList[] = $coupon;
            }
        }
        if($couponList){
            if(isset($storeCarts['coupons'])){
                $storeCarts['coupons'] = array_merge($storeCarts['coupons'],$couponList);
            }else{
                $storeCarts['coupons'] = $couponList;
            }
            array_multisort(array_column($storeCarts['coupons'],'reliefAmount'),SORT_DESC,$storeCarts['coupons']);//按照优惠力度倒序排序
        }else{
            $storeCarts['coupons'] = array();
        }
        return $storeCarts;

    }

    public function getOneCouponReliefAmount($tempCoupon,$storeCarts){
        $couponDao = \DAO\Coupon\CouponModel::getInstance();
        if($tempCoupon['coupon_type'] == \Our\ApiConst::fullForGiftCouponType) {//满额赠礼品
            $reliefAmount = $couponDao->calcGiftCouponReliefAmount($tempCoupon, $storeCarts['storeCarts']);
            if ($reliefAmount === false) {
                return false;
            }
        }else{
            if($tempCoupon['type'] == \Our\ApiConst::noLimitCoupon){//无门槛优惠券
                $reliefAmount =  $tempCoupon['cash_money'];
            }else if($tempCoupon['type'] == \Our\ApiConst::goodsClassCoupon){//指定品类券
                $reliefAmountReturn  = $couponDao->calcCouponMinusMoney($tempCoupon,$storeCarts['gcPrices'],$storeCarts['storeCarts']);
                if($reliefAmountReturn === \Our\ApiConst::zero||$reliefAmountReturn>\Our\ApiConst::zero ){
                    $reliefAmount = $reliefAmountReturn;
                }
            }else if($tempCoupon['type'] == \Our\ApiConst::goodsCoupon){//指定商品优惠券
                $reliefAmountReturn  = $couponDao->calcCouponMinusMoney($tempCoupon,$storeCarts['goodsCommonPrices'],$storeCarts['storeCarts']);
                if($reliefAmountReturn === \Our\ApiConst::zero||$reliefAmountReturn>\Our\ApiConst::zero ){
                    $reliefAmount = $reliefAmountReturn;
                }
            }else if($tempCoupon['type'] == \Our\ApiConst::commonCoupon){
                $reliefAmountReturn  = $couponDao->calcCouponMinusMoneyByOrderAmount($tempCoupon,$storeCarts['storeCouponPrice'],$storeCarts['storeCarts']);
                if($reliefAmountReturn === \Our\ApiConst::zero||$reliefAmountReturn>\Our\ApiConst::zero ){
                    $reliefAmount = $reliefAmountReturn;
                }
            }
        }
        if(isset($reliefAmount)){
            return $reliefAmount;
        }
        return false;
    }

    public function getFormatCartListForOrder($storeCartData,$address){
        $storeCartsList = $storeCartData['cartList'];
        $choosedCouponIds = array();
        $returnData = array();
        $totalPrice = \Our\ApiConst::zero;
        foreach($storeCartsList as $key=>$storeCarts){
            $newStoreData = array();
            $storeCouponMinusMoney = \Our\ApiConst::zero; //店铺优惠券减免金额
            $shippingFee = \Our\ApiConst::zero; //默认配送费
            $storeSumData= array();//店铺汇总信息;
            //第一步获取选中优惠券
            if(isset($storeCarts['coupons'])&&count($storeCarts['coupons'])>0){
                foreach($storeCarts['coupons'] as $keyCoupon=>$coupon){
                    if($choosedCouponIds&&in_array($coupon['couponId'],$choosedCouponIds)){
                        continue;
                    }else{
                        $storeCarts['coupons'][$keyCoupon]['chooseFlag'] = \Our\ApiConst::one;
                        $storeCouponMinusMoney = $coupon['reliefAmount'];
                        $choosedCouponIds[] = $coupon['couponId'];
                        break;
                    }
                }
                $newStoreData['coupons'] = $storeCarts['coupons'];
            }else{
                $newStoreData['coupons'] = array();
            }
            //获取默认配送方式 快递默认优先级:商家配送大于快递订单大于买家自提
            $deliverySetting = $storeCarts['deliverySetting'];
            $deliverySettings = array();
            if($deliverySetting['sellerDistribution']==\Our\ApiConst::one&&$deliverySetting['deliverTimeList']){
                $deliveryTimes = $deliverySetting['deliverTimeList'];
                $delivery = array();
                array_multisort(array_column($deliverySetting['deliverTimeList'],'isDefault'),SORT_DESC,$deliverySetting['deliverTimeList']);
                $tempDeliverTimeList = $deliverySetting['deliverTimeList'];
                $delivery['name'] = \Our\DescribeConst::deliveryNameStore;
                $delivery['type'] = \Our\ApiConst::deliveryStore;
                $deliveryFee = $tempDeliverTimeList[0]['price'];
                $shippingFee = $deliveryFee;
                $delivery['isChoosed'] = \Our\ApiConst::one;
                $delivery['deliveryFee'] = $deliveryFee;
                $delivery['timeList'] = $deliveryTimes;
                $deliverySettings[]= $delivery;
                $storeSumData['deliveryFee'] = $deliveryFee;
            }
            if($deliverySetting['expressDistribution']==\Our\ApiConst::one){
                $deliveryFee = $deliverySetting['shippingFee'];
                $delivery = array();
                $delivery['name'] = \Our\DescribeConst::deliveryNameExpress;
                $delivery['type'] = \Our\ApiConst::deliveryExpress;
                if(isset($shippingFee)){
                    $delivery['isChoosed'] = \Our\ApiConst::zero;
                }else{
                    $shippingFee = $deliveryFee;
                    $delivery['isChoosed'] = \Our\ApiConst::one;
                    $storeSumData['deliveryFee'] = $deliveryFee;
                }
                $delivery['deliveryFee'] = $deliveryFee;
                $deliverySettings[]= $delivery;
            }
            if($deliverySetting['buyerDistribution']==\Our\ApiConst::one){
                $deliveryFee = \Our\ApiConst::zero;//到店自提
                $delivery = array();
                $delivery['name'] = \Our\DescribeConst::deliveryNameBuyer;
                $delivery['type'] = \Our\ApiConst::deliveryBuyer;
                if(isset($shippingFee)){
                    $delivery['isChoosed'] = \Our\ApiConst::zero;
                }else{
                    $shippingFee = $deliveryFee;
                    $delivery['isChoosed'] = \Our\ApiConst::one;
                    $storeSumData['deliveryFee'] = $deliveryFee;
                }
                $delivery['deliveryFee'] = $deliveryFee;
                $deliverySettings[]= $delivery;
            }
            $newStoreData['deliverys']=$deliverySettings;
            /*if(!isset($shippingFee)){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNoDeliveryTypeForBuy);
            }*/
            $storeCarts['deliverys'] = $deliverySettings;
            //获取支付方式 优先级:线上支付大于线下支付大于货到付款
            $payways = array();
            $paywayFlag = \Our\ApiConst::zero;
            if($deliverySetting['onelinePay']==\Our\ApiConst::one){
                $payway = array();
                $payway['name'] = \Our\DescribeConst::payOnlineName;
                $payway['type'] = \Our\ApiConst::payOnline;
                $paywayFlag= \Our\ApiConst::one;
                $payway['isChoosed'] =  \Our\ApiConst::one;
                $payways[] =$payway;
                $storeSumData['paywayName'] = $payway['name'];
            }
            if($deliverySetting['offlinePay']==\Our\ApiConst::one){
                $payway = array();
                $payway['name'] = \Our\DescribeConst::payOfflineName;
                $payway['type'] = \Our\ApiConst::payOffline;
                $payway['offlinePayway'] = $deliverySetting['offlinePayway']?$deliverySetting['offlinePayway']:\Our\NameConst::emptyString;//线下支付方式内容
                if($paywayFlag== \Our\ApiConst::zero){
                    $paywayFlag= \Our\ApiConst::one;
                    $payway['isChoosed'] =  \Our\ApiConst::one;
                    $storeSumData['paywayName'] = $payway['name'];
                    $storeSumData['paywayMemo'] = $payway['offlinePayway'];//支付方式备注
                }else{
                    $payway['isChoosed'] =  \Our\ApiConst::zero;
                }
                $payways[] =$payway;
            }
            if($deliverySetting['aogPay']==\Our\ApiConst::one){
                $payway = array();
                $payway['name'] = \Our\DescribeConst::payAogName;
                $payway['type'] = \Our\ApiConst::payAog;
                if($paywayFlag== \Our\ApiConst::zero){
                    $paywayFlag= \Our\ApiConst::one;
                    $payway['isChoosed'] =  \Our\ApiConst::one;
                    $storeSumData['paywayName'] = $payway['name'];
                }else{
                    $payway['isChoosed'] =  \Our\ApiConst::zero;
                }
                $payways[] =$payway;
            }
            /*if($paywayFlag == \Our\ApiConst::zero){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNoPaywayForBuy);
            }*/
            $storeSumData['reliefAmount'] = $storeCouponMinusMoney;//优惠券减免金额
            $storeSumData['storeName'] = $storeCarts['storeName'];

            $storeSumData['storeGoodsPrice'] = $storeCarts['storeTotalPrice'];
            $storeTotalPrice = $storeCarts['storeTotalPrice']- $storeCouponMinusMoney + $shippingFee;
            if($storeTotalPrice<\Our\ApiConst::zero){
                $storeTotalPrice = \Our\ApiConst::zero;
            }
            $storeSumData['totalPrice'] = $storeTotalPrice;

            $newStoreData['payways'] = $payways;//支付方式
            $newStoreData['storeCarts'] = $storeCarts['storeCarts'];//店铺商品
            $newStoreData['storeId'] = $storeCarts['storeId'];
            $newStoreData['storeName'] = $storeCarts['storeName'];
            $newStoreData['totalPrice'] = $storeTotalPrice;
            $newStoreData['totalGoodsNum'] = $storeCarts['totalGoodsNum'];
            $newStoreData['storeGoodsPrice']= $storeCarts['storeTotalPrice'];
            $totalPrice += $storeTotalPrice;
            $returnData['stores'][]=$newStoreData;
            $returnData['sum'][] = $storeSumData;
        }
        $returnData['totalPrice'] = $totalPrice;

        $returnData['address'] = new \stdClass();
        if($address){
            unset($address['lat']);
            unset($address['lng']);
            unset($address['city_id']);
            $returnData['address'] = $address;
        }
        return $returnData;
    }


    function addOrder($data,$memberId,$currentAddress){
        $orderUtil =\Order\OrderConfirmUtil::getInstance();
        $return = $orderUtil->addOrder($data,$memberId,$currentAddress);
        //删除订单列表缓存
        $orderDao=\DAO\Order\OrderModel::getInstance();
        $orderDao->deleteOrderCache($memberId);

        return $return;
    }




    private static $_instance = null;

    /**
     * 单例模式获取类实例
     *
     */
    public static function getInstance() {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}