/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title:
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: ping.wu
 * @date: 2018/5/18 19:46
 * @version V1.0
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
package cn.freemud.service.impl;

import cn.freemud.adapter.ActivityAdapter;
import cn.freemud.adapter.CouponAdapter;
import cn.freemud.adapter.ShoppingCartConvertAdapter;
import cn.freemud.base.constant.Version;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.CustomerScoreConstant;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.activity.ActivityQueryResponseDto;
import cn.freemud.entities.dto.calculate.CalculationSharingDiscountRequestDto;
import cn.freemud.entities.dto.calculate.CalculationSharingDiscountResponseDto;
import cn.freemud.entities.dto.openplatform.WeixinProductRequestDto;
import cn.freemud.entities.dto.openplatform.WeixinProductResponseDto;
import cn.freemud.entities.dto.shoppingCart.SendPoint;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.dto.user.GetSessionUserInfoDto;
import cn.freemud.entities.dto.user.GetUserScoreUseDetailRequest;
import cn.freemud.entities.dto.user.GetUserScoreUserDetailResponse;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.interceptor.BizServiceException;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.*;
import cn.freemud.service.delivery.DeliveryFactory;
import cn.freemud.service.delivery.DeliveryService;
import cn.freemud.service.impl.calculate.*;
import cn.freemud.service.shoppingCart.ShoppingCartRelationFactory;
import cn.freemud.service.shoppingCart.ShoppingCartRelationService;
import cn.freemud.service.thirdparty.*;
import cn.freemud.utils.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartnerStoreDeliveryConfig;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerStoreDeliveryConfigManager;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.constant.FMStatusCode;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.GetMemberByMobileRequest;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.request.StatisticalPropertyRequest;
import com.freemud.application.sdk.api.membercenter.request.StatisticalScoreRequest;
import com.freemud.application.sdk.api.membercenter.response.GetMemberByMobileResponse;
import com.freemud.application.sdk.api.membercenter.response.GetSvcInfoByMemberIdResponse;
import com.freemud.application.sdk.api.membercenter.response.QueryReceiveAddressResponse;
import com.freemud.application.sdk.api.membercenter.response.StatisticalScoreResponse;
import com.freemud.application.sdk.api.membercenter.service.MemberCenterService;
import com.freemud.application.sdk.api.membercenter.service.MemberPropertyService;
import com.freemud.application.sdk.api.paymentcenter.client.request.SVCCardAmountRequest;
import com.freemud.application.sdk.api.paymentcenter.client.response.SVCCardAmountResponse;
import com.freemud.application.sdk.api.paymentcenter.client.service.PaymentNewService;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.application.sdk.api.storecenter.request.StoreInfoRequest;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import com.freemud.sdk.api.assortment.shoppingcart.request.CheckCartRequest;
import com.freemud.sdk.api.assortment.shoppingcart.service.ShoppingCartBaseService;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.freemud.constant.ApplicationConstant.*;
import static cn.freemud.constant.ShoppingCartConstant.SHOPPING_CART_EMPTY_GOODS_LIST;
import static cn.freemud.constant.ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS;
import static java.util.stream.Collectors.toList;

@Slf4j
@Service
public class ShoppingCartNewServiceImpl implements ShoppingCartNewService {

    // 配送费逻辑是否使用旧的
    @Value("${store.delivery.use.old:true}")
    private boolean storeDeliveryUseOld;

    @Autowired
    private ActivityAdapter activityAdapter;
    @Autowired
    private StoreItemClient storeItemClient;
    @Autowired
    private ActivityClient activityClient;
    @Autowired
    private ItemService itemService;
    @Autowired
    private ShoppingCartNewBaseService shoppingCartNewBaseService;
    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private ShoppingCartConvertAdapter shoppingCartConvertAdapter;
    @Autowired
    private FullSubtractionActivityServiceImpl fullSubtractionActivityService;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private OpenPlatformClient openPlatformClient;
    @Autowired
    private StockClient stockClient;
    @Value("${goods.cache.second}")
    private long goodsCacheSeconds;
    @Autowired
    private AssortmentSdkService assortmentSdkService;
    @Autowired
    private CouponAdapter couponAdapter;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private PaymentNewService paymentNewService;
    @Autowired
    private MemberCenterService memberCenterService;
    @Autowired
    private AssortmentOpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    @Autowired
    private StoreServiceImpl storeService;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SvcComPayClient svcComPayClient;

    @Autowired
    private DeliveryFactory deliveryFactory;

    private static final String limitCartKey = "ecology:kgd:wxappconfig:open_platform_partner_wxapp_config:appkey_";


    @Autowired
    private CalculationSharingDiscountService sharingDiscountService;
    @Autowired
    private CalculationSharingCartService sharingCartService;
    @Autowired
    private CalculationSharingEquallyService sharingEquallyService;

    @Autowired
    private CalculationSharingValidatorService calculationSharingValidatorService;

    @Autowired
    private CustomerExtendClient customerExtendClient;

    @Autowired
    private MemberPropertyService memberPropertyService;

    @Autowired
    private CustomScoreClient customScoreClient;

    @Value("${saas.cart.sharing}")
    private String sharing;

    @Autowired
    private ShoppingCartRelationFactory shoppingCartRelationFactory;




    /**
     * 从微信卡券向购物车中添加商品
     */
    @Override
    public BaseResponse addGoodsByCard(AddGoodsByWeixinCardRequestVo request) {
        if (CouponTypeEnum.TYPE_0.getCode().equals(request.getCouponType())) {
            // 调用B端接口，获得商品券对应商品skuId并且解码code
            WeixinProductRequestDto requestDto = shoppingCartConvertAdapter.convent2WeixinProductRequestDto(request);
            WeixinProductResponseDto productRequestDto = openPlatformClient.getWeixinProductRequestDto(requestDto);
            if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(productRequestDto.getCode())) {
                return ResponseUtil.error(productRequestDto.getCode(), productRequestDto.getMessage());
            }
            WeixinProductResponseDto.WxProductResponse result = productRequestDto.getResult();
            request.setSkuId(result.getSkuId());
            request.setEncryptCode(CommonsConstant.COUPON_PREFIX + result.getCode());

            // 根据skuId获取详情
            Map<String, GetProductsVo> products = itemService.getProducts(Arrays.asList(request.getSkuId()), request.getPartnerId(), request.getShopId(),BusinessTypeEnum.getByType(request.getMenuType()).getCode());
            if (products == null || products.size() == 0) {
                return ResponseUtil.error(ResponseResult.WEICHAT_PRODUCT_NOEXIST);
            }
            GetProductsVo getProductsVo = products.get(request.getSkuId());

            // 根据spu查询菜单（必须在当前菜单下才可以加入购物车）
            GetMenuCategoryByIdsDto getMenuCategoryByIdsDto = GetMenuCategoryByIdsDto.builder()
                    .businessDate(DateUtil.convert2String(new Date(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS))
                    .channelType(BusinessTypeEnum.getByType(request.getMenuType()).getCode())
                    .partnerId(request.getPartnerId())
                    .shopId(request.getShopId())
                    .productIds(Arrays.asList(getProductsVo.getSpuId())).build();
            GetMenuByIdsResponseDto getMenuByIdsResponseDto = storeItemClient.getMenuCategoryByIds(getMenuCategoryByIdsDto);
            List<GetMenuByIdsResponseDto.DataBean.MenuDetailDto> menuDetailDtos = null;
            if (Objects.equals(getMenuByIdsResponseDto.getErrcode(), Integer.valueOf(ResponseResult.SUCCESS.getCode()))) {
                if (Objects.equals(getMenuByIdsResponseDto.getData(), null)) {
                    return ResponseUtil.error(ResponseResult.WEICHAT_SHOP_NOTSUPPORT.getCode(), "您当前" + result.getTitle() + "商品券在本门店不支持");
                }
                menuDetailDtos = getMenuByIdsResponseDto.getData().getMenuDetailDtos();
            }
            if (CollectionUtils.isEmpty(menuDetailDtos)) {
                return ResponseUtil.error(ResponseResult.WEICHAT_SHOP_NOTSUPPORT.getCode(), "您当前" + result.getTitle() + "商品券在本门店不支持");
            }

            // 判断商品状态是否可以加入购物车
            List<ProductBeanDTO> productInfos = assortmentSdkService.getProductsInfoSdk(request.getPartnerId(), request.getShopId(), Arrays.asList(getProductsVo.getSpuId()),request.getMenuType(),this.shoppingCartBaseService);
            if (CollectionUtils.isNotEmpty(productInfos)) {
                ProductBeanDTO productBean = productInfos.get(0);
                Integer status = productBean.getStatus();
                if (status == 1) {
                    return ResponseUtil.error(ResponseResult.WEICHAT_SHOP_NOTSUPPORT.getCode(), "您当前" + result.getTitle() + "商品券在本门店不支持");
                }
            }

            AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo = shoppingCartConvertAdapter.convent2AddshoppingCartGoods(request, getProductsVo);
            //LogUtil.info("addGoodsByCard shoppingCartAdapter.convent2AddshoppingCartGoods****", JSONObject.toJSONString(addShoppingCartGoodsRequestVo), null);
            BaseResponse baseResponse = addGoods(addShoppingCartGoodsRequestVo);

            return baseResponse;
        } else {
            return ResponseUtil.success(ResponseResult.WEICHAT_NOT_PRODUCTCARD);
        }
    }

