/**
 * 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.adapter.StoreItemAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.demo.controller.ShoppingCartDemoController;
import cn.freemud.demo.entities.dto.goods.add.list.BaseListCartGoodsVO;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.activity.ActivityQueryResponseDto;
import cn.freemud.entities.dto.activity.DiscountSharingDto;
import cn.freemud.entities.dto.calculate.*;
import cn.freemud.entities.dto.openplatform.WeixinProductRequestDto;
import cn.freemud.entities.dto.openplatform.WeixinProductResponseDto;
import cn.freemud.entities.dto.order.PackAmountConfig;
import cn.freemud.entities.dto.other.ValidCouponBo;
import cn.freemud.entities.dto.pay.*;
import cn.freemud.entities.dto.product.CheckCartRequest;
import cn.freemud.entities.dto.product.info.ProductBean;
import cn.freemud.entities.dto.product.info.SkuProductBean;
import cn.freemud.entities.dto.shoppingCart.PromotionResultVO;
import cn.freemud.entities.dto.shoppingCart.SendPoint;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.dto.user.GetUserScoreUseDetailRequest;
import cn.freemud.entities.dto.user.GetUserScoreUserDetailResponse;
import cn.freemud.entities.vo.*;
import cn.freemud.entities.vo.coupon.CouponAvailableCartInfo;
import cn.freemud.entities.vo.coupon.CouponAvailableRequestVo;
import cn.freemud.enums.*;
import cn.freemud.handle.CommonFunctionHandle;
import cn.freemud.handle.GetActivityMsgHandle;
import cn.freemud.interceptor.BizServiceException;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.*;
import cn.freemud.service.cache.GiftCacheManager;
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.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerStoreDeliveryConfigManager;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.base.SDKCommonBaseContextWare;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.request.StatisticalScoreRequest;
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.ordercenter.enums.ProductTypeEnum;
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.service.ShoppingCartBaseService;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import com.google.common.collect.Lists;
import ma.glasnost.orika.MapperFacade;
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 javax.annotation.Resource;
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;

@Service
public class ShoppingCartNewServiceImpl implements ShoppingCartNewService {

    @Autowired
    private ActivityAdapter activityAdapter;
    @Autowired
    private ProductClient 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;
    @Autowired
    private AssortmentSdkService assortmentSdkService;
    @Autowired
    private CouponAdapter couponAdapter;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
    @Autowired
    private CustomerPropertyClient customerPropertyClient;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private SvcAppClient svcAppClient;
    @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;

    @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 ShoppingCartRelationFactory shoppingCartRelationFactory;
    @Resource
    private MapperFacade mapperFacade;
    @Autowired
    private ShoppingCartDemoController shoppingCartDemoController;

    @Autowired
    private StoreItemAdapter storeItemAdapter;

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

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

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

    @Value("${saas.cart.new.shopping.cart}")
    private String newShoppingCart;

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

    @Value("${goods.cache.second}")
    private long goodsCacheSeconds;

    @Autowired
    private CommonFunctionHandle commonFunctionHandle;

    @Autowired
    private GetActivityMsgHandle getActivityMsgHandle;
    @Autowired
    private GiftCacheManager giftCacheManager;

    /**
     * 从微信卡券向购物车中添加商品
     */
    @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);
            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())) {
            return ResponseUtil.error(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(); // 商品券和换购券券号
        Integer bizType = addShoppingCartGoodsRequestVo.getBizType(); // 7-爱马哥预定单
        Integer accountFlag = 0; //非结算页
        if (spuId.startsWith(CommonsConstant.COUPON_PREFIX)) { // 兼容老版本
            couponCode = spuId.substring(CommonsConstant.COUPON_PREFIX.length());
        }

        CartGoods cartGoods = ShoppingCartConvertAdapter.convent2CartGoods(addShoppingCartGoodsRequestVo);
        List<Long> productIds = new ArrayList<>();
        //商品skuId或者商品券的商品id
        String spuId2 = spuId;
        CouponProductDto couponProductDto = new CouponProductDto();
        Integer todayAvailableTimes = 0;
        if (StringUtils.isBlank(couponCode)) {
            productIds.add(Long.parseLong(goodsId));
        } else {
            //校验券是否有效  这里是新的商品券支持多商品及换购券
            ValidCouponBo validCouponBo = assortmentSdkService.validCoupon(partnerId, storeId, couponCode, productIds,
                    BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode(), skuId, couponProductDto,cartGoods);
            spuId2 = validCouponBo.getSkuId();
            todayAvailableTimes = validCouponBo.getTodayAvailableTimes();
            if (StringUtils.isNotBlank(skuId)) {
                cartGoods.setGoodsId(spuId);
            }
        }

        // 获取商品详细信息
        List<ProductBean> productBeanListSpuClass = assortmentSdkService.getProductsInfo(partnerId, storeId
                , Collections.singletonList(spuId2), addShoppingCartGoodsRequestVo.getMenuType(), this.shoppingCartBaseService);

        // 没有查到商品
        if (productBeanListSpuClass == null || productBeanListSpuClass.isEmpty()) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_PRODUCT_NOT_EXIST);
        }

        // 检查商品小料数量
        if (checkMaterialQty(addShoppingCartGoodsRequestVo, productBeanListSpuClass)) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_MATERIA_QTY_LIMIT_ERR);
        }

        //缓存中获取购物车商品信息
        // 注意，围餐和点餐redis数据结构不一样
        List<CartGoods> allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, addShoppingCartGoodsRequestVo.getSessionId(), null, shoppingCartBaseService,bizType);
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            allCartGoodsList = new ArrayList<>();
        }
        List<CartGoods> oldCartGoodsList = BeanUtil.convertBeans(allCartGoodsList, CartGoods::new);

        Integer checkQty = this.checkSkuQty(allCartGoodsList, cartGoods);
        //购物车添加数量限制
        Integer productsCount = limitGoodsQty(allCartGoodsList, cartGoods, appId, partnerId);
        //查询多个商品库存信息 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, todayAvailableTimes);
        }
        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo.getOrderType());

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, addShoppingCartGoodsRequestVo.getOrderType());
        activityQueryDto.setBizType(bizType);

        if (grayPush(partnerId, storeId, "2")) {
            CalculationDiscountResult discountResult = null;
            discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType, partnerId, storeId, userId
                    , appId, orderType, assortmentCustomerInfoVo.isMemberPaid(), allCartGoodsList
                    , new ArrayList<>() //结算页选中的代金券
                    , null //加价购商品
                    , deliveryAmount, null,bizType, accountFlag,new DiscountSharingDto(),this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            //更新购物车券状态
            newCalculationUpdateCouponStatus(userId, partnerId, storeId, bizType, cartGoods, allCartGoodsList, discountResult);
            sharingCartService.distribute(discountResult, allCartGoodsList, shoppingCartGoodsResponseVo, null
                    , userLoginInfoDto, null, activityQueryDto, menuType, deliveryAmount
                    , ShoppingCartConstant.ADD_AND_UPDATE, partnerId, null, userId, storeId,this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));

            buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo, discountResult, null, partnerId);
            //
        } else {
            // 获取优惠信息
            CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId, userLoginInfoDto.getWxAppid(), orderType, assortmentCustomerInfoVo.isMemberPaid(), allCartGoodsList, new ArrayList(), new ArrayList<>(), null, deliveryAmount,bizType, accountFlag, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getSendGoods())){
                sendGoodsQtyCheck(productsCount, appId, partnerId, userId, storeId, tableNumber, oldCartGoodsList, shoppingCartBaseService, calculationDiscountResult.getSendGoods(),bizType);
            }
            //更新买M N券 券状态
            calculationUpdateCouponStatus(userId, partnerId, storeId, bizType, allCartGoodsList, calculationDiscountResult);

            // 当商品数量被设为0时
            if (Objects.equals(cartGoods.getQty(), 0)) {
                assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoods.getCartGoodsUid(), 0, "", shoppingCartBaseService,bizType);
            }
            // 促销活动的优惠金额计算
            updateShoppingCartGoodsDiscount(null, activityQueryDto, calculationDiscountResult, allCartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto, addShoppingCartGoodsRequestVo.getMenuType(), deliveryAmount, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            clearMsg(shoppingCartGoodsResponseVo, cartGoods.getCartGoodsUid());

            //设置更新响应信息
            setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, allCartGoodsList, null, partnerId, storeId, userId, ShoppingCartConstant.ADD_AND_UPDATE, null);
        }
        //埋点添加购物车行为
        this.buriedPointShoppingCart(addShoppingCartGoodsRequestVo, spuId, productName);
        this.shoppingCartAddOrListCommonResponseHandle(shoppingCartGoodsResponseVo);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    private void calculationUpdateCouponStatus(String userId, String partnerId, String storeId, Integer bizType, List<CartGoods> allCartGoodsList, CalculationDiscountResult calculationDiscountResult) {
        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
            String activityCouponCode = null;
            List<CouponResults> couponDiscounts = calculationDiscountResult.getCouponDiscounts();
            List<CouponResults> couponResults = null;
            if (CollectionUtils.isNotEmpty(couponDiscounts)) {
                couponResults = couponDiscounts.stream().filter(discount -> ActivityTypeEnum.TYPE_330.getCode().equals(discount.getActivityType())).collect(toList());
            }
            if (CollectionUtils.isNotEmpty(couponResults)) {
                CouponResults coupon = couponDiscounts.get(0);
                activityCouponCode = coupon.getCouponCode();
            }
            if (StringUtils.isNotBlank(activityCouponCode)) {
                String finalActivityCouponCode = activityCouponCode;
                List<CartGoods> couponCartGoods = allCartGoodsList.stream().filter(good -> finalActivityCouponCode.equals(good.getCouponCode())).collect(toList());
                //更新购物车状态
                assortmentSdkService.updateGoodsCouponStatus(partnerId, userId, storeId, couponCartGoods, shoppingCartBaseService, bizType);
            }
        }
    }


    /**
     * 埋点添加购物车行为
     *
     * @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())) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
//            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();
        Integer bizType = updateShoppingCartGoodsQtyRequestVo.getBizType();
        Integer accountFlag = 0; //非结算页


        // 先验证商品是否存在
        CartGoods cartGoods = assortmentSdkService.getCartGoodsBySdk(partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService,bizType);
        if (cartGoods == null) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
//            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,bizType);

        // 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,bizType);
        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo, updateShoppingCartGoodsQtyRequestVo.getOrderType());

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, updateShoppingCartGoodsQtyRequestVo.getOrderType());
        activityQueryDto.setBizType(bizType);
        // 根据商户门店判断是否走新促销
        if (grayPush(partnerId, storeId, "2")) {
            CalculationDiscountResult discountResult = null;
            discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , new ArrayList() //券
                    , null //加价购商品
                    , deliveryAmount
                    , null,bizType, accountFlag,new DiscountSharingDto(), this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            //校验加购数量
            if (discountResult != null) {
                sendGoodsQtyCheckForUpdate(cartGoodsList, oldQty, appId, partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService, discountResult.getSendGoods(),bizType);
            }
            newCalculationUpdateCouponStatus(userId, partnerId, storeId, bizType, cartGoods, cartGoodsList, discountResult);

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

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

        }
        this.shoppingCartAddOrListCommonResponseHandle(shoppingCartGoodsResponseVo);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }


    private void newCalculationUpdateCouponStatus(String userId, String partnerId, String storeId, Integer bizType, CartGoods cartGoods, List<CartGoods> cartGoodsList, CalculationDiscountResult discountResult) {
        List<Discount> discounts = null;
        if (null != discountResult) {
             discounts = discountResult.getDiscounts();
        }
        List<Discount> mnCouponDiscount = null;

        if (CollectionUtils.isNotEmpty(discounts)) {
            mnCouponDiscount = discounts.stream().filter(discount -> ActivityTypeEnum.TYPE_330.getCode().equals(discount.getType())).collect(toList());
        }
        String mnCouponCode = null;
        if (CollectionUtils.isNotEmpty(mnCouponDiscount)) {
            Discount discount = mnCouponDiscount.get(0);
            mnCouponCode = discount.getActivityCode();

        }
        if (StringUtils.isNotBlank(mnCouponCode) && mnCouponCode.equals(cartGoods.getCouponCode())) {
            String finalMnCouponCode = mnCouponCode;
            List<CartGoods> couponCartGoods = cartGoodsList.stream().filter(good -> finalMnCouponCode.equals(good.getCouponCode())).collect(toList());
            //更新购物车状态
            assortmentSdkService.updateGoodsCouponStatus(partnerId, userId, storeId,couponCartGoods,  shoppingCartBaseService,bizType);
        }
    }

    /**
     * 检查购物车商品库存数量
     *
     * @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);
        this.commonItemVerfity(BusinessTypeEnum.getByType(updateShoppingCartGoodsQtyRequestVo.getMenuType()).getCode(),
                partnerId,
                storeId,
                Collections.singletonList(Long.parseLong(cartGoods.getGoodsId())),
                qty);

    }


    /**
     * 购物车商品详情接口
     * 配送券入口
     *
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsList(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (StringUtils.isEmpty(shoppingCartInfoRequestVo.getShopId())) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }
        if (StringUtils.isEmpty(shoppingCartInfoRequestVo.getVersion())) {
            shoppingCartInfoRequestVo.setVersion("");
        }
        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();
        List<ChooseCouponVo> couponCodes = shoppingCartInfoRequestVo.getCouponCodes();
        Integer bizType = shoppingCartInfoRequestVo.getBizType();
        // 1 为结算页
        Integer accountFlag = shoppingCartInfoRequestVo.getFlag();

        // 兼容老版本
        if (CollectionUtils.isNotEmpty(couponCodes) && StringUtils.isEmpty(couponCode)) {
            ChooseCouponVo otherCouponCode = couponCodes.stream()
                    .filter(couponCode1 -> couponCode1.getCouponType() != null && couponCode1.getCouponType().compareTo(CouponTypeEnum.TYPE_5.getCode()) != 0)
                    .findFirst().orElse(null);
            if (otherCouponCode != null) {
                // 由于对下面逻辑 不是很清楚 并且修改了 优惠券传参规则 所以直接设置一遍 防止出错
                shoppingCartInfoRequestVo.setCouponCode(otherCouponCode.getCouponCode());
                shoppingCartInfoRequestVo.setActivityCode(otherCouponCode.getActivityCode());
            }
        }

        String menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        String receiveId = shoppingCartInfoRequestVo.getReceiveId();
        String unChooseCouponCode = shoppingCartInfoRequestVo.getUnChooseCouponCode();

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService,bizType);
        // 如果购物车商品不为空， 则check购物车中所有商品
        if (CollectionUtils.isNotEmpty(cartGoodsList)) {
            // check是否反选取消商品券
            if (StringUtils.isNotBlank(unChooseCouponCode)) {
                // 遍历该商品券选择的商品,并将商品券替换为普通商品
                for (int i = cartGoodsList.size() - 1; i >= 0; i--) {
                    CartGoods cartGoods = cartGoodsList.get(i);

                    if (GoodsTypeEnum.couponTypeList.contains(cartGoods.getGoodsType())) {
                        if (Objects.equals(cartGoods.getCouponCode() ,unChooseCouponCode)) {
                            CheckSpqInfoRequestDto checkSpqInfoRequestDto = new CheckSpqInfoRequestDto(partnerId, storeId, cartGoods.getCouponCode(), menuType,null);
                            GetProductsVo productInfo = null;
                            if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType()) || GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType().equals(cartGoods.getGoodsType())) {
                                productInfo = couponService.getSpqProductInfo(checkSpqInfoRequestDto, cartGoods.getSkuId());
                            } else {
                                productInfo = couponService.getSpqProductInfo(checkSpqInfoRequestDto);
                            }
                            //取消套餐商品券，直接移除
                            if (productInfo == null || (cartGoods.getCouponCode() != null && CollectionUtils.isNotEmpty(cartGoods.getProductComboList()))) {
                                cartGoodsList.remove(i);
                            } else {
                                convert2CartGoods(cartGoods, productInfo);
                            }
                        }

                    }
                }
            }

            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,bizType);
        }

        // 获取基础运费,并且 组装 deliveryAmountList字段: 额外配送费 如夜间配送费等
        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType());

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartInfoRequestVo.getOrderType());
        activityQueryDto.setBizType(bizType);
        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);
        // fisherman 作用: 调用可选优惠券 计算 配送券是否可用
        couponPromotionVO.setDeliveryAmount(deliveryAmount);
        if (grayPush(partnerId, storeId, "2")) {
            ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            if (StringUtils.isNotEmpty(couponCode)) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.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);
                }
            }
            CalculationDiscountResult calculationSharingDiscountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , coupons
                    , sendGoods
                    , deliveryAmount
                    , null
                    ,bizType, accountFlag,new DiscountSharingDto(), this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            sharingCartService.distribute(calculationSharingDiscountResult
                    , cartGoodsList
                    , shoppingCartGoodsResponseVo
                    , shoppingCartInfoRequestVo
                    , userLoginInfoDto
                    , couponPromotionVO
                    , activityQueryDto
                    , menuType
                    , deliveryAmount
                    , ShoppingCartConstant.QUERY_INFO
                    , partnerId
                    , shoppingCartInfoRequestVo.getFlag()
                    , userId
                    , storeId,this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            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);
            }
            // 配送券信息放入 用于促销计算
            if (CollectionUtils.isNotEmpty(shoppingCartInfoRequestVo.getCouponCodes())) {
                shoppingCartInfoRequestVo.getCouponCodes().forEach(shoppingCode -> {
                    ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                    if (!shoppingCode.getCouponCode().equals(couponCode)) {
                        coupon.setCode(shoppingCode.getCouponCode());
                        coupon.setActivityCode(shoppingCode.getActivityCode());
                        coupon.setCouponType(shoppingCode.getCouponType());
                        coupons.add(coupon);
                    }
                });
            }
            long nightDistributionFee = this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList());

            // 获取优惠信息 调用促销
            CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId,
                    userLoginInfoDto.getWxAppid(), orderType, assortmentCustomerInfoVo.isMemberPaid(),
                    cartGoodsList, coupons, null, shoppingCartInfoRequestVo.getReceiveId(), deliveryAmount,bizType, accountFlag, nightDistributionFee);
            if (calculationDiscountResult == null) {
                shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
            }
            // 促销活动的优惠金额计算
            this.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto, shoppingCartInfoRequestVo.getMenuType(), deliveryAmount, nightDistributionFee);
            //设置更新响应信息
            setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, userId, ShoppingCartConstant.QUERY_INFO, shoppingCartInfoRequestVo);
            // 在原价、现价、折扣价上增加第一次使用会员卡的费用
            this.addNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsResponseVo);
        }
        // 添加购物车商品总价和加价购商品总价,现在是自己计算,后面需要优化为促销计算, 这段要删除
//        shoppingCartGoodsResponseVo.setShoppingCartGoodsAmount(0L);
//        if (CollectionUtils.isNotEmpty(shoppingCartGoodsResponseVo.getProducts())) {
//            long shoppingCartGoodsAmount = shoppingCartGoodsResponseVo.getProducts().stream().mapToLong(CartGoods::getAmount).sum();
//            shoppingCartGoodsResponseVo.setShoppingCartGoodsAmount(shoppingCartGoodsAmount);
//        }

        if (CollectionUtils.isNotEmpty(shoppingCartInfoRequestVo.getSendGoods())) {
            PremiumExchangeRequestVo request = new PremiumExchangeRequestVo();
            request.setPartnerId(shoppingCartInfoRequestVo.getPartnerId());
            request.setActivityCode(shoppingCartInfoRequestVo.getActivityCode());
            request.setCouponCode(shoppingCartInfoRequestVo.getCouponCode());
            request.setMenuType(shoppingCartInfoRequestVo.getMenuType());
            request.setOrderType(shoppingCartInfoRequestVo.getOrderType());
            request.setSessionId(shoppingCartInfoRequestVo.getSessionId());
            request.setShopId(shoppingCartInfoRequestVo.getShopId());
//            request.setVersion(shoppingCartInfoRequestVo.getVersion());
            if (CollectionUtils.isNotEmpty(shoppingCartInfoRequestVo.getCouponCodes())) {
                List<PremiumExchangeRequestVo.couponCode> list = new ArrayList<>();
                shoppingCartInfoRequestVo.getCouponCodes().forEach(code -> {
                    PremiumExchangeRequestVo.couponCode vo = new PremiumExchangeRequestVo.couponCode();
                    vo.setActivityCode(code.getActivityCode());
                    vo.setCouponCode(code.getCouponCode());
                    vo.setCouponType(code.getCouponType());
                    vo.setIndex(code.getIndex());
                    list.add(vo);
                });
                request.setCouponCodes(list);
            }
            BaseResponse<PremiumExchangeResponseVo> premiumExchangeResponseVoBaseResponse = premiumExchange(request);
            List<PremiumExchangeResponseVo.PremiumExchangeProduct> chooseSendGoodList = null;
            if (premiumExchangeResponseVoBaseResponse != null && ResponseResult.SUCCESS.getCode().equals(premiumExchangeResponseVoBaseResponse.getCode())
                    && premiumExchangeResponseVoBaseResponse.getResult() != null && CollectionUtils.isNotEmpty(premiumExchangeResponseVoBaseResponse.getResult().getProducts())) {
                List<PremiumExchangeResponseVo.PremiumExchangeProduct> products = premiumExchangeResponseVoBaseResponse.getResult().getProducts();
                List<String> sendGoodsIdList = shoppingCartInfoRequestVo.getSendGoods().stream().map(p -> p.getGoodsId()).collect(toList());
                chooseSendGoodList = products.stream().filter(p -> sendGoodsIdList.contains(p.getSkuId()) || sendGoodsIdList.contains(p.getSpuId())).collect(toList());
                long sendGoodsAmount = chooseSendGoodList.stream().mapToLong(PremiumExchangeResponseVo.PremiumExchangeProduct::getNowPrice).sum();
                shoppingCartGoodsResponseVo.setSendGoodsAmount(sendGoodsAmount);
                // fisherman 需要加上原价-->  新算价已经在促销加过, 不需要再加
                if (!grayPush(partnerId, storeId, "2")) {
                    long sendOriginalGoodsAmount = chooseSendGoodList.stream().mapToLong(PremiumExchangeResponseVo.PremiumExchangeProduct::getOriginalPrice).sum();
                    shoppingCartGoodsResponseVo.setShoppingCartOriginalGoodsAmount(shoppingCartGoodsResponseVo.getShoppingCartOriginalGoodsAmount() + sendOriginalGoodsAmount);
                }
            }
            updateForPopupWindow(shoppingCartGoodsResponseVo, premiumExchangeResponseVoBaseResponse.getResult().getShowType(), chooseSendGoodList, shoppingCartInfoRequestVo.getSendGoods());
        }
        // 设置优惠券的使用门槛金额, 需要排除券的金额
        this.shoppingCartAddOrListCommonResponseHandle(shoppingCartGoodsResponseVo);
        // 校验入参券是否可用
        if (!checkAvailableCoupon(shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getCouponCode())) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_COUPON_NOT_USE);
        }
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     *  加车 和list接口 公用处理方法
     * @param shoppingCartGoodsResponseVo
     */
    private void shoppingCartAddOrListCommonResponseHandle(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo){
        if (Objects.isNull(shoppingCartGoodsResponseVo)) {
            return;
        }
        // 设置 使用信息
        Long useCouponThreshold = this.getUseCouponThreshold(shoppingCartGoodsResponseVo.getProducts());
        shoppingCartGoodsResponseVo.setUseCouponThreshold(useCouponThreshold);
        // 如果有夜间配送费 需要维护划线价  deliveryAmount 字段, ___> 注意, 配送费的优惠是 促销在算(又特么各算一半,这产品真是恶心)
        //shoppingCartGoodsResponseVo.setDeliveryAmount(this.responseDataMaintain2DeliverAmount(shoppingCartGoodsResponseVo.getDeliveryAmount(),this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList())));

        // 设置单点不可下单标志
        setNonSingleOrder(shoppingCartGoodsResponseVo);
    }

    /**
     * 如果有夜间配送费 需要维护划线价  deliveryAmount 字段, ___> 注意, 配送费的优惠是 促销在算(又特么各算一半,这产品真是恶心)
     * @param deliveryAmount
     * @param nightDistributionFee
     * @return
     */
    private Long responseDataMaintain2DeliverAmount(Long deliveryAmount,long nightDistributionFee){
        if (Objects.isNull(deliveryAmount)) {
            deliveryAmount = 0L;
        }
        if (nightDistributionFee < 0){
            return deliveryAmount;
        }
        return deliveryAmount + nightDistributionFee;
    }

    /**
     *  获取 券使用的门槛信息
     * @param products
     * @return
     */
    private Long getUseCouponThreshold(List<CartGoods> products) {
        Long useCouponThreshold = 0L;
        if (CollectionUtils.isNotEmpty(products)) {
            // 过滤出 活动商品 以及 优惠券商品  求和
//            return products.stream().filter(p -> !GoodsTypeEnum.couponTypeList.contains(p.getGoodsType()) && Objects.isNull(p.getActivityType()))
//                    .mapToLong(CartGoods::getOriginalAmount)
//                    .sum();
            // activityType = 61 是赠送商品 已过滤
            List<CartGoods> collect = products.stream().filter(p -> !GoodsTypeEnum.couponTypeList.contains(p.getGoodsType()) && Objects.isNull(p.getActivityType())).collect(toList());
            for (CartGoods cartGoods : collect) {
                useCouponThreshold += cartGoods.getOriginalAmount();
                // 小料
                Integer qty = cartGoods.getQty();
                if (CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
                    for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
                        useCouponThreshold += materialGoods.getOriginalAmount() * materialGoods.getQty() * qty;
                    }
                }
            }
        }
        return useCouponThreshold;
    }

    public void updateForPopupWindow(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, Integer showType, List<PremiumExchangeResponseVo.PremiumExchangeProduct> chooseSendGoodList,
                                     List<ShoppingCartInfoRequestVo.SendGoods> sendGoods) {
        if (Integer.valueOf("5").equals(showType) && !org.springframework.util.CollectionUtils.isEmpty(chooseSendGoodList)) {
            chooseSendGoodList.forEach(good -> {
                ShoppingCartInfoRequestVo.SendGoods first = null;
                first = sendGoods.stream().filter(a -> a.getGoodsId().equals(good.getSkuId()) || a.getGoodsId().equals(good.getSpuId())).findFirst().orElse(null);
                if (first == null) return;
                CartGoods cartGoods = new CartGoods();
                cartGoods.setSpuId(good.getSpuId());
                cartGoods.setSkuId(good.getSkuId());
                cartGoods.setSkuName(good.getSkuName());
                cartGoods.setOriginalAmount(good.getOriginalPrice());
                cartGoods.setFinalPrice(good.getNowPrice());
                cartGoods.setOriginalAmount(good.getOriginalPrice());
                cartGoods.setAmount(good.getNowPrice());
                cartGoods.setPhotoUrl(good.getPicture());
                // fisherman 设置虚拟券商品 属性
                cartGoods.setGoodsType(good.getProductType());
                cartGoods.setOriginalProductType(good.getProductType());
                cartGoods.setGoodsId(good.getPid());
                cartGoods.setName(good.getName());
                cartGoods.setSpuName(good.getSpuName());
                cartGoods.setQty(first.getQty());
                cartGoods.setActivityCode(first.getActivityCode());
                cartGoods.setCouponData(good.getCouponData());
                if (!CollectionUtils.isEmpty(first.getAttributes())) {
                    List<CartGoods.CartGoodsExtra> extra = new ArrayList();
                    first.getAttributes().forEach(attribute -> {
                        CartGoods.CartGoodsExtra goodsExtra = new CartGoods.CartGoodsExtra();
                        goodsExtra.setAttributeId(attribute.getAttributeId());
                        goodsExtra.setAttributeName(attribute.getAttributeValue());
                        extra.add(goodsExtra);
                    });
                    cartGoods.setExtra(extra);
                }
                shoppingCartGoodsResponseVo.getProducts().add(cartGoods);
            });
        }
    }

    private void convert2CartGoods(CartGoods cartGoods, GetProductsVo productInfo) {
        cartGoods.setCartGoodsUid(UUID.randomUUID().toString());
        Integer goodsType = GoodsTypeEnum.SPU_GOODS.getGoodsType();
        if (productInfo.getType() == null || productInfo.getType() == 1) {
            goodsType = GoodsTypeEnum.SPU_GOODS.getGoodsType();
        } else {
            goodsType = GoodsTypeEnum.SKU_GOODS.getGoodsType();
        }
        cartGoods.setGoodsType(goodsType);
        cartGoods.setAmount(productInfo.getFinalPrice());
        cartGoods.setCategoryName(productInfo.getCategoryName());
        cartGoods.setCustomerCode(productInfo.getCustomerCode());
        cartGoods.setFinalPrice(null);
        cartGoods.setGoodsId(cartGoods.getSkuId());
        cartGoods.setMaterialAmount(0l);
        cartGoods.setName(goodsType == GoodsTypeEnum.SPU_GOODS.getGoodsType() ? productInfo.getSpuName() : productInfo.getSkuName());
        cartGoods.setOriginalPrice(productInfo.getFinalPrice());
        cartGoods.setOriginalMaterialAmount(0l);
        cartGoods.setSpuId(productInfo.getSpuId());
        cartGoods.setSkuId(cartGoods.getSkuId());
        cartGoods.setSpuName(productInfo.getSpuName());
        cartGoods.setSkuName(productInfo.getSkuName());
        cartGoods.setCouponCode(null);

    }

    /**
     * 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()) && Objects.equals(shoppingCartInfoRequestVo.getOrderType(), 2)
                && StringUtils.isBlank(shoppingCartInfoRequestVo.getReceiveId())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING);
        }

        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        // 是否走重构
        if (SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).newShoppingCartGray(shoppingCartInfoRequestVo.getPartnerId(), shoppingCartInfoRequestVo.getShopId())) {
            Map requestMap = mapperFacade.map(shoppingCartInfoRequestVo, Map.class);
            BaseResponse<BaseListCartGoodsVO> goodsList = shoppingCartDemoController.listCartGoods(requestMap);

            if (goodsList == null || !ResponseResult.SUCCESS.getCode().equals(goodsList.getCode())) {
                return goodsList;
            }

            BaseListCartGoodsVO result = goodsList.getResult();
            //SVC卡支付
            SVCCardPay(shoppingCartInfoRequestVo.getCardCode(), shoppingCartInfoRequestVo.getReceiveId(), partnerId, storeId, result);
            return ResponseUtil.success(goodsList.getResult());

        } else {
            BaseResponse<ShoppingCartGoodsResponseVo> goodsList = null;
            goodsList = getGoodsList(shoppingCartInfoRequestVo);
            if (goodsList == null || !ResponseResult.SUCCESS.getCode().equals(goodsList.getCode())) {
                return goodsList;
            }
            ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = goodsList.getResult();
            //SVC卡支付
            SVCCardPay(shoppingCartInfoRequestVo.getCardCode(), shoppingCartInfoRequestVo.getReceiveId(), partnerId, storeId, shoppingCartGoodsResponseVo);
            return ResponseUtil.success(goodsList.getResult());

        }

    }

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

        String appId = shoppingCartClearRequestVo.getAppId();
        Integer bizType = shoppingCartClearRequestVo.getBizType();
        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,bizType);
        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());
        activityQueryDto.setBizType(bizType);
        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(promotionMessageDto.getActivityList());
        }
        shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        shoppingCartGoodsResponseVo.setProducts(new ArrayList<>());
        shoppingCartGoodsResponseVo.setProductsCount(0);

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

        // 清空购物车赠品的缓存信息
        giftCacheManager.clearGiftCache(partnerId, storeId, userId);
        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();
        List<ChooseCouponVo> couponCodes = shoppingCartInfoRequestVo.getCouponCodes();
        Integer bizType = shoppingCartInfoRequestVo.getBizType();
        Integer accountFlag = shoppingCartInfoRequestVo.getUseCouponFlag();

        if (Objects.isNull(couponCode) && CollectionUtils.isNotEmpty(couponCodes)) {
            // fisherman 这里可能会有问题 如果只有配送券的情况下 这里 过滤掉了 得检查后面的逻辑 是否用了list去做事情
            ChooseCouponVo otherCouponCode = couponCodes.stream()
                    .filter(couponCode1 -> couponCode1.getCouponType() != null && couponCode1.getCouponType().compareTo(CouponTypeEnum.TYPE_5.getCode()) != 0)
                    .findFirst().orElse(null);
            if (otherCouponCode != null) {
                // 由于对下面逻辑 不是很清楚 并且修改了 优惠券传参规则 所以直接设置一遍 防止出错
                shoppingCartInfoRequestVo.setCouponCode(otherCouponCode.getCouponCode());
                shoppingCartInfoRequestVo.setActivityCode(otherCouponCode.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,bizType);
        if (cartGoodsList == null) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        /**
         *  校验该名店是否有必选商品
         *  1. 调用商品服务拿到该门店是否有必选商品
         *  2. 如果有，则和购物车的商品对比
         */
        if (productService.hasRequiredProducts(partnerId, storeId, cartGoodsList, BusinessTypeEnum.getByType(shoppingCartInfoRequestVo.getMenuType()).getCode())) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_REQUIRED_PRODUCT_NOT_EXIST);