    /**
     * 添加商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @return
     */
    @Override
    public BaseResponse addGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo) {
        if (StringUtils.isEmpty(addShoppingCartGoodsRequestVo.getShopId())){
            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }
        ShoppingCartConvertAdapter.convent2SkuId(addShoppingCartGoodsRequestVo);
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(addShoppingCartGoodsRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = addShoppingCartGoodsRequestVo.getPartnerId();
        String storeId = addShoppingCartGoodsRequestVo.getShopId();
        String appId = addShoppingCartGoodsRequestVo.getAppId();
        String spuId = addShoppingCartGoodsRequestVo.getSpuId();
        String skuId = addShoppingCartGoodsRequestVo.getSkuId();
        String goodsId = StringUtils.isEmpty(skuId) ? spuId : skuId;
        String menuType = addShoppingCartGoodsRequestVo.getMenuType();
        Integer orderType = addShoppingCartGoodsRequestVo.getOrderType();
        String receiveId = addShoppingCartGoodsRequestVo.getReceiveId();
        String tableNumber = addShoppingCartGoodsRequestVo.getTableNumber();
        String couponCode = addShoppingCartGoodsRequestVo.getCouponCode(); // 商品券和换购券券号

        CartGoods cartGoods = ShoppingCartConvertAdapter.convent2CartGoods(addShoppingCartGoodsRequestVo);
        List<Long> productIds = new ArrayList<>();
        //商品skuId或者商品券的商品id
        String spuId2 = spuId;
        CouponProductDto couponProductDto = new CouponProductDto();
        if (StringUtils.isBlank(couponCode)) {
            productIds.add(Long.parseLong(goodsId));
        } else {
            //校验券是否有效  这里是新的商品券支持多商品及换购券
            if (StringUtils.isNotBlank(skuId)) {
                spuId2 = validCoupon(partnerId, storeId, couponCode, productIds, BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode(), skuId, couponProductDto);
                cartGoods.setGoodsId(spuId);
            } else {
                // 老版本商品券
                spuId2 = validCoupon(partnerId, storeId, couponCode, productIds, BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode(), couponProductDto);
            }
        }
        // 获取商品详细信息
        List<ProductBeanDTO> productBeanListSpuClass = assortmentSdkService.getProductsInfoSdk(partnerId, storeId
                , Collections.singletonList(spuId2),addShoppingCartGoodsRequestVo.getMenuType(), this.shoppingCartBaseService);
        LogUtil.info("productBeanListSpuClass", spuId2,JSON.toJSONString(productBeanListSpuClass));

        //缓存中获取购物车商品信息
        // 注意，围餐和点餐redis数据结构不一样
        List<CartGoods> allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, addShoppingCartGoodsRequestVo.getSessionId(), null, shoppingCartBaseService);
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            allCartGoodsList = new ArrayList<>();
        }
        List<CartGoods> oldCartGoodsList = BeanUtil.convertBeans(allCartGoodsList, CartGoods::new);
        /**
         Integer checkQty = allCartGoodsList.indexOf(cartGoods) != -1 ?
         allCartGoodsList.get(allCartGoodsList.indexOf(cartGoods)).getQty() + cartGoods.getQty() : cartGoods.getQty();
         */
        Integer checkQty = this.checkSkuQty(allCartGoodsList, cartGoods);
        //购物车添加数量限制
        Integer productsCount = limitGoodsQty(allCartGoodsList,cartGoods,appId);
        //查询多个商品库存信息 TODO
        queryManyGoodsStocks(addShoppingCartGoodsRequestVo, productIds, productBeanListSpuClass, skuId, checkQty);
        String productName = null;
        // 当添加的商品不是商品券时
        if (StringUtils.isBlank(couponCode)) {
            //添加非商品券商品
            addNotProductGoods(addShoppingCartGoodsRequestVo, cartGoods, goodsId, userId, shoppingCartGoodsResponseVo, allCartGoodsList);
        } else {
            // 当商品是商品券，里面会判断如果购物车中已有商品券，会将cartGoods的CartGoodsUid设为null
            this.addProductGoods(addShoppingCartGoodsRequestVo, cartGoods, spuId2, userId, shoppingCartGoodsResponseVo,
                    spuId, allCartGoodsList, productBeanListSpuClass, couponProductDto, couponCode);
        }
        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo,addShoppingCartGoodsRequestVo.getOrderType());

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, addShoppingCartGoodsRequestVo.getOrderType());
        if (grayPush(partnerId,storeId,"2")) {
            CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult = null;
            discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , allCartGoodsList
                    , new ArrayList<>() //券
                    , null //加价购商品
                    , deliveryAmount
                    , null);

            //
            sharingCartService.distribute(discountResult
                    , allCartGoodsList
                    , shoppingCartGoodsResponseVo
                    , null
                    , null
                    , null
                    , activityQueryDto
                    , menuType
                    , deliveryAmount
                    , ShoppingCartConstant.ADD_AND_UPDATE
                    , partnerId
                    , null);

            buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,discountResult,null,partnerId);
        }
        else {
            // 获取优惠信息
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
                    = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId, userLoginInfoDto.getWxAppid(), orderType, assortmentCustomerInfoVo.isMemberPaid(), allCartGoodsList, new ArrayList(), new ArrayList<>(), null, deliveryAmount);
            if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getSendGoods())) {
                sendGoodsQtyCheck(productsCount, appId, partnerId, userId, storeId, tableNumber, oldCartGoodsList, shoppingCartBaseService, calculationDiscountResult.getSendGoods());
            }
            // 当商品数量被设为0时
            if (Objects.equals(cartGoods.getQty(), 0)) {
                assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoods.getCartGoodsUid(), 0, "", shoppingCartBaseService);
            }
            // 促销活动的优惠金额计算
            updateShoppingCartGoodsDiscount(null, activityQueryDto, calculationDiscountResult, allCartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto, addShoppingCartGoodsRequestVo.getMenuType(), deliveryAmount);
            clearMsg(shoppingCartGoodsResponseVo, cartGoods.getCartGoodsUid());
            //设置更新响应信息
            setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, allCartGoodsList, null, partnerId, storeId, userId, ShoppingCartConstant.ADD_AND_UPDATE, null);

        }
        //埋点添加购物车行为
        this.buriedPointShoppingCart(addShoppingCartGoodsRequestVo, spuId, productName);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }


    /**
     * 埋点添加购物车行为
     *
     * @param addShoppingCartGoodsRequestVo
     * @param spuId
     * @param productName
     */
    private void buriedPointShoppingCart(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, String spuId, String productName) {
        if (StringUtils.isEmpty(productName)) {
            return;
        }

        List<ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo> productVos = Lists.newArrayList();
        ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo productVo = new ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo();
        productVo.setProductName(productName);
        productVo.setProductId(spuId);
        productVo.setSpuId(spuId);
        productVos.add(productVo);
        BuriedPointShoppingCartRequestDto shoppingCartRequestDto = BuriedPointShoppingCartRequestDto.builder()
                .sessionId(addShoppingCartGoodsRequestVo.getSessionId()).partnerId(addShoppingCartGoodsRequestVo.getPartnerId())
                .storeId(addShoppingCartGoodsRequestVo.getShopId()).build();
        buriedPointService.buriedPointAddShoppingCart(productVos, shoppingCartRequestDto);
    }

    /**
     * 更新商品数量
     *
     * @param updateShoppingCartGoodsQtyRequestVo
     * @return
     */
    @Override
    public BaseResponse updateGoodsQty(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo) {
        if (StringUtils.isEmpty(updateShoppingCartGoodsQtyRequestVo.getShopId())){
            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(updateShoppingCartGoodsQtyRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String storeId = updateShoppingCartGoodsQtyRequestVo.getShopId();
        String appId = updateShoppingCartGoodsQtyRequestVo.getAppId();
        String cartGoodsUid = updateShoppingCartGoodsQtyRequestVo.getCartGoodsUid();
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        String menuType = updateShoppingCartGoodsQtyRequestVo.getMenuType();
        Integer orderType=updateShoppingCartGoodsQtyRequestVo.getOrderType();
        String receiveId = updateShoppingCartGoodsQtyRequestVo.getReceiveId();

        // 先验证商品是否存在
        CartGoods cartGoods = assortmentSdkService.getCartGoodsBySdk(partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService);
        if (cartGoods == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
        }
        // 检查购物车商品库存数量
        checkUpdateStock(updateShoppingCartGoodsQtyRequestVo, cartGoods);
        Integer oldQty = cartGoods.getQty();
        // 更新购物车中数量
        List<CartGoods> cartGoodsList = assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoodsUid, qty<0?0:qty, "", shoppingCartBaseService);

        // check购物车中所有商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, updateShoppingCartGoodsQtyRequestVo.getOrderType(), "", updateShoppingCartGoodsQtyRequestVo.getMenuType(), shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, updateShoppingCartGoodsQtyRequestVo.getSessionId(), "", shoppingCartBaseService);
        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo,updateShoppingCartGoodsQtyRequestVo.getOrderType());

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, updateShoppingCartGoodsQtyRequestVo.getOrderType());
        if (grayPush(partnerId,storeId,"2")) {
            CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult = null;
            discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , new ArrayList() //券
                    , null //加价购商品
                    , deliveryAmount
                    , null);

            sharingCartService.distribute(discountResult
                    , cartGoodsList
                    , shoppingCartGoodsResponseVo
                    , null //入参
                    , userLoginInfoDto
                    , null //券信息
                    , activityQueryDto
                    , menuType
                    , deliveryAmount
                    , ShoppingCartConstant.ADD_AND_UPDATE
                    , partnerId
                    , null);

            buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,discountResult,null,partnerId);
        }
        else {
            // 获取优惠信息
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
                    = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId, userLoginInfoDto.getWxAppid(), orderType, assortmentCustomerInfoVo.isMemberPaid(), cartGoodsList, new ArrayList(), new ArrayList<>(), null, deliveryAmount);
            if (calculationDiscountResult == null) {
                shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
            }
            if (calculationDiscountResult != null) {
                sendGoodsQtyCheckForUpdate(cartGoodsList, oldQty, appId, partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService, calculationDiscountResult.getSendGoods());
            }
            // 促销活动的优惠金额计算
            updateShoppingCartGoodsDiscount(null, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto, updateShoppingCartGoodsQtyRequestVo.getMenuType(), deliveryAmount);
            clearMsg(shoppingCartGoodsResponseVo, cartGoodsUid);
            //设置更新响应信息
            setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, userId, ShoppingCartConstant.ADD_AND_UPDATE, null);

        }

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 检查购物车商品库存数量
     *
     * @param updateShoppingCartGoodsQtyRequestVo
     * @param cartGoods
     */
    private void checkUpdateStock(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo, CartGoods cartGoods) {
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        // 购物车商品数量减少
        if (cartGoods.getQty() > qty) {
            return;
        }
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String storeId = updateShoppingCartGoodsQtyRequestVo.getShopId();
        //查询商品信息
        List<String> pids = new ArrayList<>();
        pids.add(cartGoods.getGoodsId());
        Map<String, GetProductsVo> products = itemService.getProducts(pids, partnerId, storeId, BusinessTypeEnum.getByType(updateShoppingCartGoodsQtyRequestVo.getMenuType()).getCode());

        GetProductsVo getProductsVo = products.get(cartGoods.getGoodsId());
        // 商品没有库存限制
        if (getProductsVo == null || getProductsVo.getStockLimit() != 1) {
            return;
        }

        ShoppingCartConvertAdapter.setClassification(cartGoods, getProductsVo);
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.getByType(updateShoppingCartGoodsQtyRequestVo.getMenuType()).getCode());
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        requestDto.setProductIds(Collections.singletonList(Long.parseLong(cartGoods.getGoodsId())));
        GetProductStockResponseDto availableStocks = stockClient.getAvailableStocks(requestDto);
        if ((availableStocks != null) && (ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode()))) {
            if ((CollectionUtils.isEmpty(availableStocks.getResult())) || (availableStocks.getResult().get(0).getQty() != null &&
                    qty > availableStocks.getResult().get(0).getQty())) {
                Integer stock = 0;
                if (!CollectionUtils.isEmpty(availableStocks.getResult()) && (stock = availableStocks.getResult().get(0).getQty()) > 0) {
                    throw new BizServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE, "仅剩" + stock + "件库存了");
                }
                throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
            }
        }
    }


    /**
     * 购物车商品详情接口
     *
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsList(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (StringUtils.isEmpty(shoppingCartInfoRequestVo.getShopId())){
            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        String appId = shoppingCartInfoRequestVo.getAppId();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        String menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        String receiveId = shoppingCartInfoRequestVo.getReceiveId();

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService);
        // 如果购物车商品不为空， 则check购物车中所有商品
        if (CollectionUtils.isNotEmpty(cartGoodsList)){
            CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType(), "", shoppingCartInfoRequestVo.getMenuType() ,shoppingCartBaseService);
            if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
                shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
                shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
            }
            cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
            // 重新存储最新购物车
            assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService);
        }

        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo,shoppingCartInfoRequestVo.getOrderType());

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartInfoRequestVo.getOrderType());
        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);
        if (grayPush(partnerId,storeId,"2")) {
            ArrayList<CalculationSharingDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            if (StringUtils.isNotEmpty(couponCode)) {
                CalculationSharingDiscountRequestDto.CalculationDiscountCoupon coupon = new CalculationSharingDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(couponCode);
                coupon.setActivityCode(activityCode);
                coupons.add(coupon);
            }

            buildCoupons(coupons,shoppingCartInfoRequestVo.getCouponCodes());

            List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList = shoppingCartInfoRequestVo.getSendGoods();
            List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(sendGoodsList)) {
                for (ShoppingCartInfoRequestVo.SendGoods sds : sendGoodsList) {
                    ShoppingCartInfoRequestVo.SendGoods sd = new ShoppingCartInfoRequestVo.SendGoods();
                    sd.setGoodsId(sds.getGoodsId());
                    if (StringUtils.isBlank(sds.getActivityCode())) continue;
                    sd.setQty(sds.getQty());
                    sd.setOriginalPrice(0L);
                    sd.setActivityCode(sds.getActivityCode());
                    sendGoods.add(sd);
                }
            }
            CalculationSharingDiscountResponseDto.CalculationDiscountResult calculationSharingDiscountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , coupons
                    , sendGoods
                    , deliveryAmount
                    , null);
            sharingCartService.distribute(calculationSharingDiscountResult
                    , cartGoodsList
                    , shoppingCartGoodsResponseVo
                    , shoppingCartInfoRequestVo
                    , userLoginInfoDto
                    , couponPromotionVO
                    , activityQueryDto
                    , menuType
                    , deliveryAmount
                    , ShoppingCartConstant.QUERY_INFO
                    , partnerId
                    ,shoppingCartInfoRequestVo.getFlag());

            buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,calculationSharingDiscountResult,shoppingCartInfoRequestVo.getFlag(),partnerId);
        }
        else {
            List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            // 当couponCode不为空时，需参与价格计算
            if (StringUtils.isNotEmpty(couponCode)) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(couponCode);
                coupon.setActivityCode(activityCode);
                coupons.add(coupon);
            }
            // 获取优惠信息
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType,partnerId,storeId,userId,appId,userLoginInfoDto.getWxAppid(),orderType,assortmentCustomerInfoVo.isMemberPaid(),cartGoodsList,coupons,null,shoppingCartInfoRequestVo.getReceiveId(),deliveryAmount);
            if (calculationDiscountResult == null) {
                shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
            }
            // 促销活动的优惠金额计算
            this.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto,shoppingCartInfoRequestVo.getMenuType(),deliveryAmount);
            //设置更新响应信息
            setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, userId, ShoppingCartConstant.QUERY_INFO, shoppingCartInfoRequestVo);
            // 在原价、现价、折扣价上增加第一次使用会员卡的费用
            this.addNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsResponseVo);

        }
        // 校验入参券是否可用
        if (!checkAvailableCoupon(shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getCouponCode())){
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_COUPON_NOT_USE);
        };

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * svc 卡支付使用
     *
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsListCheck(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (StringUtils.isBlank(shoppingCartInfoRequestVo.getCardCode())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING);
        }
        //打包带走外卖
        if (StringUtils.isNotBlank(shoppingCartInfoRequestVo.getCardCode()) && shoppingCartInfoRequestVo.getOrderType() == 2
                && StringUtils.isBlank(shoppingCartInfoRequestVo.getReceiveId())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING);
        }
        BaseResponse<ShoppingCartGoodsResponseVo> goodsList = getGoodsList(shoppingCartInfoRequestVo);
        if (goodsList == null || !ResponseResult.SUCCESS.getCode().equals(goodsList.getCode())) {
            return goodsList;
        }
        
        
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = goodsList.getResult();
        // 校验入参券是否可用
        if (!checkAvailableCoupon(shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getCouponCode())){
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_COUPON_NOT_USE);
        };
        
        //SVC卡支付
        SVCCardPay(shoppingCartInfoRequestVo.getCardCode(), shoppingCartInfoRequestVo.getReceiveId(), partnerId, storeId, shoppingCartGoodsResponseVo);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 清空购物车
     *
     * @param shoppingCartClearRequestVo
     * @return
     */
    @Override
    public BaseResponse clear(ShoppingCartClearRequestVo shoppingCartClearRequestVo) {

        String appId = shoppingCartClearRequestVo.getAppId();
        if (StringUtils.isBlank(appId)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING, "appId不能为空");
        }
        String userId = shoppingCartClearRequestVo.getUserId();
        if (StringUtils.isEmpty(userId)){
            CustomerInfoVo userLoginInfoDto =getCustomerInfoVo(shoppingCartClearRequestVo.getSessionId());
            userId=userLoginInfoDto.getMemberId();
        }
        String partnerId = shoppingCartClearRequestVo.getPartnerId();
        String storeId = shoppingCartClearRequestVo.getShopId();
        shoppingCartNewBaseService.clear(partnerId, storeId, userId);
        if (ObjectUtils.equals(shoppingCartClearRequestVo.getOperationType(), OperationTypeEnum.PAY_SUCCESS.getOperationType())) {
            return ResponseUtil.success();
        }

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartClearRequestVo.getOrderType());
        ArrayList<ActivityList> activityList = new ArrayList<>();
        PromotionMessageDto promotionMessageDto = fullSubtractionActivityService.getFullPromotionActivityInfo(activityQueryDto, null, activityList);

        ActivityTip activityTip = new ActivityTip();
        if (promotionMessageDto != null) {
            activityTip.setActivityCode(promotionMessageDto.getActivityId());
            activityTip.setActivityType(promotionMessageDto.getActivityType());
            activityTip.setActivityName(promotionMessageDto.getPromotionMessage());
            activityTip.setActivityList(activityList);
        }
        shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        shoppingCartGoodsResponseVo.setProducts(new ArrayList<>());
        shoppingCartGoodsResponseVo.setProductsCount(0);

        ShoppingCartRelationService shoppingCartRelationService = shoppingCartRelationFactory.cleanAfter(shoppingCartClearRequestVo.getPartnerId());
        shoppingCartRelationService.cleanAfter(shoppingCartGoodsResponseVo,shoppingCartClearRequestVo);

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    @Override
    public BaseResponse<ShoppingCartGoodsDto> getShoppingCartGoods(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo,
                                                                   CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {
        ShoppingCartGoodsDto shoppingCartGoodsDto = new ShoppingCartGoodsDto();
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        String appId = StringUtils.isEmpty(shoppingCartInfoRequestVo.getAppId())?userLoginInfoDto.getWxAppid():shoppingCartInfoRequestVo.getAppId();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        String tableNumber = assortmentCustomerInfoVo.getTableNumber();
        String menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        String receiveId = shoppingCartInfoRequestVo.getReceiveId();

        List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList = shoppingCartInfoRequestVo.getSendGoods();

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, tableNumber, shoppingCartBaseService);
        if (cartGoodsList == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        /**
         *  校验该名店是否有必选商品
         *  1. 调用商品服务拿到该门店是否有必选商品
         *  2. 如果有，则和购物车的商品对比
         */
        if (productService.hasRequiredProducts(partnerId, storeId, cartGoodsList,BusinessTypeEnum.getByType(shoppingCartInfoRequestVo.getMenuType()).getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_REQUIRED_PRODUCT_NOT_EXIST);
        }

        // check购物车中所有商品(商品是否存在，价格变动，券是否支持当前点餐方式)
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo,
                shoppingCartInfoRequestVo.getOrderType(), tableNumber, shoppingCartInfoRequestVo.getMenuType() ,shoppingCartBaseService);
        com.freemud.sdk.api.assortment.shoppingcart.domain.ShoppingCartGoodsResponseVo cartGoodsResponseVo = checkCartRequest.getShoppingCartGoodsResponseVo();
        // 校验商品券库存


        //商品不再售卖状态或价格变动，直接返回报错
        if (cartGoodsResponseVo != null) {
            if (cartGoodsResponseVo.getCartGoodsStates() != null && cartGoodsResponseVo.getCartGoodsStates().isHasInvalidGoods()) {
                return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
            }
            if (cartGoodsResponseVo.getCartGoodsStates() != null && cartGoodsResponseVo.getCartGoodsStates().isPriceChanged()) {
                return ResponseUtil.error(ResponseResult.SHOPPING_CART_ACTIVITY_CHANGE);
            }
            shoppingCartGoodsResponseVo.setToastMsg(cartGoodsResponseVo.getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
        // 多规格的sku商品计算包装费
        //this.checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), tableNumber, this.shoppingCartBaseService);

        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            processSendGoods(sendGoodsList, partnerId, storeId , shoppingCartInfoRequestVo.getMenuType() , shoppingCartBaseService);
        } else {
            //组装加价购商品
            if (null != premiumExchangeActivity && CollectionUtils.isNotEmpty(premiumExchangeActivity.getProducts())) {
                List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = premiumExchangeActivity.getProducts().stream().map(product -> {
                    ShoppingCartInfoRequestVo.SendGoods sendGood = new ShoppingCartInfoRequestVo.SendGoods();
                    sendGood.setGoodsId(product.getSkuId());
                    sendGood.setQty(product.getQty());
                    sendGood.setOriginalPrice(product.getOriginalPrice());
                    sendGood.setActivityCode(premiumExchangeActivity.getActivityCode());
                    return sendGood;
                }).collect(toList());
                shoppingCartInfoRequestVo.setSendGoods(sendGoods);
            }
        }
        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartInfoRequestVo.getOrderType());
        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);

        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo,shoppingCartInfoRequestVo.getOrderType());
        if (grayPush(partnerId,storeId,"2")) {
            List<CalculationSharingDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            // 当couponCode不为空时，需参与价格计算
            if (StringUtils.isNotEmpty(couponCode)) {
                CalculationSharingDiscountRequestDto.CalculationDiscountCoupon coupon = new CalculationSharingDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(couponCode);
                coupon.setActivityCode(activityCode);
                coupons.add(coupon);
            }
            // 当couponCodes不为空时，需参与价格计算,同时排除单券入参
            buildCoupons(coupons,shoppingCartInfoRequestVo.getCouponCodes());

            CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , coupons
                    , shoppingCartInfoRequestVo.getSendGoods()
                    , deliveryAmount
                    , shoppingCartInfoRequestVo);

            // 活动校验
            calculationSharingValidatorService.validator(discountResult
                    , cartGoodsList
                    , shoppingCartGoodsResponseVo
                    , shoppingCartInfoRequestVo
                    , userLoginInfoDto
                    , couponPromotionVO
                    , activityQueryDto
                    , menuType
                    , deliveryAmount
                    , ShoppingCartConstant.QUERY_INFO);

            //直接利用促销返回做均摊
            sharingEquallyService.equally(discountResult
                    , cartGoodsList
                    , shoppingCartGoodsResponseVo
                    , shoppingCartInfoRequestVo
                    , userLoginInfoDto
                    , couponPromotionVO
                    , activityQueryDto
                    , menuType
                    , deliveryAmount
                    , shoppingCartGoodsDto
                    , premiumExchangeActivity);
        }
        else {
            List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            // 当couponCode不为空时，需参与价格计算
            if (StringUtils.isNotEmpty(couponCode)) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(couponCode);
                coupon.setActivityCode(activityCode);
                coupons.add(coupon);
            }
            // 获取优惠信息
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType,partnerId,storeId,userId,appId,userLoginInfoDto.getWxAppid(),orderType,assortmentCustomerInfoVo.isMemberPaid(),cartGoodsList,coupons,sendGoodsList,shoppingCartInfoRequestVo.getReceiveId(),deliveryAmount);
            //临时方案
            packgeAdditional(shoppingCartInfoRequestVo, premiumExchangeActivity);
            // 促销活动的优惠金额计算
            updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto,shoppingCartInfoRequestVo.getMenuType(),deliveryAmount);

            //设置更新响应信息
            setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, userId, ShoppingCartConstant.QUERY_INFO, shoppingCartInfoRequestVo);
            //设置均摊信息
            updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

            getNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsDto);
            shoppingCartGoodsDto.setDeliveryAmount(shoppingCartGoodsResponseVo.getDeliveryAmount());
            shoppingCartGoodsDto.setDiscountDeliveryAmount(shoppingCartGoodsResponseVo.getDiscountDeliveryAmount());
            shoppingCartGoodsDto.setThresholdAmount(shoppingCartGoodsResponseVo.getThresholdAmount());
            shoppingCartGoodsDto.setIsDiscountDelivery(shoppingCartGoodsResponseVo.getIsDiscountDelivery());
            shoppingCartGoodsDto.setDiscountDeliveryActivityCode(shoppingCartGoodsResponseVo.getDiscountDeliveryActivityCode());
            if (calculationDiscountResult != null){
                shoppingCartGoodsDto.setSendPoint(calculationDiscountResult.getSendPointVo());
            }

        }
        return ResponseUtil.success(shoppingCartGoodsDto);
    }

    @Override
    public BaseResponse<GetMemberInfoResponseVo> getMemberInfo(GetMemberInfoRequestDto request) {

        GetMemberInfoResponseVo responseData = new GetMemberInfoResponseVo();

        String partnerId = request.getPartnerId();
        String memberId = request.getUserId();
        responseData.setUserId(memberId);
        List<GetMemberInfoRequestDto.OrderItemRequest> orderItemList = request.getOrderItemList();
        if (CollectionUtils.isEmpty(orderItemList)){
            // 优惠券
            GetMemberCouponListRequestDto getMemberCouponListRequestDto = new GetMemberCouponListRequestDto(partnerId, memberId);
            getMemberCouponListRequestDto.setStatusFlags(Arrays.asList(CouponStatus.STATUS_0.getCode()));
            getMemberCouponListRequestDto.setPageNum(1);
            getMemberCouponListRequestDto.setPageSize(Integer.MAX_VALUE);
            GetMemberCouponListResponseDto.Result result = getMemberCouponList(getMemberCouponListRequestDto);
            List<GetMemberInfoResponseVo.Coupon> coupons = new ArrayList<>();
            if (result != null && CollectionUtils.isNotEmpty(result.getMemberCoupons())){
                List<GetMemberCouponListResponseDto.Result.MemberCoupon> memberCoupons = result.getMemberCoupons();
                Date nowDate = new Date();
                memberCoupons = memberCoupons.stream().filter(item -> filterExpireCoupon(nowDate, item.getEndTime())).collect(Collectors.toList());//过滤掉过期的券
                coupons = memberCoupons.stream().map(each -> convert2MemberCoupon(each)).collect(toList());
            }
            responseData.setCoupons(coupons);
            // 积分
            GetMemberInfoResponseVo.Score score = new GetMemberInfoResponseVo.Score();
            StatisticalScoreRequest statisticalScoreRequest = new StatisticalScoreRequest();
            statisticalScoreRequest.setMemberId(memberId);
            statisticalScoreRequest.setPartnerId(partnerId);
            com.freemud.application.sdk.api.base.BaseResponse<StatisticalScoreResponse> statisticalScoreResponseBaseResponse = memberPropertyService.statisticalScore(statisticalScoreRequest, LogThreadLocal.getTrackingNo());
            if (statisticalScoreResponseBaseResponse != null && statisticalScoreResponseBaseResponse.getData() != null){
                StatisticalScoreResponse statisticalScoreResponse = statisticalScoreResponseBaseResponse.getData();
                score.setCurrentScore(statisticalScoreResponse.getCurrentScore());
            } else {
                score.setCurrentScore(0);
            }
            responseData.setScore(score);

        } else {
            // 优惠券
            List<CartGoods> cartGoodsList = orderItemList.stream().map(each -> convert2ShopCartGoods(each)).collect(toList());

            ActivityClassifyCouponBean activityClassifyCouponBean = couponService.availableCoupon(cartGoodsList, partnerId
                    , memberId, request.getStoreId(), "", false, request.getOrderType(), 0,"");
            if (activityClassifyCouponBean != null && CollectionUtils.isNotEmpty(activityClassifyCouponBean.getUsableCoupons())){
                List<GetMemberInfoResponseVo.Coupon> coupons = activityClassifyCouponBean.getUsableCoupons().stream().map(each -> convert2MemberCoupon(each)).collect(toList());
                responseData.setCoupons(coupons);
            }

            // 积分
            GetUserScoreUseDetailRequest scoreRequest = new GetUserScoreUseDetailRequest();
            scoreRequest.setMemberId(memberId);
            scoreRequest.setPaidAmount(request.getActualPayAmount());
            scoreRequest.setPartnerId(partnerId);
            GetUserScoreUserDetailResponse userScoreUseDetail = customScoreClient.getUserScoreUseDetail(scoreRequest);
            GetMemberInfoResponseVo.Score score = new GetMemberInfoResponseVo.Score();
            if (userScoreUseDetail != null && userScoreUseDetail.getResult() != null){
                GetUserScoreUserDetailResponse.UserScoreDetailVo result = userScoreUseDetail.getResult();
                score.setCurrentScore(result.getCurrentScore());
                score.setReduceAmount(result.getReduceAmount());
                score.setReduceScore(result.getUseScore());
            } else {
                score.setCurrentScore(0);
                score.setReduceAmount(0);
                score.setReduceScore(0);
            }
            responseData.setScore(score);
        }
        // 储值卡
        StatisticalPropertyRequest getMemberCardRequest = new StatisticalPropertyRequest();
        getMemberCardRequest.setPartnerId(partnerId);
        getMemberCardRequest.setMemberId(memberId);
        com.freemud.application.sdk.api.base.BaseResponse<List<GetSvcInfoByMemberIdResponse>> svcInfoByMemberId = memberPropertyService.getSvcInfoByMemberId(getMemberCardRequest, LogThreadLocal.getTrackingNo());
        if (svcInfoByMemberId != null && CollectionUtils.isNotEmpty(svcInfoByMemberId.getData())){
            List<GetSvcInfoByMemberIdResponse> memberCardResponses = svcInfoByMemberId.getData();
            // 查询储值卡的余额
            List<String> cardCodes = memberCardResponses.stream().map(GetSvcInfoByMemberIdResponse::getCardCode).collect(Collectors.toList());
            SVCCardAmountRequest svcCardAmountRequest = new SVCCardAmountRequest();
            svcCardAmountRequest.setCardCodes(cardCodes);
            svcCardAmountRequest.setPartnerId(partnerId);
            com.freemud.application.sdk.api.base.BaseResponse<SVCCardAmountResponse> svcCardAmountResponseBaseResponse = paymentNewService.querySVCCardAmount(svcCardAmountRequest, LogThreadLocal.getTrackingNo());
            List<SVCCardAmountResponse.CardSimpleInfo> cardSimpleInfos = svcCardAmountResponseBaseResponse.getData().getData().getCardSimpleInfos();
            List<GetMemberInfoResponseVo.Card> cards = cardSimpleInfos.stream().map(each -> convert2MemberSvcCard(each)).collect(toList());
            responseData.setCards(cards);

        }
        return ResponseUtil.success(responseData);
    }

    private boolean filterExpireCoupon(Date now, String endTime){
        if (StringUtils.isBlank(endTime)){
            return true;
        }
        Date date = DateUtil.convert2Date(endTime, DateUtil.FORMAT_yyyyMMdd_date);
        return now.before(date);
    }

    private GetMemberInfoResponseVo.Coupon convert2MemberCoupon(GetMemberCouponListResponseDto.Result.MemberCoupon each){
        GetMemberInfoResponseVo.Coupon coupon = new GetMemberInfoResponseVo.Coupon();
        coupon.setStatus(each.getStatus());
        if (each.getCouponType() == 0){
            coupon.setProducts(null); // TODO
        } else {
            coupon.setProducts(null);
        }
        coupon.setCuoponType(each.getCouponType());
        coupon.setCouponName(each.getCouponName());
        String limit = each.getStartTime() + "至" + each.getEndTime() + "当天有效";
        coupon.setCouponLimit(limit);
        coupon.setCouponCode(each.getCouponCode());
        return coupon;
    }

    private GetMemberInfoResponseVo.Coupon convert2MemberCoupon(ActivityCouponBean each){
        GetMemberInfoResponseVo.Coupon coupon = new GetMemberInfoResponseVo.Coupon();
        coupon.setStatus(0);
        if (each.getCouponType() == 0){
            coupon.setProducts(null); // TODO
        } else {
            coupon.setProducts(null);
        }
        coupon.setCuoponType(each.getCouponType());
        coupon.setCouponName(each.getCouponName());
        coupon.setDiscountAmount(Integer.valueOf(each.getDiscountAmount()));
        coupon.setCouponLimit(null);
        coupon.setCouponCode(each.getCouponCode());
        return coupon;

    }

    private GetMemberInfoResponseVo.Card convert2MemberSvcCard(SVCCardAmountResponse.CardSimpleInfo each){
        GetMemberInfoResponseVo.Card card = new GetMemberInfoResponseVo.Card();
        card.setAmount(each.getAmount());
        card.setApplyId(each.getApplyId());
        card.setCardCode(each.getCardCode());
        card.setCardName(each.getCardName());
        card.setVamount(each.getVamount());
        return card;
    }

    private CartGoods convert2ShopCartGoods(GetMemberInfoRequestDto.OrderItemRequest each){
        CartGoods card = new CartGoods();
        int sharePrice = each.getProductSharePrice() == null ? 0 : each.getProductSharePrice();
        int saleValue = (each.getProductPrice() * each.getProductQuantity() - sharePrice) / each.getProductQuantity();
        card.setAmount(Long.valueOf(saleValue));
        card.setOriginalPrice(each.getProductPrice() == null ? 0L : Long.valueOf(each.getProductPrice()));
        card.setQty(each.getProductQuantity());
        card.setSkuId(each.getProductId());
        card.setSpuId(each.getProductId());
        return card;
    }




    private void packgeAdditional(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {

        ArrayList<ShoppingCartInfoRequestVo.SendGoods> senGoods = new ArrayList<>();
        if (premiumExchangeActivity != null && CollectionUtils.isNotEmpty(premiumExchangeActivity.getProducts())) {

            for (CreateOrderVo.PremiumExchangeActivity.Product product : premiumExchangeActivity.getProducts()) {
                ShoppingCartInfoRequestVo.SendGoods sendGoods = new ShoppingCartInfoRequestVo.SendGoods();
                sendGoods.setQty(product.getQty());
                sendGoods.setGoodsId(StringUtils.isEmpty(product.getSkuId()) ? product.getSpuId() : product.getSkuId());
                senGoods.add(sendGoods);
            }
        }
        shoppingCartInfoRequestVo.setSendGoods(senGoods);
    }


    /**
     * 计算第一次使用会员卡需多支付的金额  单位:分
     *
     * @param shoppingCartInfoRequestVo
     * @param shoppingCartGoodsDto
     * @return
     */
    private void getNeedCardAmount(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = shoppingCartInfoRequestVo.getBuyMemberCard();
        if (buyMemberCard != null && StringUtils.isNotEmpty(buyMemberCard.getPaidId()) && StringUtils.isNotEmpty(buyMemberCard.getRuleId())) {
            GetPaidRuleRequestDto getPaidRuleRequestDto = new GetPaidRuleRequestDto();
            getPaidRuleRequestDto.setPartnerId(shoppingCartInfoRequestVo.getPartnerId());
            getPaidRuleRequestDto.setPaidId(buyMemberCard.getPaidId());
            getPaidRuleRequestDto.setRuleId(buyMemberCard.getRuleId());
            BaseResponse<GetPaidRuleResponseDto> baseResponse = customerApplicationClient.getPaidRule(getPaidRuleRequestDto);
            if (baseResponse == null || baseResponse.getResult() == null || !ResponseResult.SUCCESS.getCode().equals(baseResponse.getCode())
                    || baseResponse.getResult().getActivityPrice() == null) {
                return;
            }
            Integer activityPrice = baseResponse.getResult().getActivityPrice();
            Integer firstCouponAmount = baseResponse.getResult().getFirstCouponAmount()==null?0: baseResponse.getResult().getFirstCouponAmount();
            Integer needCardAmount = activityPrice - firstCouponAmount;
            shoppingCartGoodsDto.setMemberCardAmount(needCardAmount);
            shoppingCartGoodsDto.setCardOriginalAmount(baseResponse.getResult().getActivityPrice());
            shoppingCartGoodsDto.setCardDiscountAmount(firstCouponAmount);
            shoppingCartGoodsDto.setOriginalTotalAmount(shoppingCartGoodsDto.getOriginalTotalAmount() + activityPrice);
            shoppingCartGoodsDto.setTotalAmount(shoppingCartGoodsDto.getTotalAmount() + needCardAmount);
            shoppingCartGoodsDto.setTotalDiscountAmount(shoppingCartGoodsDto.getTotalDiscountAmount() + firstCouponAmount);
        }
    }

    /**
     * 获取优惠信息
     *
     * @param partnerId
     * @param storeId
     * @param cartGoodsList
     * @return
     */
    @Override
    public ActivityCalculationDiscountResponseDto.CalculationDiscountResult getActivityCalculationDiscountResponse(
            String partnerId, String storeId, String userId, String appId, Integer orderType,boolean isMember, List<CartGoods> cartGoodsList,
            List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons,
            List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList,String menuType,Long distributionFee) {

        ActivityCalculationDiscountRequestDto activityCalculationDiscountRequestDto = getActivityCalculationDiscountRequestDto(partnerId, storeId, userId, appId, orderType);
        List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList = new ArrayList<>();
        // 校验后有效的商品券map
        Map<String, CheckSpqInfoResponseDto> validCouponMap = new HashMap<>(16);
        for (int i = cartGoodsList.size() - 1; i >= 0; i--) {
            CartGoods cartGoods = cartGoodsList.get(i);
            // 商品不是商品券
            if (StringUtils.isBlank(cartGoods.getCouponCode())) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, cartGoods);
            }
            // 商品是商品券
            else {
                // 商品券ID换取商品
                String couponCode = cartGoods.getCouponCode();
                CheckSpqInfoRequestDto checkSpqInfoRequestDto = new CheckSpqInfoRequestDto(partnerId, storeId, couponCode, menuType);
                CheckSpqInfoResponseDto checkSpqInfoResponseDto = null;
                if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                    checkSpqInfoResponseDto = couponService.checkSpqInfo(checkSpqInfoRequestDto, cartGoods.getSkuId());
                } else {
                    checkSpqInfoResponseDto = couponService.checkSpqInfo(checkSpqInfoRequestDto);
                }
                // 商品券不存在时，将商品券从购物车移除
                if (checkSpqInfoResponseDto == null) {
                    cartGoodsList.remove(i);
                    assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, null, null, this.shoppingCartBaseService);
                } else {
                    validCouponMap.put(couponCode, checkSpqInfoResponseDto);
                    validCouponMap.put(couponCode + checkSpqInfoResponseDto.getSkuId(), checkSpqInfoResponseDto);
                    cartGoods.setName(checkSpqInfoResponseDto.getCouponName());
                    cartGoods.setSpuName(checkSpqInfoResponseDto.getCouponName());
                    cartGoods.setStockLimit(checkSpqInfoResponseDto.isStockLimit());
                    // 添加请求的优惠券信息
                    ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                    coupon.setCode(checkSpqInfoResponseDto.getCouponCode());
                    coupon.setActivityCode(checkSpqInfoResponseDto.getActiveCode());
                    coupons.add(coupon);
                    // 添加商品券代表的商品
                    // 换购券传给促销要带code
                    String goodsId = StringUtils.isEmpty(checkSpqInfoResponseDto.getSkuId()) ? checkSpqInfoResponseDto.getSpuId() : checkSpqInfoResponseDto.getSkuId();
                    if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                        this.addCalculationDiscountGoods(calculationDiscountGoodsList, goodsId, 1, checkSpqInfoResponseDto.getPrice(), 100, cartGoods.getCartGoodsUid(), cartGoods.getSpuId());
                    } else {
                        this.addCalculationDiscountGoods(calculationDiscountGoodsList, goodsId, 1, checkSpqInfoResponseDto.getPrice(), 100, cartGoods.getCartGoodsUid());
                    }
                }
            }

            if (GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                if (CollectionUtils.isEmpty(cartGoods.getProductGroupList()) && CollectionUtils.isEmpty(cartGoods.getProductComboList())) {
                    cartGoodsList.remove(i);
                    assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, null, null, this.shoppingCartBaseService);
                    throw new ServiceException(ResponseResult.SHOPPING_CART_NO_MEAL);
                }
            }
        }
        // 当加价购商品不为空时
        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, sendGoods.getGoodsId(), sendGoods.getQty(), sendGoods.getOriginalPrice(), 100, "");
            }
        }
        calculationDiscountGoodsList.removeIf(calculationDiscountGoods -> (calculationDiscountGoods.getGoodsQuantity().equals(0)));
        if (CollectionUtils.isEmpty(calculationDiscountGoodsList)) {
            return null;
        }
        activityCalculationDiscountRequestDto.setGoods(calculationDiscountGoodsList);
        activityCalculationDiscountRequestDto.setCoupons(coupons);
        activityCalculationDiscountRequestDto.setOrgIds(commonService.getOrgIds(partnerId, storeId));
        activityCalculationDiscountRequestDto.setDistributionFee(distributionFee);
        activityCalculationDiscountRequestDto.setIsMember(isMember);
        ActivityCalculationDiscountResponseDto activityCalculationDiscountResponseDto;
        try {
            activityCalculationDiscountResponseDto = activityClient.calculationDiscount(activityCalculationDiscountRequestDto);
        } catch (Exception ex) {
            ErrorLog.printErrorLog("calculation_discount_error", "/calculation/discount", activityCalculationDiscountRequestDto, ex);
            throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
        }
        // 返回成功
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), ResponseCodeConstant.RESPONSE_SUCCESS_STR)) {
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult result = activityCalculationDiscountResponseDto.getResult();
            List<Integer> activityTypes = result.getDiscounts().stream().map(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount::getType).collect(Collectors.toList());
            if (activityTypes.contains(221)) {
                ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount discountDTO = result.getDiscounts().stream().filter(d -> 221 == d.getType()).findFirst().get();
                convert2SendPoint(result, discountDTO);
            }
            result.setValidCouponMap(validCouponMap);
            result.setDeliveryAmount(distributionFee);
            result.setDistributionFee(result.getDistributionFee());
            return result;
        }
        // 支付宝华莱士紧急修改代码，当促销返回103错误码时，需要报券不适用于该门店，且清空购物车
        ShoppingCartClearRequestVo shoppingCartClearRequestVo = new ShoppingCartClearRequestVo();
        shoppingCartClearRequestVo.setAppId(appId);
        shoppingCartClearRequestVo.setPartnerId(partnerId);
        shoppingCartClearRequestVo.setUserId(userId);
        shoppingCartClearRequestVo.setShopId(storeId);
        shoppingCartClearRequestVo.setOperationType(1);
        clear(shoppingCartClearRequestVo);
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), "103")){
            throw new ServiceException(ResponseResult.SHOPPING_CART_COUPON_CAN_NOT_USE_THIS_SHOP);
        }
        throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
    }

    private void convert2SendPoint(ActivityCalculationDiscountResponseDto.CalculationDiscountResult result, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount discountDTO) {
        SendPoint sendPointNew = new SendPoint();

        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendPointDto sendPointVo = discountDTO.getSendPointVo();
        if (sendPointVo != null) {
            sendPointNew.setMaxNum(sendPointVo.getMaxNum());
            sendPointNew.setSendPoint(sendPointVo.getSendPoint());
            sendPointNew.setValidityDateDays(sendPointVo.getValidityDateDays());
            sendPointNew.setActivityCode(discountDTO.getActivityCode());
            sendPointNew.setEndTime(discountDTO.getEndTime());
            sendPointNew.setStoreLevel(sendPointVo.getStoreLevel());
            result.setSendPointVo(sendPointNew);
        }

    }

    /**
     * 将calculationDiscountGoods 封装后加入 calculationDiscountGoodsList
     *
     * @param calculationDiscountGoodsList
     * @param goodsId
     * @param goodsQuantity
     * @param originalPrice
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList,
                                             String goodsId, Integer goodsQuantity, Long originalPrice, Integer memberDiscount, String cartGoodsUid) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsId(goodsId);
        calculationDiscountGoods.setCartGoodsUid(cartGoodsUid);
        calculationDiscountGoods.setGoodsQuantity(goodsQuantity);
        calculationDiscountGoods.setOriginalPrice(originalPrice);
        calculationDiscountGoods.setMemberDiscount(memberDiscount);
        this.addCalculationDiscountGoods(calculationDiscountGoodsList, calculationDiscountGoods);
    }

    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList
            , String goodsId
            , Integer goodsQuantity
            , Long originalPrice
            , Integer memberDiscount
            , String cartGoodsUid
            , String couponCode) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsId(goodsId);
        calculationDiscountGoods.setCartGoodsUid(cartGoodsUid);
        calculationDiscountGoods.setGoodsQuantity(goodsQuantity);
        calculationDiscountGoods.setOriginalPrice(originalPrice);
        calculationDiscountGoods.setMemberDiscount(memberDiscount);
        calculationDiscountGoods.setCouponCode(couponCode);
        this.addCalculationDiscountGoods(calculationDiscountGoodsList, calculationDiscountGoods);
    }

    /**
     * 促销增加
     *
     * @param calculationDiscountGoodsList
     * @param cartGoods
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList, CartGoods cartGoods) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();

        calculationDiscountGoods.setGoodsId(cartGoods.getGoodsId());
        calculationDiscountGoods.setCartGoodsUid(cartGoods.getCartGoodsUid());
        calculationDiscountGoods.setGoodsQuantity(cartGoods.getQty());
        calculationDiscountGoods.setOriginalPrice(cartGoods.getFinalPrice());
        calculationDiscountGoods.setMemberDiscount(cartGoods.getMemberDiscount());
        calculationDiscountGoods.setSpuId(cartGoods.getSpuId());

        //加料
        if (CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
            new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
            ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material> materials = new ArrayList<>();
            for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material material = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
                material.setType(1);
                material.setGoodsId(materialGoods.getSpuId());
                material.setGoodsQuantity(1);
                material.setOriginalPrice(materialGoods.getFinalPrice());
                materials.add(material);
            }
            calculationDiscountGoods.setSmallMaterial(materials);
        }
        this.addCalculationDiscountGoods(calculationDiscountGoodsList, calculationDiscountGoods);
    }

    /**
     * 构建 ActivityCalculationDiscountRequestDto
     *
     * @param partnerId
     * @param storeId
     * @param userId
     * @param appId
     * @param orderType
     * @return
     */
    private ActivityCalculationDiscountRequestDto getActivityCalculationDiscountRequestDto(String partnerId, String storeId, String userId, String appId, Integer orderType) {
        ActivityCalculationDiscountRequestDto activityCalculationDiscountRequestDto = new ActivityCalculationDiscountRequestDto();
        activityCalculationDiscountRequestDto.setPartnerCode(partnerId);
        activityCalculationDiscountRequestDto.setStoreId(storeId);
        activityCalculationDiscountRequestDto.setIsShowGoodsActivity(1);
        activityCalculationDiscountRequestDto.setUserId(userId);
        activityCalculationDiscountRequestDto.setVer(1);
        activityCalculationDiscountRequestDto.setAppId(appId);
        ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeConvert2ActivityChannel(orderType);
        if (!Objects.isNull(activityChannelEnum)) {
            activityCalculationDiscountRequestDto.setChannel(activityChannelEnum.getCode());
        }
        return activityCalculationDiscountRequestDto;
    }


    /**
     * 累加需加入计算的商品
     *
     * @param calculationDiscountGoodsList
     * @param calculationDiscountGoods
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList,
                                             ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods) {
        int index;
        // 当商品已存在时,需累加数量
        if ((index = calculationDiscountGoodsList.indexOf(calculationDiscountGoods)) >= 0) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountGoods oldCalculationDiscountGoods = calculationDiscountGoodsList.get(index);
            oldCalculationDiscountGoods.setGoodsQuantity(oldCalculationDiscountGoods.getGoodsQuantity() + calculationDiscountGoods.getGoodsQuantity());
        } else {
            calculationDiscountGoodsList.add(calculationDiscountGoods);
        }
    }

    /**
     * 处理加价购商品
     *
     * @param sendGoodsList
     * @param partnerId
     * @param storeId
     */
    private void processSendGoods(List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList
            , String partnerId, String storeId,String menuType, ShoppingCartBaseService shoppingCartService) {
        List<String> goodsIds = sendGoodsList.parallelStream().map(ShoppingCartInfoRequestVo.SendGoods::getGoodsId).collect(Collectors.toList());
        List<ProductBeanDTO> productBeanList =
                assortmentSdkService.getProductsInfoSdk(partnerId, storeId, goodsIds, menuType, shoppingCartService);
        // 将productBeanList转换为Map，key为pid，即goodsId
        Map<String, ProductBeanDTO> productBeanMap = productBeanList.parallelStream()
                .collect(Collectors.toMap(ProductBeanDTO::getPid, Function.identity(), (k1, k2) -> k1));
        // 遍历购物车进行加个更新
        for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
            ProductBeanDTO productBean;
            if ((productBean = productBeanMap.get(sendGoods.getGoodsId())) != null) {
                // 设置加价购商品原价
                sendGoods.setOriginalPrice(productBean.getFinalPrice());
            } else {
                throw new ServiceException(ResponseResult.SHOPPING_CART_SENDGOODS_NOT_EXIST);
            }
        }

    }


    /**
     * 当ToastMsg为空时才赋值
     *
     * @param shoppingCartGoodsResponseVo
     * @param message
     */
    private void setToastMsgIfNotExist(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String message) {
        if (StringUtils.isEmpty(shoppingCartGoodsResponseVo.getToastMsg())) {
            shoppingCartGoodsResponseVo.setToastMsg(message);
        }
    }

    /**
     * 促销活动的优惠金额计算
     *
     * @param calculationDiscountResult
     * @param cartGoodsList
     * @param shoppingCartGoodsResponseVo
     */
    private void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, UserLoginInfoDto userLoginInfoDto,String menuType,Long deliveryAmount) {
        //默认计算优惠
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        // 优惠券
        CouponPromotionService couponPromotionService = (CouponPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.COUPON_DISCOUNT);
        couponPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        // 满减
        FullPromotionService fullPromotionService = (FullPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.FULL_REDUCTION);
        fullPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getSendGoods())) {
            if (calculationDiscountResult.getSendGoods().stream()
                    .anyMatch(sendActivity -> Objects.equals(sendActivity.getActivityType(), ActivityTypeEnum.TYPE_6.getCode())
                            || Objects.equals(sendActivity.getActivityType(), ActivityTypeEnum.TYPE_61.getCode()))) {
                // 买赠
                BuySendPromotionService buySendPromotionService = (BuySendPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_ONE_SEND);
                buySendPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
            if (calculationDiscountResult.getSendGoods().stream()
                    .anyMatch(sendActivity -> Objects.equals(sendActivity.getActivityType(), ActivityTypeEnum.TYPE_81.getCode()))) {
                // 加价购
                AdditionalPromotionService additionalPromotionService = (AdditionalPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.ADDITIONAL_BUY);
                additionalPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
        }

        /**
         * 第x件y折活动计算方式：
         * 1. 从calculationDiscountResult.discounts中，type=104&discount>0则走下面的代码逻辑
         * 2. calculationDiscountResult.apportionGoods中，找到商品的所有的活动，然后把apportionAmount相加，把均摊放到当前的购物车商品里
         * 3. 限时特价和第x件y折活动冲突，故在第x件y折活动中去掉这个104type的活动
         *
         */
        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
            if (calculationDiscountResult.getDiscounts().stream()
                    .anyMatch(discount -> Objects.equals(discount.getType(), ActivityTypeEnum.TYPE_104.getCode())
                            && discount.getDiscount() > 0)) {
                XyDiscountServiceImpl xyDiscountService = (XyDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.XY_DISCOUNT);
                xyDiscountService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
        }

        // 限时特价
        TimeSalePromotionService timeSalePromotionService = (TimeSalePromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.TIME_SALE);
        timeSalePromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        //积分兑换
        CustomerScoreService customerScoreService = (CustomerScoreService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.CUSTOMER_SCORE);
        customerScoreService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        /**
         * 第2件N折计算划线价
         */
        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
            if (calculationDiscountResult.getDiscounts().stream()
                    .anyMatch(discount -> Objects.equals(discount.getType(), ActivityTypeEnum.TYPE_53.getCode())
                            && discount.getDiscount() > 0)) {
                TwoNDiscountServiceImpl twoNDiscountService = (TwoNDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.TwoN_DISCOUNT);
                twoNDiscountService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
        }
        // 买赠活动
        BuyAndGiftsPromotionService buyAndGiftsPromotionService =(BuyAndGiftsPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_GIFTS);
        buyAndGiftsPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        //会员价
        MemberDiscountServiceImpl memberDiscountService=(MemberDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.MEMBER_DISCOUNT);
        memberDiscountService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        /**
         * 满额减配送费
         */

        if(BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(menuType)) {
            DecimalFormat df = new DecimalFormat("###.##");
            List<ActivityTypeEnum> activityTypeEnums = new LinkedList<>();
            activityTypeEnums.add(ActivityTypeEnum.TYPE_14);

            ActivityQueryResponseDto activityQueryResponseDto = activityService.queryActivityByType(activityQueryDto, activityTypeEnums, null);
            ActivityResponseDto activityResponse =null;
            BenefitBeanDto beanDto=null;
            if (activityQueryResponseDto != null &&activityQueryResponseDto.getResult()!=null && activityQueryResponseDto.getResult().size()>0) {
                activityResponse = activityQueryResponseDto.getResult().get(0);
                shoppingCartGoodsResponseVo.setDiscountDeliveryActivityCode(activityResponse.getActivityCode());
                beanDto=activityResponse.getBenefits().get(0);
            }

            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount discount=null;
            if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
                Optional<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discountop
                        = calculationDiscountResult.getDiscounts().stream()
                        .filter(discount1 -> {
                            return ActivityTypeEnum.TYPE_14.getCode().equals(discount1.getType());
                        })
                        .findFirst();
                discount=discountop.orElseGet(() -> {return null ;});
            }
            if(discount!=null){
                if(beanDto.getBenefitType() == 1){
                    String desc = DELIVERY_DISCOUNT_DESC2;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ));
                }else{
                    String desc = DELIVERY_DISCOUNT_DESC1;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ,df.format(beanDto.getDiscountAmount().doubleValue() / 100)));
                }
                shoppingCartGoodsResponseVo.setDeliveryAmount(calculationDiscountResult.getDeliveryAmount());
                shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(calculationDiscountResult.getDistributionFee());
                shoppingCartGoodsResponseVo.setThresholdAmount(discount.getThresholdAmount());
                shoppingCartGoodsResponseVo.setIsDiscountDelivery(true);
            }else{

                if (activityResponse!=null) {

                    if(beanDto.getBenefitType() == 1){
                        String desc = DELIVERY_DISCOUNT_DESC2;
                        shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ));
                    }else{
                        String desc = DELIVERY_DISCOUNT_DESC1;
                        shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100 ),df.format(beanDto.getDiscountAmount().doubleValue() / 100)));
                    }

                    shoppingCartGoodsResponseVo.setDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setIsDiscountDelivery(false);

                } else {
                    String desc = DELIVERY_DISCOUNT_DESC3;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(deliveryAmount.doubleValue() / 100)));
                    shoppingCartGoodsResponseVo.setDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setIsDiscountDelivery(false);
                }
            }
        }

        /**
         * 加料
         */
        MaterialPromotionService materialPromotionService = (MaterialPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.Material);
        materialPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

    }

    /**
     * 促销均摊计算
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param shoppingCartGoodsDto
     * @param premiumExchangeActivity
     * @param shoppingCartInfoRequestVo
     */
    private void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 优惠券
        CouponPromotionService couponPromotionService = (CouponPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.COUPON_DISCOUNT);
        couponPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 买赠
        BuySendPromotionService buySendPromotionService = (BuySendPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_ONE_SEND);
        buySendPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 加价购
        AdditionalPromotionService additionalPromotionService = (AdditionalPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.ADDITIONAL_BUY);
        additionalPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 限时特价
        TimeSalePromotionService timeSalePromotionService = (TimeSalePromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.TIME_SALE);
        timeSalePromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //积分兑换
        CustomerScoreService customerScoreService = (CustomerScoreService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.CUSTOMER_SCORE);
        customerScoreService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //xy折
        XyDiscountServiceImpl xyDiscountService = (XyDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.XY_DISCOUNT);
        xyDiscountService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //xy折
        BuyAndGiftsPromotionService buyAndGiftsPromotionService = (BuyAndGiftsPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_GIFTS);
        buyAndGiftsPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 集点活动
        GatherSpotPromotionService gatherSpotPromotionService = (GatherSpotPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.GATHER_SPOT);
        gatherSpotPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        /**
         * 设置加料商品行记录
         */
        MaterialPromotionService materialPromotionService = (MaterialPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.Material);
        materialPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);
    }


    /**
     * 获取购物车商品,添加商品,校验商品合法性,合并商品行,重新set购物车信息到缓存中
     *
     * @param cartGoods
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param addShoppingCartGoodsRequestVo
     */
    @Override
    public List<CartGoods> updateCartGoodsLegal(CartGoods cartGoods, String userId, ShoppingCartGoodsBaseResponseVo shoppingCartGoodsResponseVo, AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<CartGoods> oldAllCartGoodsList) {
        //存储新添加的购物车信息
        List<CartGoods> nowCartGoodsList = new ArrayList<>();
        oldAllCartGoodsList.add(cartGoods);

        //当商品全部添加完毕,校验购物车商品(是否合法,上下架,点餐方式,是否在当前菜单中...),并移除非法商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(oldAllCartGoodsList, addShoppingCartGoodsRequestVo.getPartnerId(),
                addShoppingCartGoodsRequestVo.getShopId(), shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo.getOrderType(),
                "", addShoppingCartGoodsRequestVo.getMenuType(),shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
            shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
        }
        List<CartGoods> allCartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        //判断当前商品在购物车是否已存在,存在则数量＋1,不存在商品行 + 1
        allCartGoodsList.forEach(oldCartGoods -> {
            int index;
            if ((index = nowCartGoodsList.indexOf(oldCartGoods)) >= 0) {
                nowCartGoodsList.get(index).setQty(nowCartGoodsList.get(index).getQty() + cartGoods.getQty());
            } else {
                nowCartGoodsList.add(oldCartGoods);
            }
        });
        // 重新set购物车信息到缓存中
        assortmentSdkService.setShoppingCart(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(),
                userId, nowCartGoodsList, addShoppingCartGoodsRequestVo.getSessionId(), addShoppingCartGoodsRequestVo.getTableNumber(), this.shoppingCartBaseService);
        oldAllCartGoodsList.clear();
        oldAllCartGoodsList.addAll(nowCartGoodsList);
        return nowCartGoodsList;
    }

    /**
     * 添加商品券商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @param cartGoods
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param spuId
     * @param spuId2
     * @param allCartGoodsList
     * @param productBeanListSpuClass
     */
    private void addProductGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo
            , CartGoods cartGoods, String spuId2, String userId, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String spuId
            , List<CartGoods> allCartGoodsList, List<ProductBeanDTO> productBeanListSpuClass, CouponProductDto couponProductDto, String couponCode) {

        // 设置商品类型为商品券
        if (CouponTypeEnum.TYPE_4.getCode().equals(couponProductDto.getType())) {
            cartGoods.setGoodsType(GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType());
        } else {
            cartGoods.setGoodsType(GoodsTypeEnum.COUPON_GOODS.getGoodsType());
        }
        cartGoods.setCouponCode(couponCode);
        cartGoods.setSpuId(spuId);
        cartGoods.setSkuId(spuId2);
        cartGoods.setOriginalPrice(0L);
        cartGoods.setOriginalAmount(0L);
        cartGoods.setAmount(0L);
        cartGoods.setPackPrice(productBeanListSpuClass.get(0).getPackPrice());
        cartGoods.setPic(productBeanListSpuClass.get(0).getPicture());
        cartGoods.setWeight(productBeanListSpuClass.get(0).getWeight());
        cartGoods.setUnit(productBeanListSpuClass.get(0).getUnit());
        boolean stockLimit = false;
        if (productBeanListSpuClass.get(0).getType() == ProductType.NOSPEC.getCode()
                && productBeanListSpuClass.get(0).getStockLimit() == 1) {
            stockLimit = true;
        } else {
            for (ProductBeanDTO.SkuProductBean skuProductBean : productBeanListSpuClass.get(0).getSkuList()) {
                if (spuId2.equals(skuProductBean.getSkuId()) && skuProductBean.getStockLimit() == 1) {
                    stockLimit = true;
                    break;
                }
            }
        }
        cartGoods.setStockLimit(stockLimit);

        List<String> goodsIds = allCartGoodsList.parallelStream().map(CartGoods::getGoodsId).collect(Collectors.toList());
        boolean hasSpecialGoods = hasSpecialGoods(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(), userId, addShoppingCartGoodsRequestVo.getAppId(), goodsIds, addShoppingCartGoodsRequestVo.getOrderType());
        // 如果购物车先加入促销活动的商品，再加入商品券时，toast提示“该商品券与其他活动不同享，购物车中已优惠的商品将恢复原价”
        if (hasSpecialGoods) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.HAS_OTHER_ACTIVITY_WHEN_ADD_GOODS_COUPON);
        }
        //校验合法性,更新缓存中购物车信息
        LogUtil.info("updateCartGoodsLegal", JSON.toJSONString(cartGoods), JSON.toJSONString(allCartGoodsList));

        updateCartGoodsLegal(cartGoods, userId, shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo, allCartGoodsList);

    }

    /**
     * 查询多个商品库存信息
     *
     * @param addShoppingCartGoodsRequestVo
     * @param productIds
     * @param productBeanListSpuClass
     * @param skuId
     */
    private void queryManyGoodsStocks(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<Long> productIds
            , List<ProductBeanDTO> productBeanListSpuClass, String skuId, Integer qty) {
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode());
        requestDto.setPartnerId(addShoppingCartGoodsRequestVo.getPartnerId());
        requestDto.setStoreId(addShoppingCartGoodsRequestVo.getShopId());
        requestDto.setProductIds(productIds);
        GetProductStockResponseDto availableStocks = null;
        if (productBeanListSpuClass.get(0).getType() == ProductType.NOSPEC.getCode()
                && productBeanListSpuClass.get(0).getStockLimit() == 1) {
            availableStocks = stockClient.getAvailableStocks(requestDto);
        } else {
            for (ProductBeanDTO.SkuProductBean skuProductBean : productBeanListSpuClass.get(0).getSkuList()) {
                if (skuId.equals(skuProductBean.getSkuId()) && skuProductBean.getStockLimit() == 1) {
                    availableStocks = stockClient.getAvailableStocks(requestDto);
                    break;
                }
            }
        }
        if (availableStocks != null && !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
        if (availableStocks != null && ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode()) &&
                (CollectionUtils.isEmpty(availableStocks.getResult()) || availableStocks.getResult().get(0).getQty() == null
                        || availableStocks.getResult().get(0).getQty() < qty)) {
            Integer stock = 0;
            if (!CollectionUtils.isEmpty(availableStocks.getResult()) && (stock = availableStocks.getResult().get(0).getQty()) > 0) {
                throw new BizServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE, "仅剩" + stock + "件库存了");
            }
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
    }

    /**
     * 组装添加商品和更新商品和查询的响应信息
     * <p>
     * 查询购物车计算包装费
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param cartGoodsList
     * @param toastMsg
     * @param userId
     * @param opt
     * @param shoppingCartInfoRequestVo
     */
    private void setAddAndUpdateResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
            , List<CartGoods> cartGoodsList, String toastMsg, String partnerId, String storeId, String userId, String opt, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        shoppingCartGoodsResponseVo.setProductsCount(cartGoodsList.size());
        if (StringUtils.isNotEmpty(toastMsg)) {
            toastMsg=shoppingCartInfoRequestVo!=null && ObjectUtils.equals(1, shoppingCartInfoRequestVo.getFlag())?SHOPPING_CART_EMPTY_GOODS_LIST:SHOPPING_CART_INVALIAD_GOODS;
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, toastMsg);
            //结算页，只有商品全部非法（即products为空）时，才提示changed为true toastMsg 不为空
            if (shoppingCartInfoRequestVo!=null && ObjectUtils.equals(1, shoppingCartInfoRequestVo.getFlag())){
                shoppingCartGoodsResponseVo.setChanged(CollectionUtils.isEmpty(cartGoodsList));
                shoppingCartGoodsResponseVo.setToastMsg(CollectionUtils.isEmpty(cartGoodsList)?toastMsg:"");
            }

        }
        // 更新和添加商品时不需要包装费
        if (ShoppingCartConstant.ADD_AND_UPDATE.equals(opt)) {
            shoppingCartGoodsResponseVo.setNewPackAmount(null);
            return;
        }
        //==========================  购物车查询特有逻辑  =================================
        // 到店自取包装费设为null,外卖要计算包装费，flag为1表示去结算
        // 兼容老版本判断null
        if (Objects.equals(shoppingCartInfoRequestVo.getOrderType(), CreateOrderType.COLLECT_GOODS.getCode())
                && (Objects.equals(shoppingCartInfoRequestVo.getReachStoreType(), null)
                || Objects.equals(shoppingCartInfoRequestVo.getReachStoreType(), OrderType.EAT_IN.getCode()))) {
            shoppingCartGoodsResponseVo.setNewPackAmount(null);
        } else if ((Objects.equals(shoppingCartInfoRequestVo.getOrderType(), CreateOrderType.TAKE_OUT.getCode())
                || Objects.equals(shoppingCartInfoRequestVo.getReachStoreType(), OrderType.COLLECT_GOODS.getCode()))
                && Objects.equals(shoppingCartInfoRequestVo.getFlag(), CouponFlag.YES.getCode())) {
            Long packAmount = shoppingCartGoodsResponseVo.getNewPackAmount() == null ? 0 : shoppingCartGoodsResponseVo.getNewPackAmount();
            Long originalTotalAmount = shoppingCartGoodsResponseVo.getOriginalTotalAmount() + packAmount;
            Long totalAmount = shoppingCartGoodsResponseVo.getTotalAmount() + packAmount;
            shoppingCartGoodsResponseVo.setOriginalTotalAmount(originalTotalAmount);
            shoppingCartGoodsResponseVo.setTotalAmount(totalAmount);
        }

    }

    /**
     * 在原价、现价、折扣价上增加第一次使用会员卡的费用
     *
     * @param shoppingCartInfoRequestVo
     * @param shoppingCartGoodsResponseVo
     */
    private void addNeedCardAmount(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = shoppingCartInfoRequestVo.getBuyMemberCard();
        if (shoppingCartInfoRequestVo.getBuyMemberCard() == null || StringUtils.isEmpty(buyMemberCard.getPaidId()) || StringUtils.isEmpty(buyMemberCard.getRuleId())) {
            return;
        }
        GetPaidRuleRequestDto getPaidRuleRequestDto = new GetPaidRuleRequestDto();
        getPaidRuleRequestDto.setPartnerId(shoppingCartInfoRequestVo.getPartnerId());
        getPaidRuleRequestDto.setPaidId(buyMemberCard.getPaidId());
        getPaidRuleRequestDto.setRuleId(buyMemberCard.getRuleId());
        BaseResponse<GetPaidRuleResponseDto> baseResponse = customerApplicationClient.getPaidRule(getPaidRuleRequestDto);
        if (baseResponse == null || !ResponseResult.SUCCESS.getCode().equals(baseResponse.getCode()) || baseResponse.getResult() == null
                || baseResponse.getResult().getActivityPrice() == null) {
            return;
        }
        // 购买会员卡的金额
        Integer activityPrice = baseResponse.getResult().getActivityPrice();
        // 首次使用会员卡享受的折扣金额
        Integer firstCouponAmount = baseResponse.getResult().getFirstCouponAmount() == null ? 0 : baseResponse.getResult().getFirstCouponAmount();
        Long originalTotalAmount = shoppingCartGoodsResponseVo.getOriginalTotalAmount() + activityPrice;
        Long totalAmount = shoppingCartGoodsResponseVo.getTotalAmount() + (activityPrice - firstCouponAmount);
        Long totalDiscountAmount = shoppingCartGoodsResponseVo.getTotalDiscountAmount() + firstCouponAmount;
        shoppingCartGoodsResponseVo.setOriginalTotalAmount(originalTotalAmount);
        shoppingCartGoodsResponseVo.setTotalAmount(totalAmount);
        shoppingCartGoodsResponseVo.setTotalDiscountAmount(totalDiscountAmount);
        shoppingCartGoodsResponseVo.setCardOriginalAmount(activityPrice);
        shoppingCartGoodsResponseVo.setCardDiscountAmount(firstCouponAmount);
    }

    private UserLoginInfoDto convert2UserLoginInfoDto(CustomerInfoVo assortmentCustomerInfoVo) {
        if (assortmentCustomerInfoVo == null || assortmentCustomerInfoVo.getMemberId() == null) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        UserLoginInfoDto userLoginInfoDto = new UserLoginInfoDto();
        userLoginInfoDto.setMemberId(assortmentCustomerInfoVo.getMemberId());
        userLoginInfoDto.setOpenId(assortmentCustomerInfoVo.getOpenId());
        userLoginInfoDto.setWxAppid(assortmentCustomerInfoVo.getWxAppId());
        userLoginInfoDto.setSessionKey(assortmentCustomerInfoVo.getSessionKey());
        userLoginInfoDto.setMobile(assortmentCustomerInfoVo.getMobile());
        userLoginInfoDto.setAppsecret(assortmentCustomerInfoVo.getAppSecret());
        userLoginInfoDto.setPartnerId(assortmentCustomerInfoVo.getPartnerId());
        userLoginInfoDto.setNewMemeber(assortmentCustomerInfoVo.getNewMember());
        userLoginInfoDto.setUnionId(assortmentCustomerInfoVo.getUnionId());

        return userLoginInfoDto;
    }

    /**
     * 储值卡支付余额校验
     * 校验订单商品金额与外卖配送费
     */
    private void SVCCardPay(String cardCode, String receiveId, String partnerId, String storeId,
                            ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        if (StringUtils.isBlank(cardCode)) {
            return;
        }
        Integer orderAmount = shoppingCartGoodsResponseVo.getTotalAmount().intValue();
        String trackingNo = LogThreadLocal.getTrackingNo();
        SVCCardAmountRequest request = new SVCCardAmountRequest();
        request.setPartnerId(partnerId);
        request.setCardCodes(Arrays.asList(cardCode));
        //查询svc卡金额
        com.freemud.application.sdk.api.base.BaseResponse<SVCCardAmountResponse> response = paymentNewService.querySVCCardAmount(request, trackingNo);
        if (response == null) {
            throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }
        if (response.getData() == null || response.getData().getData() == null || response.getData().getData().getCardSimpleInfos().size() > 1) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        boolean check = this.checkSvcComPay(partnerId, storeId);
        if (check) {
            //混合支付无需校验svc卡余额,但是配送和包装费不计算在svc卡支付
            Integer amount1 = response.getData().getData().getCardSimpleInfos().get(0).getAmount();
            Integer vamount = response.getData().getData().getCardSimpleInfos().get(0).getVamount();
            Integer svcTotalAmount = amount1+vamount;
            //获取实际配送费
            Integer deliveryAmount = 0;
            Integer svcPayAmount   = 0;
            if (StringUtils.isNotBlank(receiveId) && shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() != null) {
                //Integer deliveryAmount = getDeliveryAmount(receiveId, partnerId, storeId);
                deliveryAmount = shoppingCartGoodsResponseVo.getDiscountDeliveryAmount().intValue();
                orderAmount += deliveryAmount;
            }
            if (svcTotalAmount>0 && svcTotalAmount>orderAmount) {
                svcPayAmount = orderAmount;
                shoppingCartGoodsResponseVo.setTotalAmount(0L);
            }
            else if (svcTotalAmount>0 && svcTotalAmount<=orderAmount) {
                svcPayAmount = svcTotalAmount;
                shoppingCartGoodsResponseVo.setTotalAmount((orderAmount.longValue()-svcPayAmount.longValue()));
            }
            BigDecimal bigDecimal = new BigDecimal(svcPayAmount);
            String amountStr = bigDecimal.divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            shoppingCartGoodsResponseVo.setSvcPayAmount(amountStr);
            shoppingCartGoodsResponseVo.setSvcDiscountDesc("储值卡支付￥" + amountStr);
        }
        else {
            //获取实际配送费
            if (StringUtils.isNotBlank(receiveId) && shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() != null) {
                Integer deliveryAmount = shoppingCartGoodsResponseVo.getDiscountDeliveryAmount().intValue();
                orderAmount += deliveryAmount;
            }
            Integer amount1 = response.getData().getData().getCardSimpleInfos().get(0).getAmount();
            Integer vamount = response.getData().getData().getCardSimpleInfos().get(0).getVamount();
            if (orderAmount > amount1 + vamount) {
                throw new ServiceException(ResponseResult.USER_SVC_CARD_AMOUNT_DEFICIENCY);
            }
            BigDecimal bigDecimal = new BigDecimal(orderAmount);
            String amountStr = bigDecimal.divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            shoppingCartGoodsResponseVo.setTotalAmount(0L);
            shoppingCartGoodsResponseVo.setSvcDiscountDesc("储值卡支付￥" + amountStr);
        }
    }

    /**
     * 储值卡支付查询配送费
     *
     * @return
     */
    private Integer getDeliveryAmount(String receiveId, String partnerId, String storeId) {
        String trackingNo = LogThreadLocal.getTrackingNo();
        Integer amount = 0;
        if (StringUtils.isBlank(receiveId)) {
            return amount;
        }
        QueryReceiveAddressRequest queryReceive = new QueryReceiveAddressRequest(receiveId, partnerId);
        //查询会员后货地址经纬度
        com.freemud.application.sdk.api.base.BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(queryReceive, trackingNo);
        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR);
        }
        StoreInfoRequest request = new StoreInfoRequest();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeId);
        //查询门店信息，获取门店经纬度
        StoreResponse storeResponse = storeCenterService.getStoreInfo(request, trackingNo);
        if (storeResponse == null || storeResponse.getStatusCode() != 100 || storeResponse.getBizVO() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        //查询门店外卖配送配置
        AssortmentOpenPlatformPartnerStoreDeliveryConfig deliveryConfig = deliveryConfigManager.findByPartnerIdAndStoreCode(partnerId, storeId);
        if (deliveryConfig == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
        }
        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(partnerId);
        storeDeliveryInfoDto.setStoreId(storeId);
        storeDeliveryInfoDto.setStoreName(storeResponse.getBizVO().getStoreName());
        storeDeliveryInfoDto.setDeliveryLimitAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryLimitAmount());
        storeDeliveryInfoDto.setDeliveryAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryAmount());
        storeDeliveryInfoDto.setDefaultDeliveryRange(deliveryConfig == null ? 0L : deliveryConfig.getDefaultDeliveryRange());
        storeDeliveryInfoDto.setAddRangeAmount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeAmount());
        storeDeliveryInfoDto.setAddRangeCount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeCount());
        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponse.getBizVO().getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponse.getBizVO().getDeliveryHoursDay());
        storeDeliveryInfoDto.setLongitude(storeResponse.getBizVO().getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponse.getBizVO().getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponse.getBizVO().getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponse.getBizVO().getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponse.getBizVO().getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }
        storeDeliveryInfoDto.setEnableTakeaway(true);
        String userLongitude = queryReceiveAddressResponse.getData().getLongitude();
        String userLatitude = queryReceiveAddressResponse.getData().getLatitude();
        amount = storeService.getUserRealDeliveryAmount(storeDeliveryInfoDto, userLongitude, userLatitude).intValue();
        return amount;
    }

    private Long getNewDeliveryAmount(String receiveId, String partnerId, String storeId, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,Integer orderType) {
        //String trackingNo = LogThreadLocal.getTrackingNo();
        Long amount = 0L;
        // 如果订单的收获地址为空，且订单是外卖单，返回运费
        // 主要是为了兼容coco不传收获地址，需要获取固定运费的情况
        if (StringUtils.isBlank(receiveId) && !Objects.equals(orderType, CreateOrderType.TAKE_OUT.getCode())) {
            return amount;
        }

        DeliveryService deliveryService = deliveryFactory.getCalculateDeliveryAmount(orderType,receiveId);
        amount = deliveryService.calculateDeliveryAmount(receiveId,partnerId,storeId,shoppingCartGoodsResponseVo);

        return amount;
    }

    /**
     * 获取配送范围内集合
     */
    public List<Point2D.Double> getDeliveryPoint2DList(String distributionScope) {
        if (StringUtils.isBlank(distributionScope)) {
            return Collections.emptyList();
        }
        /**
         * 如果点不为整数，返回空
         */
        String[] points = distributionScope.split(",");
        if (points.length % 2 != 0) {
            return Collections.emptyList();
        }
        List<String> pointList = Arrays.asList(points);
        List<Point2D.Double> point2DList = Lists.newArrayList();
        for (int i = 0; i < pointList.size(); i++) {
            Double pointX = Double.parseDouble(pointList.get(i));
            Double pointY = Double.parseDouble(pointList.get(++i));
            point2DList.add(new Point2D.Double(pointX, pointY));
        }
        return point2DList;
    }

    /**
     * 获取优惠
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult getCalculationDiscountResult(String menuType
            ,String partnerId,String storeId,String userId,String appId,String wxappid,Integer orderType,boolean isMember
            ,List<CartGoods> cartGoodsList,List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons
            ,List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList,String receiveId,Long deliveryAmount){
        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult=null;
        //外卖场景下 查询门店配送信息
        if(BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(menuType)){

            calculationDiscountResult = this.getActivityCalculationDiscountResponse(partnerId, storeId, userId, appId, orderType,isMember, cartGoodsList, coupons, sendGoodsList,BusinessTypeEnum.getByType(menuType).getCode(),deliveryAmount);
        }else{
            calculationDiscountResult = this.getActivityCalculationDiscountResponse(partnerId, storeId, userId, appId, orderType,isMember, cartGoodsList, coupons, sendGoodsList,BusinessTypeEnum.getByType(menuType).getCode(),null);
        }

        return calculationDiscountResult;
    }

    public Long calculateDeliveryAmount(String receiveId, String partnerId, String storeId, String wxappid, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,Integer orderType) {
        Long deliveryAmount = 0L;
        // 如果订单的收获地址为空，且订单是外卖单，返回运费
        // 主要是为了兼容coco不传收获地址，需要获取固定运费的情况
        if (StringUtils.isBlank(receiveId) && !Objects.equals(orderType, CreateOrderType.TAKE_OUT.getCode())) {
            return deliveryAmount;
        }
        log.info("获取配送配逻辑 tackingNo:{},storeDeliveryUseOld:{},receiveId:{},partnerId:{},storeId:{}", LogThreadLocal.getTrackingNo(), storeDeliveryUseOld, receiveId, partnerId, storeId);
        if (storeDeliveryUseOld) {
            deliveryAmount = Long.parseLong(getDeliveryAmount(receiveId, partnerId, storeId).toString());
            shoppingCartGoodsResponseVo.setDeliveryFeeZeroReason(0);
        } else {
            deliveryAmount = getNewDeliveryAmount(receiveId, partnerId, storeId, shoppingCartGoodsResponseVo,orderType);
        }
        return deliveryAmount;

    }

    private CustomerInfoVo getCustomerInfoVo(String sessionId) {
        GetSessionUserInfoDto getSessionUserInfoDto = new GetSessionUserInfoDto();
        getSessionUserInfoDto.setIsGetPaid(true);
        getSessionUserInfoDto.setSessionId(sessionId);
        BaseResponse<CustomerInfoVo> sessionUserInfo = customerApplicationClient.getSessionUserInfo(getSessionUserInfoDto);
        if (!ResponseResult.SUCCESS.getCode().equals(sessionUserInfo.getCode()) || sessionUserInfo.getResult() == null) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        return sessionUserInfo.getResult();
    }

    /**
     * 检查sku数量
     *
     * @param allCartGoodsList
     * @param cartGoods
     * @return
     */
    private Integer checkSkuQty(List<CartGoods> allCartGoodsList, CartGoods cartGoods) {
        Integer qty = 0;
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            qty = cartGoods.getQty();
        } else {
            qty = cartGoods.getQty();
            for (CartGoods goods : allCartGoodsList) {
                if (goods.getSkuId().equals(cartGoods.getSkuId()) && goods.getSpuId().equals(cartGoods.getSpuId())) {
                    qty += goods.getQty();
                }
            }
        }
        return qty;
    }

    /**
     * 去除非活动商品的提示
     *
     * @param shoppingCartGoodsResponseVo
     * @param cartUid
     */
    public void clearMsg(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String cartUid) {
        if (StringUtils.isNotBlank(shoppingCartGoodsResponseVo.getToastMsg()) && StringUtils.isNotBlank(shoppingCartGoodsResponseVo.getUid()) && !cartUid.equals(shoppingCartGoodsResponseVo.getUid())) {
            shoppingCartGoodsResponseVo.setUid("");
            shoppingCartGoodsResponseVo.setToastMsg("");
        }
    }

    /**
     * @param partnerId
     * @param storeId
     * @return
     */
    public boolean grayPush(String partnerId, String storeId, String version) {

        if (StringUtils.isBlank(sharing)) return false;
        CalculateCenter center = JSON.parseObject(sharing, CalculateCenter.class);
        Boolean enable = false;
        if (!center.getEnable()) return false;
        switch (center.getType()) {
            case 2:
                enable = true;
                break;
            case 1: {
                //商户+门店级别
                String real = partnerId.concat(storeId);
                if (Arrays.asList(center.getGrayList().split(",")).contains(real)) {
                    enable = true;
                }
                //商户级别
                else if (Arrays.asList(center.getGrayList().split(",")).contains(partnerId)) {
                    enable = true;
                }
            }
        }
        if (center.getEnable() && enable) {
            enable = true;
        }
        return enable;
    }


    /**
     * 查询生态配置限制加购开关与限制数量
     */
    public Integer limitGoodsQty(List<CartGoods> oldCartGoodsList, CartGoods cartGoods,String appid){
        Integer qty = 0;
        if(CollectionUtils.isNotEmpty(oldCartGoodsList)){
            for (CartGoods goods : oldCartGoodsList) {
                qty += goods.getQty();
            }
        }
        qty += cartGoods.getQty();
        String redisKey = limitCartKey + appid;

        Object value = redisCache.hashGet(redisKey, "2");
        if (value == null) {
            return qty;
        } else {
            boolean bool = value.getClass().getName().equals("java.lang.String");
            if(bool){
                return qty;
            }
            JSONArray jsonArray = (JSONArray)value;
            int cartLimitFlag = 0;
            int cartLimitCount = 0;
            for (Object object : jsonArray){
                JSONObject jsonObject = (JSONObject)object;
                HashMap hashMap = JSONObject.parseObject(jsonObject.toJSONString(),HashMap.class);
                if("cartLimitFlag".equals(hashMap.get("appKey"))){
                    if (StringUtils.isBlank((String)hashMap.get("appValue"))) {
                        return qty;
                    }
                    cartLimitFlag = Integer.parseInt((String)hashMap.get("appValue"));
                }
                if("cartLimitCount".equals(hashMap.get("appKey"))){
                    if (StringUtils.isBlank((String)hashMap.get("appValue"))) {
                        return qty;
                    }
                    cartLimitCount = Integer.parseInt((String)hashMap.get("appValue"));
                }
            }
            if(cartLimitFlag == 1 && cartLimitCount != 0 && qty > cartLimitCount){
                throw new ServiceException(ResponseResult.SHOPPING_CART_LIMIT_ADD);
            }
        }
        return qty;
    }


    /**
     * 购物车添加完成后促销返回赠送商品总数量校验
     */
    public void sendGoodsQtyCheck(Integer checkQty,String appid,String partnerId, String userId, String storeId, String tableNumber,List<CartGoods> oldCartGoodsList, ShoppingCartBaseService shoppingCartService,List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendActivitys){
        if(CollectionUtils.isEmpty(sendActivitys)){
            return;
        }
        int sendQty = 0;
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity sendActivity : sendActivitys){
            for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods sendGoods : sendActivity.getSendGoods()){
                sendQty += sendGoods.getSendNumber();
            }
        }
        String redisKey = limitCartKey + appid;

        Object value = redisCache.hashGet(redisKey, "2");
        if (value == null) {
            return ;
        } else {
            boolean bool = value.getClass().getName().equals("java.lang.String");
            if(bool){
                return;
            }
            JSONArray jsonArray = (JSONArray)value;
            int cartLimitFlag = 0;
            int cartLimitCount = 0;
            for (Object object : jsonArray){
                JSONObject jsonObject = (JSONObject)object;
                HashMap hashMap = JSONObject.parseObject(jsonObject.toJSONString(),HashMap.class);
                if("cartLimitFlag".equals(hashMap.get("appKey"))){
                    if (StringUtils.isBlank((String)hashMap.get("appValue"))) {
                        return;
                    }
                    cartLimitFlag = Integer.parseInt((String)hashMap.get("appValue"));
                }
                if("cartLimitCount".equals(hashMap.get("appKey"))){
                    if (StringUtils.isBlank((String)hashMap.get("appValue"))) {
                        return;
                    }
                    cartLimitCount = Integer.parseInt((String)hashMap.get("appValue"));
                }
            }
            if(cartLimitFlag == 1 && cartLimitCount != 0 && checkQty+sendQty > cartLimitCount){
                assortmentSdkService.setShoppingCart( partnerId,  storeId,  userId,  oldCartGoodsList,  null,  tableNumber,  shoppingCartService);
                throw new ServiceException(ResponseResult.SHOPPING_CART_LIMIT_ADD);
            }
        }

    }

    /**
     * 购物车添加完成后促销返回赠送商品总数量校验
     */
    public void sendGoodsQtyCheckForUpdate(List<CartGoods> cartGoodsList,Integer goodsQty,String appid,String partnerId, String userId, String storeId, String cartGoodsUid,String tableNumber, ShoppingCartBaseService shoppingCartService,List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendActivitys){
        Integer updateQty = 0;
        if(CollectionUtils.isNotEmpty(cartGoodsList)){
            for (CartGoods goods : cartGoodsList) {
                updateQty += goods.getQty();
            }
        }

        String redisKey = limitCartKey + appid;

        Object value = redisCache.hashGet(redisKey, "2");
        if (value == null) {
            return ;
        } else {
            boolean bool = value.getClass().getName().equals("java.lang.String");
            if(bool){
                return;
            }
            JSONArray jsonArray = (JSONArray)value;
            int cartLimitFlag = 0;
            int cartLimitCount = 0;
            for (Object object : jsonArray){
                JSONObject jsonObject = (JSONObject)object;
                HashMap hashMap = JSONObject.parseObject(jsonObject.toJSONString(),HashMap.class);
                if("cartLimitFlag".equals(hashMap.get("appKey"))){
                    if (StringUtils.isBlank((String)hashMap.get("appValue"))) {
                        return;
                    }
                    cartLimitFlag = Integer.parseInt((String)hashMap.get("appValue"));
                }
                if("cartLimitCount".equals(hashMap.get("appKey"))){
                    if (StringUtils.isBlank((String)hashMap.get("appValue"))) {
                        return;
                    }
                    cartLimitCount = Integer.parseInt((String)hashMap.get("appValue"));
                }
            }

            int sendQty = 0;
            if(CollectionUtils.isNotEmpty(sendActivitys)){
                for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity sendActivity : sendActivitys){
                    for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods sendGoods : sendActivity.getSendGoods()){
                        sendQty += sendGoods.getSendNumber();
                    }
                }
            }
            if(cartLimitFlag == 1 && cartLimitCount != 0 && updateQty+sendQty > cartLimitCount){
                assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoodsUid, goodsQty, "", shoppingCartBaseService);
                throw new ServiceException(ResponseResult.SHOPPING_CART_LIMIT_ADD);
            }
        }

    }

    /**
     * 获取混合支付是否开启
     * @param partnerId
     * @return
     */
    private boolean checkSvcComPay(String partnerId,String storeId) {
        SvcComPayRequestDto requestDto = new SvcComPayRequestDto();
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        SvcComPayResponseDto query = null;
        for (int i=0;i<3;i++) {
            query = svcComPayClient.query(requestDto);
            if (query!=null) break;
        }
        if (query==null || !ResponseResult.SUCCESS.getCode().equals(query.getCode())) {
            return false;
        }
        if (query.getResult()!=null && query.getResult().getValue()) {
            return true;
        }
        else {
            return false;
        }
    }

    private boolean checkAvailableCoupon(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String couponCode) {
        if (StringUtils.isBlank(couponCode)){
            return true;
        }
        if (shoppingCartGoodsResponseVo == null || shoppingCartGoodsResponseVo.getAvailableCoupon() == null || shoppingCartGoodsResponseVo.getAvailableCoupon().getDisableCoupons() == null){
            return true;
        }
        List<ActivityCouponBean> disableCoupons = shoppingCartGoodsResponseVo.getAvailableCoupon().getDisableCoupons();
        ActivityCouponBean activityCouponBean = disableCoupons.stream().filter(p -> p.getCouponCode().equals(couponCode)).findFirst().orElse(null);
        if (activityCouponBean == null){
            return true;
        } else {
            return false;
        }
    }
    /**
     * 设置总的优惠信息和商品优惠信息
     * @param shoppingCartGoodsResponseVo
     * @param discountResult
     */
    private void buildShoppingCartGoodsResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,
                                                CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult,
                                                Integer flag,
                                                String partnerId) {

        ShoppingCartRelationService shoppingCartRelationService = shoppingCartRelationFactory.getBuildShoppingCartGoodsResponseService(partnerId);
        shoppingCartRelationService.buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,discountResult,flag);

    }

    private List<CalculationSharingDiscountRequestDto.CalculationDiscountCoupon> buildCoupons(List<CalculationSharingDiscountRequestDto.CalculationDiscountCoupon> oldCoupons, List<ShoppingCartInfoRequestVo.couponCode> coupons){


        ApiLog.info("批量使用优惠券前，oldCoupons,coupons",oldCoupons,coupons);

        for(int i = 0 ; i < oldCoupons.size() ; i++){
            CalculationSharingDiscountRequestDto.CalculationDiscountCoupon oldCoupon = oldCoupons.get(i);
            oldCoupon.setUseIndex(i);
        }



        List<String> codes = oldCoupons.stream().map(CalculationSharingDiscountRequestDto.CalculationDiscountCoupon::getCode).collect(toList());

        if (coupons != null) {
            for(int x = 0 ; x < coupons.size() ; x++){
                ShoppingCartInfoRequestVo.couponCode cp  = coupons.get(x);
                if(codes.contains(cp.getCouponCode())){
                    continue;
                }
                CalculationSharingDiscountRequestDto.CalculationDiscountCoupon coupon = new CalculationSharingDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(cp.getCouponCode());
                coupon.setActivityCode(cp.getActivityCode());
                coupon.setUseIndex(cp.getIndex() == null ? x + oldCoupons.size():  cp.getIndex() + oldCoupons.size());
                oldCoupons.add(coupon);
            }
        }

        ApiLog.info("批量使用优惠券后，oldCoupons,coupons",oldCoupons,coupons);

        return oldCoupons;
    }

    /**
     * 获取会员服务的优惠券列表
     *
     * @param getMemberCouponListRequestDto
     * @return
     */
    public GetMemberCouponListResponseDto.Result getMemberCouponList(GetMemberCouponListRequestDto getMemberCouponListRequestDto) {
        GetMemberCouponListResponseDto getMemberCouponListResponseDto = null;
        try {
            getMemberCouponListResponseDto = customerExtendClient.getMemberCouponListRequestDto(getMemberCouponListRequestDto);
        } catch (Exception ex) {
            log.error("会员服务优惠券接口调用失败", ex);
        }
        if (getMemberCouponListResponseDto != null && Objects.equals(getMemberCouponListResponseDto.getCode(), ResponseResult.SUCCESS.getCode())) {
            return getMemberCouponListResponseDto.getData();
        }
        return null;
    }
}