//            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);
        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);
        boolean cannotOrder = true;
        for (CartGoods p : cartGoodsList) {
            //singleOrder=1 表示为不可单点商品， 商品全部为不可单点商品时  不可下单
            cannotOrder = cannotOrder && Objects.equals(p.getSingleOrder(), 1);
        }
        if (cannotOrder) return ResponseUtil.error(ResponseResult.SHOPPING_CART_NON_SINGLE_ORDER);
        // 多规格的sku商品计算包装费
        //this.checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), tableNumber, this.shoppingCartBaseService,bizType);

        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());
        activityQueryDto.setBizType(bizType);
        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);

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

            CalculationDiscountResult discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , coupons
                    , shoppingCartInfoRequestVo.getSendGoods()
                    , deliveryAmount
                    , shoppingCartInfoRequestVo,bizType, accountFlag,new DiscountSharingDto(), this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));

            // 活动校验
            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, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
        } else {
            List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            if (StringUtils.isNotEmpty(couponCode)) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(couponCode);
                coupon.setActivityCode(activityCode);
                coupons.add(coupon);
            }
            if (!CollectionUtils.isEmpty(couponCodes)) {
                couponCodes.forEach(shoppingCouponCode -> {
                    if (!shoppingCouponCode.getCouponCode().equals(couponCode)) {
                        ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                        coupon.setCode(shoppingCouponCode.getCouponCode());
                        coupon.setActivityCode(shoppingCouponCode.getActivityCode());
                        coupon.setCouponType(shoppingCouponCode.getCouponType());
                        coupons.add(coupon);
                    }
                });
            }

            // 获取优惠信息
            CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId, userLoginInfoDto.getWxAppid(), orderType, assortmentCustomerInfoVo.isMemberPaid(), cartGoodsList, coupons, sendGoodsList, shoppingCartInfoRequestVo.getReceiveId(), deliveryAmount,bizType, accountFlag, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            //临时方案
            packgeAdditional(shoppingCartInfoRequestVo, premiumExchangeActivity);
            // 促销活动的优惠金额计算
            updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto, shoppingCartInfoRequestVo.getMenuType(), deliveryAmount, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));

            //设置更新响应信息
            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());
            }
        }
        //shoppingCartGoodsDto.setDeliveryAmount(this.responseDataMaintain2DeliverAmount(shoppingCartGoodsDto.getDeliveryAmount(), this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList())));
        return ResponseUtil.success(shoppingCartGoodsDto);
    }

    /**
     * 设置购物车是否可以下单状态
     * @param shoppingCartGoodsResponseVo
     */
    private void setNonSingleOrder(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        // 设置单点不可下单标志
        shoppingCartGoodsResponseVo.setNonSingleOrder(false);
        if (CollectionUtils.isNotEmpty(shoppingCartGoodsResponseVo.getProducts())) {
            boolean flag = true;
            for (CartGoods p : shoppingCartGoodsResponseVo.getProducts()) {
                //排除赠品
                if (Objects.equals(p.getIsSendGoods(), true)) continue;
                //singleOrder=1 表示为不可单点商品， 商品全部为不可单点商品时  不可下单
                flag = flag && Objects.equals(p.getSingleOrder(), 1);
            }
            shoppingCartGoodsResponseVo.setNonSingleOrder(flag);
        }
    }

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

        GetMemberInfoResponseVo responseData = new GetMemberInfoResponseVo();

        String partnerId = request.getPartnerId();
        String memberId = request.getUserId();
        List<Integer> statusFlagList = request.getStatusFlagList();
        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(this::convert2MemberCoupon).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(this::convert2ShopCartGoods).collect(toList());

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

            // 积分
            GetUserScoreUseDetailRequest scoreRequest = new GetUserScoreUseDetailRequest();
            scoreRequest.setMemberId(memberId);
            scoreRequest.setPaidAmount(request.getActualPayAmount());
            scoreRequest.setPartnerId(partnerId);
            GetUserScoreUserDetailResponse userScoreUseDetail = customerApplicationClient.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);
        getMemberCardRequest.setStatusFlagList(statusFlagList);
        com.freemud.application.sdk.api.base.BaseResponse<List<GetSvcInfoByMemberIdResponse>> svcInfoByMemberId = customerPropertyClient.getMemberCards(getMemberCardRequest);
        if (svcInfoByMemberId != null && CollectionUtils.isNotEmpty(svcInfoByMemberId.getData())) {
            List<GetSvcInfoByMemberIdResponse> memberCardResponses = svcInfoByMemberId.getData();
            // 查询储值卡的余额
            List<String> cardCodes = memberCardResponses.stream().map(GetSvcInfoByMemberIdResponse::getCardCode).collect(Collectors.toList());
            if (statusFlagList!=null&&statusFlagList.size()>0&&statusFlagList.contains(0)){
                //从SVC查询出有效的储值卡,状态2
                SvcCardDetailRequest req=  new SvcCardDetailRequest(partnerId,cardCodes);
                BaseResponse<List<SvcCardDetailsResponse>> details = svcAppClient.details(req);
                cardCodes=details.getResult().stream().filter(item->item.getCardState().equals(2)).map(SvcCardDetailsResponse::getCardCode).collect(toList());
            }
            SVCCardAmountRequest svcCardAmountRequest = new SVCCardAmountRequest();
            svcCardAmountRequest.setCardCodes(cardCodes);
            svcCardAmountRequest.setPartnerId(partnerId);
            BaseResponse<SVCCardAmountResponse> svcCardAmountResponseBaseResponse = svcAppClient.batchQueryCardAmount(svcCardAmountRequest);
            List<CardSimpleInfo> cardSimpleInfos = svcCardAmountResponseBaseResponse.getResult().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_YYYY_MM_DD_HHMMSS);
        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());
        // 折扣券使用折扣字段
        if (Objects.equals(each.getCouponType(), CouponTypeEnum.TYPE_3.getCode())) {
            int discountAmount = Integer.parseInt(Optional.ofNullable(each.getDiscountAmount()).orElse("0"));
            BigDecimal discount = BigDecimal.ZERO;
            // 转换千分比为小数
            if (discountAmount != 0) {
                discount = new BigDecimal(discountAmount).divide(BigDecimal.valueOf(100), 1, BigDecimal.ROUND_DOWN);
            }
            coupon.setDiscount(discount);
            // 暂时先不上
            coupon.setDiscountAmount(0);
        } else {
            coupon.setDiscount(BigDecimal.ZERO);
            coupon.setDiscountAmount(Integer.valueOf(each.getDiscountAmount()));
        }
        coupon.setCouponLimit(null);
        coupon.setCouponCode(each.getCouponCode());
        return coupon;

    }

    private GetMemberInfoResponseVo.Card convert2MemberSvcCard(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 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,
            Integer bizType,
            Integer accountFlag,
            long nightDistributionFee
            ) {

        ActivityCalculationDiscountRequestDto activityCalculationDiscountRequestDto = getActivityCalculationDiscountRequestDto(partnerId, storeId, userId, appId, orderType);
        List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList = new ArrayList<>();
        // 校验后有效的商品券map
        Map<String, CheckSpqInfoResponseDto> validCouponMap = new HashMap<>(16);
        HashMap<String, List<String>> spqIdToCartUuid = new HashMap<>(16);
        for (int i = cartGoodsList.size() - 1; i >= 0; i--) {
            CartGoods cartGoods = cartGoodsList.get(i);
            //套餐商品的固定和可选商品必有一个
            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,bizType);
                    throw new ServiceException(ResponseResult.SHOPPING_CART_NO_MEAL);
                }
            }

            String cartGoodsUid = cartGoods.getCartGoodsUid();

            String couponCode = "";
            if (cartGoodsUid.startsWith(CommonsConstant.COUPON_PREFIX)) {
                couponCode = cartGoods.getCartGoodsUid().substring(CommonsConstant.COUPON_PREFIX.length());
            } else {
                couponCode = cartGoods.getCouponCode();
            }
            // 商品不是商品券
            if (StringUtils.isBlank(couponCode)) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, cartGoods);
            } else {
                CheckSpqInfoRequestDto checkSpqInfoRequestDto = new CheckSpqInfoRequestDto(partnerId, storeId, couponCode, menuType,cartGoods);
                CheckSpqInfoResponseDto checkSpqInfoResponseDto = null;
                // fisherman 删除商品券导致 购物车显示商品名称 为换购券 券名称
                boolean viewProductName = false;
                if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())
                        || GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType().equals(cartGoods.getGoodsType())) {
                    viewProductName = true;
                    checkSpqInfoResponseDto = couponService.checkSpqInfo(checkSpqInfoRequestDto, cartGoods.getSkuId());
                } else {
                    checkSpqInfoResponseDto = couponService.checkSpqInfo(checkSpqInfoRequestDto,cartGoods.getSkuId());
                }
                // 商品券不存在时，将商品券从购物车移除
                if (checkSpqInfoResponseDto == null) {
                    cartGoodsList.remove(i);
                    assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, null, null, this.shoppingCartBaseService,bizType);
                    continue;
                }
                if (cartGoodsUid.startsWith(CommonsConstant.COUPON_PREFIX)) {
                    validCouponMap.put(couponCode, checkSpqInfoResponseDto);
                }if (!GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType().equals(cartGoods.getGoodsType())) {
                    validCouponMap.put(couponCode + checkSpqInfoResponseDto.getSkuId(), checkSpqInfoResponseDto);
                    validCouponMap.put(couponCode, checkSpqInfoResponseDto);
                }
                if (spqIdToCartUuid.containsKey(couponCode)) {
                    List<String> uuidList = spqIdToCartUuid.get(couponCode);
                    uuidList.add(cartGoods.getCartGoodsUid());
                    spqIdToCartUuid.put(couponCode, uuidList);
                } else {
                    List<String> uuidList = new ArrayList<>();
                    uuidList.add(cartGoods.getCartGoodsUid());
                    spqIdToCartUuid.put(couponCode, uuidList);
                }
                if (viewProductName) {
                    cartGoods.setName(checkSpqInfoResponseDto.getSkuName());
                    cartGoods.setSpuName(checkSpqInfoResponseDto.getSkuName());
                    cartGoods.setSkuName(checkSpqInfoResponseDto.getSkuName());
                }else {
                    cartGoods.setName(checkSpqInfoResponseDto.getCouponName());
                    cartGoods.setSpuName(checkSpqInfoResponseDto.getCouponName());
                }
                cartGoods.setStockLimit(checkSpqInfoResponseDto.isStockLimit());
                //逻辑同 viewProductName
//                if (GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType().equals(cartGoods.getGoodsType())) {
//                    cartGoods.setName(checkSpqInfoResponseDto.getSkuName());
//                    cartGoods.setSpuName(checkSpqInfoResponseDto.getSpuName());
//                }
                //添加请求的优惠券信息 买M赠N券，不重复加促销券集合字段
                String finalCouponCode = couponCode;
                List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> collect = coupons.stream().filter(calculationDiscountCoupon -> Objects.equals(calculationDiscountCoupon.getCode(), finalCouponCode)).collect(toList());
                // canUseCoupon 0 表示可用
                accountFlag = accountFlag == null ? 0 : accountFlag;
                if (CollectionUtils.isEmpty(collect)) {
                    if (GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType().equals(cartGoods.getGoodsType()) && accountFlag == 1 )
                    {
                        if (cartGoods.getCanUseCoupon() == 0) {
                            ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                            coupon.setCode(checkSpqInfoResponseDto.getCouponCode());
                            coupon.setActivityCode(checkSpqInfoResponseDto.getActiveCode());
                            coupons.add(coupon);
                        }
                    } else {
                        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();
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, goodsId, cartGoods.getQty(), checkSpqInfoResponseDto.getPrice(), 100, cartGoodsUid, couponCode);
            }

        }
        // 当加价购商品不为空时
        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, sendGoods.getGoodsId(), sendGoods.getQty(), sendGoods.getOriginalPrice(), 100, "",null);
            }
        }
        calculationDiscountGoodsList.removeIf(calculationDiscountGoods -> (calculationDiscountGoods.getGoodsQuantity().equals(0)));

        if (CollectionUtils.isEmpty(calculationDiscountGoodsList)) {
            return null;
        }
        activityCalculationDiscountRequestDto.setGoods(calculationDiscountGoodsList);
        activityCalculationDiscountRequestDto.setCoupons(coupons);
        activityCalculationDiscountRequestDto.setOrgIds(commonService.getOrgIdsForCoupon(partnerId, storeId));
        activityCalculationDiscountRequestDto.setDistributionFee(distributionFee);
        activityCalculationDiscountRequestDto.setNightDistributionFee(nightDistributionFee);
        activityCalculationDiscountRequestDto.setIsMember(isMember);
        //todo   def是什么？
        activityCalculationDiscountRequestDto.setProductChannel("def");
        if (Objects.equals(orderType, CreateOrderType.COLLECT_GOODS.getCode())) {
            activityCalculationDiscountRequestDto.setProductChannel(BusinessTypeEnum.SAAS_PICKUP.getCode());
        } else if (Objects.equals(orderType, CreateOrderType.TAKE_OUT.getCode())) {
            activityCalculationDiscountRequestDto.setProductChannel(BusinessTypeEnum.SAAS_DELIVERY.getCode());
        }
        ActivityCalculationDiscountResponseDto activityCalculationDiscountResponseDto = activityClient.calculationDiscount(activityCalculationDiscountRequestDto);
        // 返回成功
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), ResponseCodeConstant.RESPONSE_SUCCESS_STR)) {
            CalculationDiscountResult result = activityCalculationDiscountResponseDto.getResult();
            List<Integer> activityTypes = result.getDiscounts().stream().map(Discount::getType).collect(Collectors.toList());
            if (activityTypes.contains(ActivityTypeEnum.TYPE_221.getCode())) {
                Discount discountDTO = result.getDiscounts().stream().filter(d -> ActivityTypeEnum.TYPE_221.getCode().equals(d.getType())).findFirst().get();
                convert2SendPoint(result, discountDTO);
            }

            result.setValidCouponMap(validCouponMap);
            result.setSpqIdToCartUuid(spqIdToCartUuid);
            // fisherman 配送费原价 + 夜间配送费逻辑  为了划线价展示
            result.setDeliveryAmount((Objects.isNull(distributionFee) ? 0L : distributionFee) + nightDistributionFee);
            // fisherman 优惠后配送费,需要加上促销反馈夜间配送费的优惠价格
            Long calculationNightDistributionFee = Objects.isNull(result.getNightDistributionFee()) ? 0L : result.getNightDistributionFee();
            // 老算价 可能会返回 null  牛皮
            Long calculationDistributionFee = Objects.isNull(result.getDistributionFee()) ? 0L : result.getDistributionFee();
            result.setDistributionFee(calculationDistributionFee + calculationNightDistributionFee);
            return result;
        }
        // 支付宝华莱士紧急修改代码，当促销返回103错误码时，需要报券不适用于该门店，且清空购物车
        ShoppingCartClearRequestVo shoppingCartClearRequestVo = new ShoppingCartClearRequestVo();
        shoppingCartClearRequestVo.setAppId(appId);
        shoppingCartClearRequestVo.setPartnerId(partnerId);
        shoppingCartClearRequestVo.setUserId(userId);
        shoppingCartClearRequestVo.setShopId(storeId);
        shoppingCartClearRequestVo.setOperationType(OperationTypeEnum.PAY_SUCCESS.getOperationType());
        // 因为数量限制的问题,不清空购物车缓存
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), "80000")) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_LIMIT_ADD);
        }
        clear(shoppingCartClearRequestVo);
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), "103")) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_COUPON_CAN_NOT_USE_THIS_SHOP);
        }
        // 新增算价失败提示
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), "104")) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_COUPON_CAN_NOT_USE_THIS_SHOP, activityCalculationDiscountResponseDto.getMsg());
        }
        throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
    }

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

        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());
            sendPointNew.setIsContinueExchange(sendPointVo.getIsContinueExchange());
            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.setAddCartTime(cartGoods.getAddCartTime() == null ? 0 : cartGoods.getAddCartTime());
        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(materialGoods.getQty());
                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, CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, UserLoginInfoDto userLoginInfoDto, String menuType, Long deliveryAmount, long nightDistributionFee) {
        //默认计算优惠
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        // 优惠券 这里设置了优惠券的优惠金额  setCouponDiscount(couponDiscount);
        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);
            }
        }

        // 满M件N折活动
        IPromotionService fullMCountNFoldService = PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.FULL_M_COUNT_N_FOLD);
        fullMCountNFoldService.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);

        //促销会员价
        MemberDiscountServiceImpl memberDiscountServiceNew = (MemberDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.MEMBER_DISCOUNT_NEw);
        memberDiscountServiceNew.updateShoppingCartGoodsDiscountNew(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        BuyMSendNCouponDiscountServiceImpl buyMSendNCouponDiscountService = (BuyMSendNCouponDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_M_SEND_N_COUPON);
        buyMSendNCouponDiscountService.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);
            }

            Discount discount = null;
            if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
                Optional<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)));
                }
                boolean isType34 = verifyActivity(calculationDiscountResult);
                if (isType34) {
                    String desc = shoppingCartGoodsResponseVo.getDeliveryDiscountDesc();
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(desc + "," + DELIVERY_DISCOUNT_DESC4);
                }
                shoppingCartGoodsResponseVo.setDeliveryAmount(calculationDiscountResult.getDeliveryAmount());
                shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(calculationDiscountResult.getDistributionFee());
                shoppingCartGoodsResponseVo.setThresholdAmount(discount.getThresholdAmount());
                shoppingCartGoodsResponseVo.setIsDiscountDelivery(true);

                // fisherman 促销优惠先 剩余的 配送费 怎么处理的? 需要沟通问一下
            } else {
                // fisherman 老算价, deliverAmount 不包含 nightDistributionFee 但是页面需要展示总价 所以 这里相加一下 做处理
                Long deliverAmountNew = deliveryAmount + nightDistributionFee;
                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(deliverAmountNew);
                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliverAmountNew);
                    shoppingCartGoodsResponseVo.setIsDiscountDelivery(false);
                    // fisherman 有活动 并且使用了优惠券
                    boolean isType34 = verifyActivity(calculationDiscountResult);
                    if (isType34) {
                        // 使用了优惠券
                        shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(calculationDiscountResult.getDistributionFee());
                        String deliveryDiscountDesc = shoppingCartGoodsResponseVo.getDeliveryDiscountDesc();
                        shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(deliveryDiscountDesc + "," + DELIVERY_DISCOUNT_DESC4);
                    }

                } else {
                    // 这里需要看看  选择了 配送券 calculationDiscountResult.getDistributionFee() 这个值是多少
                    String desc = DELIVERY_DISCOUNT_DESC3;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(deliverAmountNew.doubleValue() / 100)));
                    shoppingCartGoodsResponseVo.setDeliveryAmount(deliverAmountNew);
                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliverAmountNew);
                    // 增加配送券之后的逻辑
//                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(calculationDiscountResult==null?deliverAmountNew:calculationDiscountResult.getDistributionFee());
                    shoppingCartGoodsResponseVo.setIsDiscountDelivery(false);
                    // fisherman 确认是否 使用了优惠券
                    boolean isType34 = verifyActivity(calculationDiscountResult);
                    if (isType34) {
                        // 使用了优惠券
                        shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(calculationDiscountResult.getDistributionFee());
                        String deliveryDiscountDesc = shoppingCartGoodsResponseVo.getDeliveryDiscountDesc();
                        shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(deliveryDiscountDesc + "," + DELIVERY_DISCOUNT_DESC4);
                    }
                }
            }
        }

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

    }

    /**
     * 检验是否使用的 配送券
     *
     * @param calculationDiscountResult
     * @return
     */
    private boolean verifyActivity(CalculationDiscountResult calculationDiscountResult) {
        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getCouponDiscounts())) {
            CouponResults type34 = calculationDiscountResult.getCouponDiscounts().stream().filter(couponResults -> couponResults.getActivityType() != null &&
                    couponResults.getActivityType().compareTo(ActivityTypeEnum.TYPE_34.getCode()) == 0).findFirst().orElse(null);
            return type34 != null;
        }
        return false;
    }

    /**
     * 促销均摊计算
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param shoppingCartGoodsDto
     * @param premiumExchangeActivity
     * @param shoppingCartInfoRequestVo
     */
    private void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, 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);

        //满赠
        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);

        // 满M件N折活动
        IPromotionService fullMCountNFoldService = PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.FULL_M_COUNT_N_FOLD);
        fullMCountNFoldService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 美团Pos需求，针对优惠信息进行排序
        List<ActivityDiscountsDto> discounts = shoppingCartGoodsDto.getActivityDiscountsDtos();
        discounts.forEach(discount -> {
            for (Discount rd : calculationDiscountResult.getDiscounts()) {
                // 一定要先判断套餐，不清楚为什么套餐设置的活动是221-集点活动，不先判断的话，可能会匹配成集点的优先级了
                if (discount.getActivityCode().equals("setMeal")) {
                    // 套餐优惠不是促销返回的，这里和促销新算价保持一直，优先级设置为0
                    discount.setPriority(0);
                    break;
                }
                if (discount.getActivityType().equals(rd.getType())) {
                    discount.setPriority(rd.getPriority());
                    break;
                }
            }
            // 未匹配上的优惠，设置默认值0
            if (null == discount.getPriority()) discount.setPriority(0);
        });
        discounts.sort((a1, a2) -> a2.getPriority() - a1.getPriority());
        shoppingCartGoodsDto.setActivityDiscountsDtos(discounts);
    }


    /**
     * 获取购物车商品,添加商品,校验商品合法性,合并商品行,重新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 =checkCartRequest.getCartGoodsList();

        //判断当前商品在购物车是否已存在,存在则数量＋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,addShoppingCartGoodsRequestVo.getBizType());
        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<ProductBean> productBeanListSpuClass, CouponProductDto couponProductDto, String couponCode, Integer todayAvailableTimes) {
        ProductBean productBean = productBeanListSpuClass.get(0);
        cartGoods.setSkuId(spuId2);
        cartGoods.setOriginalPrice(0L);
        cartGoods.setOriginalAmount(0L);
        cartGoods.setAmount(0L);
        cartGoods.setPackPrice(productBean.getPackPrice());
        cartGoods.setPic(productBean.getPicture());
        cartGoods.setWeight(productBean.getWeight());
        cartGoods.setUnit(productBean.getUnit());
        // 券商品 设置商品原始类型
        cartGoods.setOriginalProductType(productBean.getType());
        cartGoods.setLinkedId(productBean.getLinkedId());

        // 设置商品类型为商品券
        if (CouponTypeEnum.TYPE_4.getCode().equals(couponProductDto.getType())) {
            cartGoods.setGoodsType(GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType());
        } else if (CouponTypeEnum.TYPE_7.getCode().equals(couponProductDto.getType())) {
            cartGoods.setGoodsType(GoodsTypeEnum.BUY_M_SEND_N_COUPON.getGoodsType());
            cartGoods.setOriginalPrice(productBean.getOriginalPrice());
            cartGoods.setAmount(productBean.getFinalPrice());
            cartGoods.setSkuName(productBean.getName());
        } else {
            cartGoods.setGoodsType(GoodsTypeEnum.COUPON_GOODS.getGoodsType());
        }
        //老商品券
        if (StringUtils.isBlank(addShoppingCartGoodsRequestVo.getCouponCode())) {
            cartGoods.setCartGoodsUid(spuId);
        }
        cartGoods.setCouponCode(couponCode);
        if (CollectionUtils.isNotEmpty(allCartGoodsList)) {
            if (Objects.equals(CouponTypeEnum.TYPE_0.getCode(), couponProductDto.getType())
                    || Objects.equals(CouponTypeEnum.TYPE_4.getCode(), couponProductDto.getType())) {
                int sum = allCartGoodsList.stream().filter(p -> Objects.equals(p.getCouponCode(),couponCode)).mapToInt(CartGoods::getQty).sum();
                //今日可用次数判断
                if (sum + cartGoods.getQty() > todayAvailableTimes) {
                    throw new ServiceException(ResponseResult.SHOPPING_CART_GOODS_COUPON_CAN_NOT_USE);
                }
            }
        }

        boolean stockLimit = false;
        if (productBean.getType() == ProductType.NOSPEC.getCode()
                && productBean.getStockLimit() == 1) {
            stockLimit = true;
        } else {
            for (SkuProductBean skuProductBean : productBean.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);
        }
        //校验合法性,更新缓存中购物车信息
        updateCartGoodsLegal(cartGoods, userId, shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo, allCartGoodsList);

    }

    /**
     * 查询多个商品库存信息
     *
     * @param addShoppingCartGoodsRequestVo
     * @param productIds
     * @param productBeanListSpuClass
     * @param skuId
     */
    private void queryManyGoodsStocks(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<Long> productIds
            , List<ProductBean> productBeanListSpuClass, String skuId, Integer qty) {
        boolean isLimit = false;
        if (productBeanListSpuClass.get(0).getType() == ProductType.NOSPEC.getCode()
                && productBeanListSpuClass.get(0).getStockLimit() == 1) {
            isLimit = true;
        } else {
            for (SkuProductBean skuProductBean : productBeanListSpuClass.get(0).getSkuList()) {
                if (skuId.equals(skuProductBean.getSkuId()) && skuProductBean.getStockLimit() == 1) {
                    isLimit = true;
                    break;
                }
            }
        }
        // 不限制库存
        if (!isLimit) {
            return;
        }
        this.commonItemVerfity(BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode(),
                addShoppingCartGoodsRequestVo.getPartnerId(),
                addShoppingCartGoodsRequestVo.getShopId(),
                productIds,
                qty);

    }

    private void commonItemVerfity(String channel, String partnerId, String storeId, List<Long> productIds, Integer qty){
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(channel);
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        requestDto.setProductIds(productIds);
        GetProductStockResponseDto availableStocks = stockClient.getAvailableStocks(requestDto);

        this.finalVerfity(availableStocks, qty);
    }

    private void finalVerfity(GetProductStockResponseDto availableStocks, Integer qty) {
        // 商品服务  返回null 或者 qty=null 表示不限制库存
        if (Objects.isNull(availableStocks)) {
            return;
        }
        // 商品服务  返回null 或者 qty=null 表示不限制库存
        List<GetProductStockResponseDto.DataBean> result = availableStocks.getResult();
        if (CollectionUtils.isEmpty(result) || Objects.isNull(result.get(0).getQty())) {
            return;
        }
        if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
        int stock = availableStocks.getResult().get(0).getQty();
        if (stock <= 0) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        } else if (stock < qty) {
            throw new BizServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE, "仅剩" + stock + "件库存了");
        }
    }

    /**
     * 组装添加商品和更新商品和查询的响应信息
     * <p>
     * 查询购物车计算包装费
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param cartGoodsList
     * @param toastMsg
     * @param userId
     * @param opt
     * @param shoppingCartInfoRequestVo
     */
    private void setAddAndUpdateResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, 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(SubmitPageEnum.YES.getCode(), shoppingCartInfoRequestVo.getFlag()) ? SHOPPING_CART_EMPTY_GOODS_LIST : SHOPPING_CART_INVALIAD_GOODS;
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, toastMsg);
            //结算页，只有商品全部非法（即products为空）时，才提示changed为true toastMsg 不为空
            if (shoppingCartInfoRequestVo != null && ObjectUtils.equals(SubmitPageEnum.YES.getCode(), shoppingCartInfoRequestVo.getFlag())) {
                shoppingCartGoodsResponseVo.setChanged(CollectionUtils.isEmpty(cartGoodsList));
                shoppingCartGoodsResponseVo.setToastMsg(CollectionUtils.isEmpty(cartGoodsList) ? toastMsg : "");
            }

        }
        // 更新和添加商品时不需要包装费
        if (ShoppingCartConstant.ADD_AND_UPDATE.equals(opt)) {
            shoppingCartGoodsResponseVo.setNewPackAmount(null);
            return;
        }
        //==========================  购物车查询特有逻辑  =================================
        if (Objects.isNull(shoppingCartInfoRequestVo)) {
            return;
        }
        // 这两行为了 展示 商品的 原价以及现在的购买价格 不需要包装费, fisherman 目前需求: 是否满足配送 按照商品原价|现价匹配
        shoppingCartGoodsResponseVo.setShoppingCartGoodsAmount(shoppingCartGoodsResponseVo.getTotalAmount());
        shoppingCartGoodsResponseVo.setShoppingCartOriginalGoodsAmount(shoppingCartGoodsResponseVo.getOriginalTotalAmount());
        // 到店自取包装费设为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()))) {
            //fisherman 【ID1033456】自提根据模板配置计算餐具包装费
            PackAmountConfig packAmountByStoreConfig = commonFunctionHandle.getPackAmountByStoreConfig(shoppingCartInfoRequestVo, shoppingCartGoodsResponseVo.getNewPackAmount(),shoppingCartGoodsResponseVo.getTotalAmount());
            Long packAmount = packAmountByStoreConfig.getNewPackAmount();
            shoppingCartGoodsResponseVo.setNewPackAmount(packAmount);
            shoppingCartGoodsResponseVo.setPackageAmountCollectType(CollectionUtils.isEmpty(packAmountByStoreConfig.getCollectType()) ? 1 : 2);
            if (Objects.equals(shoppingCartInfoRequestVo.getFlag(), SubmitPageEnum.YES.getCode())) {
                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,
                            BaseListCartGoodsVO 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卡金额
        BaseResponse<SVCCardAmountResponse> response = svcAppClient.batchQueryCardAmount(request);
        if (response == null) {
            throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }
        if (response.getResult() == null || CollectionUtils.isEmpty(response.getResult().getCardSimpleInfos())) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        boolean check = this.checkSvcComPay(partnerId, storeId);
        Integer applyType = response.getResult().getCardSimpleInfos().get(0).getApplyType();
        applyType = applyType == null ? 3 : applyType;
        String svcDesc = applyType == 3 ? "储值卡支付￥" : "礼品卡支付￥";
        if (check) {
            //混合支付无需校验svc卡余额,但是配送和包装费不计算在svc卡支付
            Integer amount1 = response.getResult().getCardSimpleInfos().get(0).getAmount();
            Integer vamount = response.getResult().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(svcDesc + amountStr);
        } else {
            //获取实际配送费
            if (StringUtils.isNotBlank(receiveId) && shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() != null) {
                Integer deliveryAmount = shoppingCartGoodsResponseVo.getDiscountDeliveryAmount().intValue();
                orderAmount += deliveryAmount;
            }
            Integer amount1 = response.getResult().getCardSimpleInfos().get(0).getAmount();
            Integer vamount = response.getResult().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(svcDesc + amountStr);
        }
    }


    /**
     * 储值卡支付余额校验
     * 校验订单商品金额与外卖配送费
     */
    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卡金额
        BaseResponse<SVCCardAmountResponse> response = svcAppClient.batchQueryCardAmount(request);
        if (response == null) {
            throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }
        if (response.getResult() == null || CollectionUtils.isEmpty(response.getResult().getCardSimpleInfos())) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        boolean check = this.checkSvcComPay(partnerId, storeId);
        Integer applyType = response.getResult().getCardSimpleInfos().get(0).getApplyType();
        applyType = applyType == null ? 3 : applyType;
        String svcDesc = applyType == 3 ? "储值卡支付￥" : "礼品卡支付￥";
        if (check) {
            //混合支付无需校验svc卡余额,但是配送和包装费不计算在svc卡支付
            Integer amount1 = response.getResult().getCardSimpleInfos().get(0).getAmount();
            Integer vamount = response.getResult().getCardSimpleInfos().get(0).getVamount();
            Integer svcTotalAmount = amount1 + vamount;
            //获取实际配送费
            Integer deliveryAmount = 0;
            Integer svcPayAmount = 0;
            if (StringUtils.isNotBlank(receiveId) && shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() != null) {
                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(svcDesc + amountStr);
        } else {
            //获取实际配送费
            if (StringUtils.isNotBlank(receiveId) && shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() != null) {
                Integer deliveryAmount = shoppingCartGoodsResponseVo.getDiscountDeliveryAmount().intValue();
                orderAmount += deliveryAmount;
            }
            Integer amount1 = response.getResult().getCardSimpleInfos().get(0).getAmount();
            Integer vamount = response.getResult().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(svcDesc + 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 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,Integer bizType, Integer accountFlag, long nightDistributionFee) {
        // 获取优惠信息
        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,bizType, accountFlag, nightDistributionFee);
        } else {
            calculationDiscountResult = this.getActivityCalculationDiscountResponse(partnerId, storeId, userId, appId, orderType, isMember, cartGoodsList, coupons, sendGoodsList, BusinessTypeEnum.getByType(menuType).getCode(), null,bizType, accountFlag, 0L);
        }

        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;
        }
        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) {
        AssortmentCustomerInfoVo customerInfoVo = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (customerInfoVo == null) throw new ServiceException(ResponseResult.NOT_LOGIN);
        String jsonObject = JSON.toJSONString(customerInfoVo);
        CustomerInfoVo customerInfoVo1 = JSON.parseObject(jsonObject, CustomerInfoVo.class);
        return customerInfoVo1;
    }

    /**
     * 检查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) {
                //todo 商品券校验数量，在此处无效  暂时不动...
                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(newSharing)) return true;
        CalculateCenter center = JSON.parseObject(newSharing, CalculateCenter.class);
        Boolean enable = true;
//        if (!center.getEnable()) return false;
        switch (center.getType()) {
            case 2:
                enable = true;
                break;
            case 1: {
                //商户+门店级别(新算价)
                String partnerId_storeId= partnerId.concat(storeId);
                if (Arrays.asList(center.getGrayList().split(",")).contains(partnerId_storeId)) {
                    enable = true;
                }
                //商户级别(老算价)
                else if (Arrays.asList(center.getGrayList().split(",")).contains(partnerId)) {
                    enable = false;
                }
            }
        }
//        if (center.getEnable() && enable) {
//            enable = true;
//        }
        return enable;
    }

    /**
     * 购物车重构开关
     *
     * @param partnerId
     * @param storeId
     * @return
     */
    public boolean newShoppingCartGray(String partnerId, String storeId) {

        if (StringUtils.isBlank(newShoppingCart) || StringUtils.isBlank(storeId)) return false;
        CalculateCenter center = JSON.parseObject(newShoppingCart, 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, String partnerId) {
        Integer qty = 0;
        if (CollectionUtils.isNotEmpty(oldCartGoodsList)) {
            for (CartGoods goods : oldCartGoodsList) {
                qty += goods.getQty();
            }
        }
        if (Objects.nonNull(cartGoods)) {
            qty += cartGoods.getQty();
        }
        int limitCount = queryLimitCount(partnerId, appid);
        if (limitCount != 0 && qty > limitCount) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_LIMIT_ADD);
        }
        return qty;
    }

    /**
     * 查询购物车限购数量
     */
    public int queryLimitCount(String partnerId, String appid) {
        int limitCount = 0;
        String redisKey = RedisUtil.limitCart + partnerId + "_" + appid;
        //购物车内部缓存
        String value = redisCache.hashGet(redisKey, "cartLimitType");
        if (StringUtils.isNotBlank(value)) {
            return Integer.parseInt(value);
        }

//        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 (cartLimitFlag != 1) {
//                        return qty;
//                    }
//                }
//                if ("cartLimitCount".equals(hashMap.get("appKey"))) {
//                    if (StringUtils.isBlank((String) hashMap.get("appValue"))) {
//                        return qty;
//                    }
//                    cartLimitCount = Integer.parseInt((String) hashMap.get("appValue"));
//                    return cartLimitCount;
//                }
//            }
//        }
        return limitCount;
    }


    /**
     * 购物车添加完成后促销返回赠送商品总数量校验
     */
    public void sendGoodsQtyCheck(Integer checkQty, String appid, String partnerId, String userId, String storeId, String tableNumber, List<CartGoods> oldCartGoodsList, ShoppingCartBaseService shoppingCartService, List<SendActivity> sendActivitys,Integer bizType) {
        if (CollectionUtils.isEmpty(sendActivitys)) {
            return;
        }
        int sendQty = 0;
        for (SendActivity sendActivity : sendActivitys) {
            for (SendGoods sendGoods : sendActivity.getSendGoods()) {
                sendQty += sendGoods.getSendNumber();
            }
        }
        int cartLimitCount = queryLimitCount(partnerId, appid);
        if (cartLimitCount != 0 && checkQty + sendQty > cartLimitCount) {
            assortmentSdkService.setShoppingCart(partnerId, storeId, userId, oldCartGoodsList, null, tableNumber, shoppingCartService,bizType);
            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<SendActivity> sendActivitys,Integer bizType) {
        Integer updateQty = 0;
        if (CollectionUtils.isNotEmpty(cartGoodsList)) {
            for (CartGoods goods : cartGoodsList) {
                updateQty += goods.getQty();
            }
        }

        int cartLimitCount = queryLimitCount(partnerId, appid);
        int sendQty = 0;
        if (CollectionUtils.isNotEmpty(sendActivitys)) {
            for (SendActivity sendActivity : sendActivitys) {
                for (SendGoods sendGoods : sendActivity.getSendGoods()) {
                    sendQty += sendGoods.getSendNumber();
                }
            }
        }
        if (cartLimitCount != 0 && updateQty + sendQty > cartLimitCount) {
            assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoodsUid, goodsQty, "", shoppingCartBaseService,bizType);
            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,
                                                CalculationDiscountResult discountResult,
                                                Integer flag,
                                                String partnerId) {

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

    }

    private List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> buildCoupons(List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> oldCoupons,
                                                                                               List<ChooseCouponVo> coupons) {

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

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

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

        return oldCoupons;
    }

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

    /**
     * 校验小料的数量
     *
     * @param addShoppingCartGoodsRequestVo
     * @return
     */
    public Boolean checkMaterialQty(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<ProductBean> products) {
        Integer materialMaxQty = products.get(0).getMaxNum();
        Integer addProductqty = 0;
        if (addShoppingCartGoodsRequestVo.getProductMaterialList() != null && !addShoppingCartGoodsRequestVo.getProductMaterialList().isEmpty()) {
            for (MaterialRequestVo materialRequestVo : addShoppingCartGoodsRequestVo.getProductMaterialList()) {
                addProductqty = addProductqty + (materialRequestVo.getQty() == null ? 0 : materialRequestVo.getQty());
            }

        }
        if (materialMaxQty == null || ObjectUtils.equals(materialMaxQty, 0) || addProductqty == null || ObjectUtils.equals(addProductqty, 0)) {
            return Boolean.FALSE;
        }

        if (materialMaxQty.intValue() < addProductqty.intValue()) {
            return Boolean.TRUE;
        }

        return Boolean.FALSE;
    }

    /**
     * 结算页获取加价购活动商品列表
     *
     * @param request
     * @return
     */
    public BaseResponse<PremiumExchangeResponseVo> premiumExchange(PremiumExchangeRequestVo request) {
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(request.getSessionId());
        String userId = assortmentCustomerInfoVo.getMemberId();
        String partnerId = request.getPartnerId();
        String storeId = request.getShopId();
        String couponCode = request.getCouponCode();
        String activityCode = request.getActivityCode();
        String appId = assortmentCustomerInfoVo.getAppId();
        String menuType = request.getMenuType();
        Integer orderType = request.getOrderType();
        Integer bizType = request.getBizType();
        Integer accountFlag = 0;//不关心是否为结算页 设置为非结算页

        // 返回构造对象
        PremiumExchangeResponseVo premiumExchangeResponseVo = new PremiumExchangeResponseVo();
        premiumExchangeResponseVo.setResultCode(ActivityResultCodeEnum.NON_PARTICIPATE.getCode());
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, request.getSessionId(), null, shoppingCartBaseService,bizType);
        if (grayPush(partnerId, storeId, "2")) {
            // 当couponCode不为空时，需参与价格计算
            ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
            if (StringUtils.isNotEmpty(couponCode)) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(couponCode);
                coupon.setActivityCode(activityCode);
                coupons.add(coupon);
            }
            if (!CollectionUtils.isEmpty(request.getCouponCodes())) {
                request.getCouponCodes().forEach(couponCode1 -> {
                    if (!couponCode1.getCouponCode().equals(couponCode)) {
                        ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                        coupon.setCode(couponCode1.getCouponCode());
                        coupon.setActivityCode(couponCode1.getActivityCode());
                        coupon.setCouponType(couponCode1.getCouponType());
                        coupons.add(coupon);
                    }
                });
            }

            CalculationDiscountResult discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , coupons //券
                    , null //加价购商品
                    , 0L
                    , null,bizType, accountFlag,new DiscountSharingDto(), 0L);

            premiumExchangeResponseVo = activityAdapter.convert2PremiumExchangeSharing(discountResult);
        } 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);
            }
            if (!CollectionUtils.isEmpty(request.getCouponCodes())) {
                request.getCouponCodes().forEach(couponCode1 -> {
                    if (!couponCode1.getCouponCode().equals(couponCode)) {
                        ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                        coupon.setCode(couponCode1.getCouponCode());
                        coupon.setActivityCode(couponCode1.getActivityCode());
                        coupon.setCouponType(couponCode1.getCouponType());
                        coupons.add(coupon);
                    }
                });
            }
            // 获取优惠信息
            CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId, assortmentCustomerInfoVo.getWxAppId(), orderType, assortmentCustomerInfoVo.isMemberPaid(), cartGoodsList, coupons, null, null, 0L,bizType
            , accountFlag, 0L);
            premiumExchangeResponseVo = activityAdapter.convert2PremiumExchange(calculationDiscountResult);

        }
        List<PremiumExchangeResponseVo.PremiumExchangeProduct> products = premiumExchangeResponseVo.getProducts();
        premiumExchangeResponseVo.setProducts(null);
        if (!Objects.equals(ActivityResultCodeEnum.PARTICIPATE.getCode(), premiumExchangeResponseVo.getResultCode())) {
            return ResponseUtil.success(premiumExchangeResponseVo);
        }

        // 获取所有spu商品Id  一个spu在菜单里面，他的sku肯定也在菜单里
        List<String> spuIds = products.stream().map(PremiumExchangeResponseVo.PremiumExchangeProduct::getSpuId).distinct().collect(toList());
        GetValidateProductInfoDto getProductInfoDto = new GetValidateProductInfoDto();
        getProductInfoDto.setPartnerId(partnerId);
        getProductInfoDto.setStoreId(storeId);
        getProductInfoDto.setChannel(menuType);
        getProductInfoDto.setProductIds(spuIds);
        getProductInfoDto.setBizType(bizType);
        ValidateProductInfosDto productInfosDto = storeItemClient.validateShopContainProduct(getProductInfoDto);
        if (!Objects.equals(productInfosDto.getErrcode(), Integer.valueOf(ResponseResult.SUCCESS.getCode()))
                || productInfosDto.getData() == null
                || CollectionUtils.isEmpty(productInfosDto.getData().getSuccessList())) {
            premiumExchangeResponseVo.setResultCode(ActivityResultCodeEnum.GOOD_NOT_AVAILABLE.getCode());
            premiumExchangeResponseVo.setResultMsg(ActivityResultCodeEnum.GOOD_NOT_AVAILABLE.getDesc());
            return ResponseUtil.success(premiumExchangeResponseVo);
        }

        //剔除products中库存不足的商品
        this.removeByProductStock(products, productInfosDto.getData().getSuccessList(), partnerId, storeId, menuType);
        if (CollectionUtils.isEmpty(products)) {
            premiumExchangeResponseVo.setResultCode(ActivityResultCodeEnum.STOCK_LIMIT.getCode());
            premiumExchangeResponseVo.setResultMsg(ActivityResultCodeEnum.STOCK_LIMIT.getDesc());
            return ResponseUtil.success(premiumExchangeResponseVo);
        }
        // 组装返回商品集合
        List<PremiumExchangeResponseVo.PremiumExchangeProduct> productResults = new ArrayList<>();
        Map<String, ValidateProductInfosDto.ProductBean> productBeanMap = productInfosDto.getData().getSuccessList().stream().map(ValidateProductInfosDto.ProductData::getProductType).collect(Collectors.toMap(ValidateProductInfosDto.ProductBean::getPid, a -> a, (k1, k2) -> k1));
        // 判断商品是否在菜单内
        for (PremiumExchangeResponseVo.PremiumExchangeProduct premiumExchangeProduct : products) {
            // 加价购的商品，现在的商品都为sku级别
            ValidateProductInfosDto.ProductBean productBean = productBeanMap.get(premiumExchangeProduct.getSpuId());
            if (productBean == null) {
                continue;
            }
            boolean onSale = false;//商品是否可售
            if (Objects.equals(productBean.getPid(), premiumExchangeProduct.getSkuId()) && Objects.equals(productBean.getStatus(), StoreItemStatus.PUT_ON_SALE.getCode())) {
                onSale = true;
            } else if (CollectionUtils.isNotEmpty(productBean.getSkuList())) {
                onSale = productBean.getSkuList().stream().anyMatch(sku -> Objects.equals(sku.getSkuId(), premiumExchangeProduct.getSkuId()) && Objects.equals(sku.getStatus(), StoreItemStatus.PUT_ON_SALE.getCode()));
            }
            if (onSale) {
                PremiumExchangeResponseVo.PremiumExchangeProduct result = storeItemAdapter.convert2SpuProductVo(productBean, premiumExchangeProduct.getSkuId());
                result.setSkuId(premiumExchangeProduct.getSkuId());
                result.setSkuName(premiumExchangeProduct.getSkuName());
                result.setNowPrice(premiumExchangeProduct.getNowPrice());
                result.setOriginalPrice(productBean.getFinalPrice());
                result.setNumber(premiumExchangeProduct.getNumber());
                result.setArtNo(premiumExchangeProduct.getArtNo());
                result.setProductType(premiumExchangeProduct.getProductType());
                // fisherman  处理虚拟商品的 券名称获取
                if (premiumExchangeProduct.getProductType().compareTo(ProductTypeEnum.VIRTUAL_PRODUCT.getCode()) == 0) {
                    result.setCouponData(getActivityMsgHandle.getCouponData(productBean.getProductBindingCouponTypes(), partnerId));
                }
                productResults.add(result);
            }
        }
        if (CollectionUtils.isEmpty(productResults)) {
            premiumExchangeResponseVo.setResultCode(ActivityResultCodeEnum.GOOD_NOT_AVAILABLE.getCode());
            premiumExchangeResponseVo.setResultMsg(ActivityResultCodeEnum.GOOD_NOT_AVAILABLE.getDesc());
            return ResponseUtil.success(premiumExchangeResponseVo);
        }
        premiumExchangeResponseVo.setProducts(productResults);
        return ResponseUtil.success(premiumExchangeResponseVo);
    }


    @Override
    public BaseResponse getV3Promotion(BaseRequestVo request) {
        boolean grayPush = grayPush(request.getPartnerId(), request.getShopId(), "2");
        PromotionResultVO vo = new PromotionResultVO();
        if (grayPush) {
            ActivityBaseResponseDto<PromotionResultVO> responseDto = activityClient.getV3Promotion(request);
            if (responseDto != null && StringUtils.equals(responseDto.getStatusCode(),ResponseCodeConstant.RESPONSE_SUCCESS_STR)) {
                vo.setV3Promotion(responseDto.getResult().isV3Promotion());
            }
        }
        return ResponseUtil.success(vo);
    }

    private void removeByProductStock(List<PremiumExchangeResponseVo.PremiumExchangeProduct> products, List<ValidateProductInfosDto.ProductData> productDataList, String partnerId, String storeId, String channel) {
        List<Long> limitSkuIds = new ArrayList<>();
        productDataList.stream().forEach(ProductData -> {
            ValidateProductInfosDto.ProductBean productType = ProductData.getProductType();
            if (productType != null) {
                if (CollectionUtils.isNotEmpty(productType.getSkuList())) {
                    limitSkuIds.addAll(productType.getSkuList().stream().filter(sku -> Objects.equals(sku.getStockLimit(), 1)).map(sku -> Long.valueOf(sku.getSkuId())).collect(Collectors.toList()));
                } else {
                    if (Objects.equals(productType.getStockLimit(), 1)) {
                        limitSkuIds.add(Long.valueOf(productType.getPid()));
                    }
                }
            }
        });
        // skuId有限制的
        if (CollectionUtils.isNotEmpty(limitSkuIds)) {
            GetProductStockRequestDto stockRequestDto = new GetProductStockRequestDto();
            stockRequestDto.setChannel(channel);
            stockRequestDto.setPartnerId(partnerId);
            stockRequestDto.setStoreId(storeId);
            stockRequestDto.setProductIds(limitSkuIds);
            GetProductStockResponseDto availableStockResponse = stockClient.getAvailableStocks(stockRequestDto);
            Map<Long, GetProductStockResponseDto.DataBean> dataBeanMap = availableStockResponse.getResult().stream().collect(Collectors.toMap(GetProductStockResponseDto.DataBean::getPid, (p) -> p));
            Iterator<PremiumExchangeResponseVo.PremiumExchangeProduct> it = products.iterator();
            while (it.hasNext()) {
                PremiumExchangeResponseVo.PremiumExchangeProduct pe = it.next();
                GetProductStockResponseDto.DataBean dataBean = dataBeanMap.get(Long.parseLong(pe.getSkuId()));
                if (dataBean != null && dataBean.getQty() <= 0) {
                    // 过滤下架的商品
                    it.remove();
                }
            }
        }
    }

    /**
     * 券码查询购物车商品信息(平台用)
     *
     * @param requestVo
     * @return
     */
    public BaseResponse<CouponAvailableCartInfo> getCartInfoByUser(CouponAvailableRequestVo requestVo) {
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(requestVo.getSessionId());

        String userId = assortmentCustomerInfoVo.getMemberId();
        String partnerId = assortmentCustomerInfoVo.getPartnerId();
        String appId = assortmentCustomerInfoVo.getAppId();
        String storeId = requestVo.getStoreId();
        String menuType = requestVo.getMenuType();
        Integer orderType = requestVo.getOrderType();
        Integer bizType = requestVo.getBizType();
        Integer accountFlag = 0; //非结算页

        CouponAvailableCartInfo couponAvailableCartInfo;
        List<String> orgCodes = commonService.getOrgIdsForCoupon(partnerId, storeId);
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        Long deliveryAmount = calculateDeliveryAmount(requestVo.getReceiveId(), partnerId, storeId, assortmentCustomerInfoVo.getWxAppId(), shoppingCartGoodsResponseVo, requestVo.getOrderType());
        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCartForCoupon(partnerId, requestVo.getStoreId(), userId, "", shoppingCartBaseService,bizType);
        if (grayPush(partnerId, storeId, "2")) {
            //此对象用于传递参数,省的一直增加方法参数个数
            DiscountSharingDto sharingDto = new DiscountSharingDto();
            sharingDto.setAutoCoupon(true);
            CalculationDiscountResult discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                    , partnerId
                    , storeId
                    , userId
                    , appId
                    , orderType
                    , assortmentCustomerInfoVo.isMemberPaid()
                    , cartGoodsList
                    , new ArrayList<>() //券
                    , null //加价购商品
                    , deliveryAmount
                    , null,bizType, accountFlag,sharingDto, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));

            if(discountResult!= null && Objects.equals(discountResult.getV3Promotion(),true)){//v3
                couponAvailableCartInfo = activityAdapter.convert2CouponAvailableCartInfoSharingV3(partnerId, storeId, discountResult, orgCodes);
            }else{//v2
                couponAvailableCartInfo = activityAdapter.convert2CouponAvailableCartInfoSharing(partnerId, storeId, discountResult, orgCodes);
            }
        } else {
            // 获取优惠信息
            CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType, partnerId, storeId, userId, appId, assortmentCustomerInfoVo.getWxAppId(), orderType, assortmentCustomerInfoVo.isMemberPaid(), cartGoodsList, new ArrayList<>(), null, null, deliveryAmount,bizType, accountFlag, this.getNightDistributionFee(shoppingCartGoodsResponseVo.getDeliveryAmountList()));
            couponAvailableCartInfo = activityAdapter.convert2CouponAvailableCartInfo(partnerId, storeId, calculationDiscountResult, orgCodes);
        }
        return ResponseUtil.success(couponAvailableCartInfo);
    }


    /**
     * 切换门店 替换原门店的购物车信息
     *
     * @param replaceGoodsRequestVo
     * @return
     */
    public BaseResponse replaceGoodsByShop(ShopGoodsReplaceVo replaceGoodsRequestVo) {
        if (StringUtils.isEmpty(replaceGoodsRequestVo.getShopId())
                || StringUtils.isEmpty(replaceGoodsRequestVo.getOldShopId())) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }
        if (replaceGoodsRequestVo.getShopId().equals(replaceGoodsRequestVo.getOldShopId())) {
            return ResponseUtil.success();
        }

        // 获取用户登录信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(replaceGoodsRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = replaceGoodsRequestVo.getPartnerId();
        // 查询原店铺购物车缓存
        List<CartGoods> allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId,
                replaceGoodsRequestVo.getOldShopId(),
                userId,
                replaceGoodsRequestVo.getSessionId(),
                null,
                shoppingCartBaseService,null);
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_REPLACE_GOODS);
        }
        // 删除购物车中的不匹配商品 加购信息不包含营销促销活动和优惠券，价格以切换后的当前门店为准
        List<Integer> excludeType = Arrays.asList(
                // 换购券
                GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType(),
                // 万能券商品
                GoodsTypeEnum.ALL_COUPON_GOODS.getGoodsType(),
                // 虚拟商品
                GoodsTypeEnum.VIRTUAL_GOODS.getGoodsType(),
                // 异常商品
                GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType());
        List<CartGoods> excludeGoods = allCartGoodsList.stream().filter(cartGoods -> !excludeType.contains(cartGoods.getGoodsType())).collect(toList());
        List<CartGoods> HGcouponGoods = allCartGoodsList.stream().filter(cartGoods -> cartGoods.getGoodsType().equals(GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType())).collect(toList());
        if (!CollectionUtils.isEmpty(HGcouponGoods)) {
            // 替换 换购券的商品 变成普通商品 --> 优惠券商品变成 普通商品带到其他门店去
            List<CartGoods> goodsList = new ArrayList<>(HGcouponGoods.size());
            HGcouponGoods.forEach(cartGoods -> {
                goodsList.add(replaceGoodsType(cartGoods));
            });
            excludeGoods.addAll(goodsList);
        }
        if (CollectionUtils.isEmpty(excludeGoods)) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_REPLACE_GOODS_AND_CLEAR);
        }

        boolean fullReplace = true;
        if (excludeGoods.size() != allCartGoodsList.size()) {
            fullReplace = false;
        }
        // 拿出 spu sku 校验 当前店铺是否有 商品
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        fullReplace = updateCartGoodsLegal(excludeGoods, userId, replaceGoodsRequestVo, shoppingCartGoodsResponseVo, fullReplace);
        if (!fullReplace) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_REPLACE_GOODS_AND_CLEAR);
        }
        return ResponseUtil.success();
    }

    /**
     * 替换 优惠券商品 变成普通商品
     *
     * @param excludeGood
     */
    private CartGoods replaceGoodsType(CartGoods excludeGood) {
        CartGoods ret = new CartGoods();
        String skuId = excludeGood.getSkuId();
        // 优惠券换购商品 spuid:88608274545893050894   "goodsId": "spq88608274545893050894"
        ret.setGoodsId(skuId);
        ret.setAddCartTime(System.currentTimeMillis());
        ret.setSpuId(skuId);
        ret.setSkuId(skuId);
        ret.setQty(excludeGood.getQty());
        ret.setCouponCode(null);
        ret.setGoodsType(GoodsTypeEnum.SPU_GOODS.getGoodsType());
        ret.setExtra(excludeGood.getExtra());
        ret.setNodeId(excludeGood.getNodeId());
        ret.setCategoryName(excludeGood.getCategoryName());
        ret.setProductComboList(excludeGood.getProductComboList());
        ret.setProductGroupList(excludeGood.getProductGroupList());
        ret.setProductMaterialList(excludeGood.getProductMaterialList());
        return ret;
    }

    private void queryManyGoodsStocks(String menuType, String partnerId, String shopId, List<Long> productIds, List<ProductBean> productBeanListSpuClass, String skuId, Integer qty) {
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.getByType(menuType).getCode());
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(shopId);
        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 (SkuProductBean skuProductBean : productBeanListSpuClass.get(0).getSkuList()) {
                if (skuId.equals(skuProductBean.getSkuId()) && skuProductBean.getStockLimit() == 1) {
                    availableStocks = stockClient.getAvailableStocks(requestDto);
                    break;
                }
            }
        }
        this.finalVerfity(availableStocks, qty);
    }


    private boolean updateCartGoodsLegal(List<CartGoods> excludeGoods, String userId, ShopGoodsReplaceVo replaceGoodsRequestVo, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, boolean fullReplace) {
        //存储新添加的购物车信息
        //当商品全部添加完毕,校验购物车商品(是否合法,上下架,点餐方式,是否在当前菜单中...),并移除非法商品
        // 删除商品价格 方便不校验商品价格
        excludeGoods.forEach(cartGoods -> cartGoods.setFinalPrice(null));
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(excludeGoods, replaceGoodsRequestVo.getPartnerId(),
                replaceGoodsRequestVo.getShopId(), shoppingCartGoodsResponseVo, replaceGoodsRequestVo.getOrderType(),
                "", replaceGoodsRequestVo.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);
        // 如果查询出来的数据 为null  表示没有该商品  需要处理 fisherman
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            fullReplace = false;
            return fullReplace;
        }
        if (allCartGoodsList.size() != excludeGoods.size()) {
            // 表示有数据被删除
            fullReplace = false;
        }
        //校验库存
        List<CartGoods> stockLimitGoods = allCartGoodsList.stream().filter(CartGoods::isStockLimit).collect(toList());
        List<CartGoods> notCheckStock = allCartGoodsList.stream().filter(cartGoods -> !cartGoods.isStockLimit()).collect(toList());
        if (!CollectionUtils.isEmpty(stockLimitGoods)) {
            List<Long> goodsId = stockLimitGoods.stream().map(v -> Long.parseLong(v.getGoodsId())).collect(toList());
            GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
            requestDto.setChannel(BusinessTypeEnum.getByType(replaceGoodsRequestVo.getMenuType()).getCode());
            requestDto.setPartnerId(replaceGoodsRequestVo.getPartnerId());
            requestDto.setStoreId(replaceGoodsRequestVo.getShopId());
            requestDto.setProductIds(goodsId);
            GetProductStockResponseDto availableStocks = stockClient.getAvailableStocks(requestDto);
            if (availableStocks != null) {
                if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode())) {
                    // 没有请求数据
                    fullReplace = false;
                }
                if (CollectionUtils.isEmpty(availableStocks.getResult())) {
                    fullReplace = false;
                }

                List<GetProductStockResponseDto.DataBean> availableStocksResult = availableStocks.getResult();
                stockLimitGoods.forEach(cartGoods -> {
                });
                availableStocksResult.forEach(dataBean -> {
                    for (CartGoods cartGoods : stockLimitGoods) {
                        if (cartGoods.getGoodsId().equals(dataBean.getPid() + "")) {
                            Integer qty = dataBean.getQty();
                            if (qty != null && qty.compareTo(cartGoods.getQty()) < 0) {
                                cartGoods.setQty(qty);
                            }
                        }
                    }
                });

                // 获取到最新的 库存 stockLimitGoods 数据 放入 nowCartGoodsList 中
                notCheckStock.addAll(stockLimitGoods);
            } else {
                fullReplace = false;
            }
        }
        allCartGoodsList = notCheckStock;

        shoppingCartNewBaseService.clear(replaceGoodsRequestVo.getPartnerId(), replaceGoodsRequestVo.getShopId(), userId,replaceGoodsRequestVo.getBizType());
        // 重新set购物车信息到缓存中
        assortmentSdkService.setShoppingCart(replaceGoodsRequestVo.getPartnerId(), replaceGoodsRequestVo.getShopId(),
                userId, allCartGoodsList, replaceGoodsRequestVo.getSessionId(), null, this.shoppingCartBaseService,replaceGoodsRequestVo.getBizType());
        excludeGoods.clear();
        excludeGoods.addAll(allCartGoodsList);
        return fullReplace;
    }

}
