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

import cn.freemud.adapter.OrderAdapter;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.StoreConstant;
import cn.freemud.entities.bo.CreateOrderBONew;
import cn.freemud.entities.dto.GetCouponDetailResponseDto;
import cn.freemud.entities.dto.StoreDeliveryInfoDto;
import cn.freemud.entities.dto.StoreResponseDto;
import cn.freemud.entities.dto.UserDeliveryInfoDto;
import cn.freemud.entities.dto.order.BusinessDate;
import cn.freemud.entities.dto.order.UnifiedPayResponseDto;
import cn.freemud.entities.dto.pay.PayOrderDto;
import cn.freemud.entities.dto.pay.PayProductDto;
import cn.freemud.entities.dto.pay.UnifiedOrderRequestDto;
import cn.freemud.entities.dto.pay.svc.BatchSvcInfoRequest;
import cn.freemud.entities.dto.pay.svc.CardApplyRes;
import cn.freemud.entities.dto.pay.svc.SVCQueryMultiInfo;
import cn.freemud.entities.dto.shoppingCart.GetShoppingCartGoodsApportionDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.dto.store.*;
import cn.freemud.entities.dto.user.CustomerPropertyBaseResponse;
import cn.freemud.entities.dto.user.GetSvcInfoByMemberIdResponseVo;
import cn.freemud.entities.dto.user.StatisticalScoreRequestVo;
import cn.freemud.entities.vo.*;
import cn.freemud.entities.vo.order.CreateOrderCouponCodeVo;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.CouponService;
import cn.freemud.service.adapter.OrderCheckAdapter;
import cn.freemud.service.thirdparty.CustomerPropertyClient;
import cn.freemud.service.thirdparty.ShoppingCartClient;
import cn.freemud.service.thirdparty.StoreBaseApiClient;
import cn.freemud.service.thirdparty.SvcAppClient;
import cn.freemud.utils.AppLogUtil;
import cn.freemud.utils.DateUtils;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformIappWxappConfig;
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.AssortmentOpenPlatformIappWxappConfigManager;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerStoreDeliveryConfigManager;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.base.BaseResponse;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.response.QueryReceiveAddressResponse;
import com.freemud.application.sdk.api.membercenter.service.MemberCenterService;
import com.freemud.application.sdk.api.ordercenter.enums.BizTypeEnum;
import com.freemud.application.sdk.api.ordercenter.enums.MarketTypeEnum;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderInfoReqs;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderItemResp;
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.order.enums.StoreDeliveryMethod;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
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.Component;

import java.awt.geom.Point2D;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class CheckOrder {


    @Autowired
    private AssortmentOpenPlatformIappWxappConfigManager openPlatformIappWxappConfigManager;
    @Autowired
    private AssortmentOpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    //门店SDK
    @Autowired
    private StoreCenterService storeCenterService;
    //会员SDK
    @Autowired
    private MemberCenterService memberCenterService;

    @Autowired
    private CustomerPropertyClient customerPropertyClient;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private StoreServiceImpl storeService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private OrderAdapter orderAdapter;

    @Autowired
    private StoreBaseApiClient storeBaseApiClient;

    @Autowired
    private SvcAppClient svcAppClient;

    // 【华莱士】【订单C端记录不分账的卡面编号】不让走分账，卡面编号--11840，11845，11846，11853，11854，11855，11857，11858，11859，11860，11861，11862，11863，11864，11865，11866，11906
    @Value("${card.pay.unDistribution.applyId:}")
    private List<Integer> unDistributions;


    /**
     * 创建订单前参数校验与数据获取
     */
    public cn.freemud.base.entity.BaseResponse checkCreateOrderInfo(CreateOrderBONew createOrderBO){
        CreateOrderVo createOrderVo = createOrderBO.getCreateOrderVo();
        //原标准点餐程序逻辑处理
        cn.freemud.base.entity.BaseResponse baseResponse = this.checkStandardParamInfo(createOrderVo);
        if (ObjectUtils.notEqual(baseResponse.getCode(), ResponseResult.SUCCESS.getCode())) {
            return baseResponse;
        }
        // 查询用户信息 校验svc卡,余额购物车校验
        AssortmentCustomerInfoVo userLoginInfoDto = this.checkOrderByMember(createOrderBO);
        createOrderBO.setUserLoginInfoDto(userLoginInfoDto);

        // 查询门店信息 营业时间 营业状态，服务器当前时间在营业时间内 点餐桌号
        StoreMixResponseDto storeMixResponseDto = this.checkOrderByStore(createOrderBO);
        StoreResponseDto storeInfo = storeMixResponseDto.getStoreInfo();

        // 查询购物车（内部校验券点餐方式，券是否可用） 校验当前订单类型的下单参数
        ShoppingCartGoodsDto shoppingCartGoodsDto = this.getShoppingCartGoodsDto(createOrderVo);
        createOrderBO.setShoppingCartGoodsDto(shoppingCartGoodsDto);

        // 查询小程序自提外卖配置信息 校验当前订单类型的下单参数 校验外卖是否满足起送条件
        this.checkOrderByOrderType(createOrderBO);

        //更新订单使用
        OrderExtInfoDto extInfo = orderAdapter.setOrderExtInfo(userLoginInfoDto, storeInfo, createOrderBO.getCreateOrderVo(), shoppingCartGoodsDto);
        createOrderBO.setExtInfo(extInfo);
        return ResponseUtil.success();
    }

    /**
     * 标准点餐参数校验
     *
     * @param createOrderVo
     * @return
     */
    private cn.freemud.base.entity.BaseResponse checkStandardParamInfo(CreateOrderVo createOrderVo) {

        if (StringUtils.isEmpty(createOrderVo.getShopId())) {
            return ResponseUtil.error(ResponseResult.CREATE_ORDER_CHECK_STORE_ERROR);
        }
        if (createOrderVo.getOrderType() == null) {
            return ResponseUtil.error(ResponseResult.CREATE_ORDER_CHECK_ORDERTYPE_ERROR);
        }
        return ResponseUtil.success();
    }



    /**
     * 下单会员相关校验
     */
    public AssortmentCustomerInfoVo checkOrderByMember(CreateOrderBONew createOrderBO) {
        CreateOrderVo createOrderVo = createOrderBO.getCreateOrderVo();
        // 通过sessionId查询缓存中会员id 外层已获取缓存用户信息
        AssortmentCustomerInfoVo userLoginInfoDto = createOrderBO.getUserLoginInfoDto();
        if (userLoginInfoDto == null || StringUtils.isEmpty(userLoginInfoDto.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        Set<String> cardCodes = new HashSet<>();
        if(StringUtils.isNotEmpty(createOrderVo.getCardCode())){
            cardCodes.add(createOrderVo.getCardCode());
        }
        if(CollectionUtils.isNotEmpty(createOrderVo.getCardCodes())){
            cardCodes.addAll(createOrderVo.getCardCodes());
        }
        //校验会员svc卡信息
        List<GetSvcInfoByMemberIdResponseVo> memberCardCode = checkCardCode(createOrderVo.getPartnerId(), userLoginInfoDto.getMemberId(), cardCodes);
//        if (CollectionUtils.isNotEmpty(memberCardCode)) {
//            // 【华莱士】【订单C端记录不分账的卡面编号】不让走分账，卡面编号--11840，11845，11846，11853，11854，11855，11857，11858，11859，11860，11861，11862，11863，11864，11865，11866，11906
//            long count = memberCardCode.stream().filter(card -> cardCodes.contains(card.getCardCode()) && unDistributions.contains(card.getApplyId())).count();
//            if (count > 0) {
//                createOrderVo.setUnDistribution(1);
//            }
//        }
        // 获取储值卡是否配置了优惠同享等
        createOrderVo.setEnableSharing(this.commonCheckSVCEnableSharing(memberCardCode,cardCodes,createOrderVo.getPartnerId()));
        createOrderVo.setUserId(userLoginInfoDto.getMemberId());
        return userLoginInfoDto;
    }

    /**
     *
     * @param memberCardCode
     * @param cardCodes
     * @param partnerId
     * @return 是否与营销活动共享 1-是 0-否
     */
    public Integer commonCheckSVCEnableSharing(List<GetSvcInfoByMemberIdResponseVo> memberCardCode, Set<String> cardCodes, String partnerId){
        Integer enableSharing = 1;
        if (CollectionUtils.isNotEmpty(memberCardCode) && CollectionUtils.isNotEmpty(cardCodes)) {
            List<BatchSvcInfoRequest> requestList = new ArrayList<>();
            memberCardCode.stream().filter(c -> cardCodes.contains(c.getCardCode())).forEach(cardInfo -> {
                BatchSvcInfoRequest request = new BatchSvcInfoRequest();
                request.setApplyId(cardInfo.getApplyId());
                request.setPartnerId(partnerId);
                request.setVer("1");
                requestList.add(request);
            });
            SVCQueryMultiInfo req = new SVCQueryMultiInfo();
            req.setQueryList(requestList);
            cn.freemud.base.entity.BaseResponse<List<CardApplyRes>> response = svcAppClient.multiInfo(req);
            if (response != null && ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(response.getCode())) {
                if (CollectionUtils.isNotEmpty(response.getResult())) {
                    CardApplyRes cardApplyRes1 = response.getResult().stream().filter(cardApplyRes -> cardApplyRes.getEnableSharing().compareTo(0) == 0).findFirst().orElse(null);
                    if (Objects.nonNull(cardApplyRes1)) {
                        enableSharing = cardApplyRes1.getEnableSharing();
                    }
                }
            }
        }
        return enableSharing;
    }

    /**
     *
     * @param partnerId
     * @param memberId
     * @param requestVo
     * @return 是否与营销活动共享 1-是 0-否
     */
    public Integer checkMemberSvcCard(String partnerId, String memberId, SellCouponCreateOrderVo requestVo) {
        if (StringUtils.isNotBlank(requestVo.getCardCode())) {
            //校验会员svc卡信息
            List<GetSvcInfoByMemberIdResponseVo> memberCardCode = checkCardCode(partnerId, memberId, Sets.newHashSet(requestVo.getCardCode()));
//            if (CollectionUtils.isNotEmpty(memberCardCode)) {
//                // 【华莱士】【订单C端记录不分账的卡面编号】不让走分账，卡面编号--11840，11845，11846，11853，11854，11855，11857，11858，11859，11860，11861，11862，11863，11864，11865，11866，11906
//                long count = memberCardCode.stream().filter(card -> Sets.newHashSet(requestVo.getCardCode()).contains(card.getCardCode()) && unDistributions.contains(card.getApplyId())).count();
//                if (count > 0) {
//                    requestVo.setUnDistribution(1);
//                }
//            }
            return this.commonCheckSVCEnableSharing(memberCardCode, Collections.singleton(requestVo.getCardCode()), partnerId);
        }
        return 1;
    }



    public AssortmentCustomerInfoVo checkOrderByMemberNew(String sessionId) {
        // 通过sessionId查询缓存中会员id
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (userLoginInfoDto == null || StringUtils.isEmpty(userLoginInfoDto.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        return userLoginInfoDto;
    }

    public AssortmentCustomerInfoVo getMemberNew(String sessionId) {
        // 通过sessionId查询缓存中会员id
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (userLoginInfoDto == null || StringUtils.isEmpty(userLoginInfoDto.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        return userLoginInfoDto;
    }

    /**
     * 查询门店信息
     */
    public StoreResponse getStoreInfo(String partnerId, String shopId, String trackingNo) {
        // 获取门店信息
        StoreInfoRequest storeInfoRequest = new StoreInfoRequest(partnerId, shopId, null);
        return storeCenterService.getStoreInfo(storeInfoRequest, trackingNo);
    }

    /**
     * 查询门店信息新接口
     */
//    public StoreMixResponseDto getStoreInfoNew(String partnerId, String shopId, StoreInfoRequestDto.QueryInfo query) {
//        // 获取门店信息
//        StoreInfoRequestDto request = new StoreInfoRequestDto();
//        request.setPartnerId(partnerId);
//        request.setStoreCode(shopId);
//        request.setQuery(query);
//        StoreBaseResponseDto<StoreMixResponseDto> storeInfoNew = storeClient.getStoreInfoNew(request);
//        if (storeInfoNew == null || storeInfoNew.getBizVO() == null) {
//            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
//        }
//        return storeInfoNew.getBizVO();
//    }

    /**
     * 下单门店相关校验
     */
    public StoreMixResponseDto checkOrderByStore(CreateOrderBONew createOrderBO) {
        CreateOrderVo createOrderVo = createOrderBO.getCreateOrderVo();
        String partnerId = createOrderVo.getPartnerId();
        String shopId = createOrderVo.getShopId();
        Boolean queryDeliveryInfo = false;
        if (CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType())) {
            queryDeliveryInfo = true;
        }
        // 获取门店信息
        StoreMixResponseDto storeMixResponseDto = storeService.getStoreInfoNew(partnerId, shopId, true,queryDeliveryInfo);
        createOrderBO.setStoreMixResponseDto(storeMixResponseDto);

        StoreResponseDto storeResponseDto = storeMixResponseDto.getStoreInfo();
        //订单预约单检查&预定单检查
        OrderCheckAdapter.check(createOrderBO);
        // 校验门店是否停业 1 营业 2 停业 3 繁忙置休
        if (storeResponseDto.getActiveFlag() == null || storeResponseDto.getActiveFlag() != 1) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
        //特殊情况
        if ("".equals(storeResponseDto.getBusinessType())) {
            throw new ServiceException(ResponseResult.STORE_DATE_ERROR);
        }
        createOrderVo.setStoreName(storeResponseDto.getStoreName());
        createOrderVo.setStoreAddress(storeResponseDto.getAddress());
        createOrderVo.setThirdShopId(storeResponseDto.getThirdPartCode());
        createOrderVo.setStoreNameEn(storeResponseDto.getStoreNameEn());
        return storeMixResponseDto;
    }

    /**
     * queryBusinessInfoNew
     */
//    public BusinessInfoDto queryBusinessInfoNew(CreateOrderVo createOrderVo) {
//        String partnerId = createOrderVo.getPartnerId();
//        String shopId = createOrderVo.getShopId();
//
//        // 获取门店信息
//        StoreMixResponseDto storeInfoNew = storeService.getStoreInfoNew(partnerId, shopId, true);
//
//        BusinessInfoDto businessInfo = storeInfoNew.getBusinessInfo();
//        return businessInfo;
//    }

//    /**
//     *  调用该方法 需要自己判断 业务对象是否为null
//     * @param partnerId
//     * @param shopId
//     * @param query
//     * @return
//     */
//    public StoreMixResponseDto getStoremixDto(String partnerId, String shopId, StoreInfoRequestDto.QueryInfo query) {
//        // 获取门店信息
//        StoreMixResponseDto storeInfoNew = getStoreInfoNew(partnerId, shopId, query);
//        return storeInfoNew;
//    }

    /**
     * 下单订单类型校验
     */
    public Integer checkOrderByOrderType(CreateOrderBONew createOrderBO) {
        CreateOrderVo createOrderVo = createOrderBO.getCreateOrderVo();
        AssortmentCustomerInfoVo userLoginInfoDto = createOrderBO.getUserLoginInfoDto();
        StoreMixResponseDto storeMixResponseDto = createOrderBO.getStoreMixResponseDto();
        StoreResponseDto storeResponseDto = storeMixResponseDto.getStoreInfo();
        ShoppingCartGoodsDto shoppingCartGoodsDto = createOrderBO.getShoppingCartGoodsDto();

        Integer pushOrderTime = 0;
        //非到店或者外卖，类型错误
        if (!(CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType()) ||
                CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType()))) {
            throw new ServiceException(ResponseResult.PARAMETER_MISSING);
        }

        // 取餐标识 -> 0 我已到店  1预约单
        String takeMealFlag = createOrderVo.getTakeMealFlag();
        // 取餐时间
        String takeMealTimes = createOrderVo.getTakeMealTime();
        // fisherman-ka 预定单-> 预订时间 校验
        boolean isAdvanceOrder = this.getIsAdvanceOrder(createOrderVo.getBizType());
        if (isAdvanceOrder) {
            // 预定单 到店&外卖 必须有取餐时间
            if (StringUtils.isBlank(takeMealTimes)) {
                //todo 这里是重点: 门店如果营业结束,下明天的单子就会 传递 expectTime 时间
                if (StringUtils.isNotBlank(createOrderVo.getExpectTime())) {
                    // 预定单 当天营业结束 _> 不准下单
                    throw new ServiceException(ResponseResult.STORE_SELF_ERROR_10);
                }else {
                    throw new ServiceException(ResponseResult.PARAMETER_MISSING);
                }
            }
            // 必须要有 电话
            if (StringUtils.isBlank(createOrderVo.getUserPhone())) {
                throw new ServiceException(ResponseResult.PARAMETER_MISSING);
            }
        }
        //立即送达  预定单不会走立即送达
        if ("0".equals(takeMealFlag) || (StringUtils.isEmpty(createOrderVo.getExpectTime()) && StringUtils.isEmpty(takeMealTimes))) {
            //未营业无预约时间无法下单
            if (!StoreConstant.BUSINESS.equals(storeResponseDto.getState())) {
                throw new ServiceException(ResponseResult.STORE_ITEM_CHECK_CLOSE);
            }
            // 外卖单选择立即送达的话，下单时间必须在店铺外卖时间内
            if (createOrderVo.getOrderType().compareTo(CreateOrderType.TAKE_OUT.getCode()) == 0) {
                checkTakeOutTime(storeResponseDto, new Date(), new Date(), true);
            }
        }
        // 校验小程序是否支持到店或者外卖
        String appId = userLoginInfoDto.getWxAppId();
//        AssortmentOpenPlatformIappWxappConfig config = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(appId);
        // 自提校验
        BusinessInfoDto businessInfoDto = storeMixResponseDto.getBusinessInfo();
        if (CreateOrderType.COLLECT_GOODS.getCode().equals(createOrderVo.getOrderType())) {
//            if (config == null || config.getTakeInside() == null || config.getTakeInside() != 1) {
//                throw new ServiceException(ResponseResult.ORDER_WXAPP_NOT_ENABLE_COLLECT_GOODS);
//            }
            if (storeResponseDto.getIsSelfMention() == null || storeResponseDto.getIsSelfMention() != 1) {
                throw new ServiceException(ResponseResult.STORE_NOT_ENABLE_COLLECT_GOODS);
            }
            //扫桌码下单开关判断
//            businessInfoDto = storeMixResponseDto.getBusinessInfo();
            if (businessInfoDto != null && businessInfoDto.getExpandFields() != null
                    && ScanOrderSwitchEnum.TRUE.getCode().equals(businessInfoDto.getExpandFields().getScanOrderSwitch().toString())
                    && StringUtils.isBlank(createOrderVo.getTableNumber())) {
                throw new ServiceException(ResponseResult.ORDER_TABLE_BINDING_ERROR);
            }
            createOrderVo.setUserName(userLoginInfoDto.getNickName());
            createOrderVo.setMobile(userLoginInfoDto.getMobile());
        }
        //有预约时间
        if (StringUtils.isNotBlank(takeMealTimes) || StringUtils.isNotBlank(createOrderVo.getExpectTime())) {
            // 设置预约时间
            Date takeMealDateTime = getOrderExpectTime(takeMealFlag, takeMealTimes, createOrderVo.getExpectTime(),
                    CreateOrderType.getByCode(createOrderVo.getOrderType()), storeResponseDto.getServiceTime(), storeResponseDto);
            if (takeMealDateTime != null && !isAdvanceOrder) {
                //校验预约时间 -->
                checkOrderExpectTime(createOrderVo, storeResponseDto, takeMealDateTime);
                //重新赋值为yyyy-MM-dd HH:mm:ss格式字符串时间
                createOrderVo.setExpectTime(DateUtil.convert2String(takeMealDateTime, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
            } else {
                if (isAdvanceOrder) {
                    //fisherman-ka 预定单校验是否在预计开业时间范围内, 2. 校验 营业结束前十分钟,不允许下预约单(上面有代码,可以复用)
//                    if (Objects.isNull(businessInfoDto)) {
//                        businessInfoDto = this.queryBusinessInfoNew(createOrderVo);
//                    }
                    // 传递过来的时间格式为 :  2021-08-17 17:38
                    Date date = DateUtil.convert2Date(takeMealTimes, "yyyy-MM-dd HH:mm");
                    if (Objects.isNull(date)) {
                        throw new ServiceException(ResponseResult.ORDER_CREATE_TAKEMEALTIME_ERROR);
                    }
                    this.checkAdvanceOrderExpectTime(businessInfoDto, storeResponseDto, date);
                    createOrderVo.setExpectTime(DateUtil.convert2String(date, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
                }
            }
        }

        // 校验外卖信息
        if (CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType())) {
//            if (config == null || config.getTakeaway() == null || config.getTakeaway() == 0) {
//                throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
//            }
            if (storeResponseDto.getDelivery() == null || storeResponseDto.getDelivery() == 2) {
                throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
            }
            if (StringUtils.isBlank(storeResponseDto.getDeliveryHoursDay())) {
                throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
            }
            //获取门店配送信息
            DeliveryInfoDTO deliveryInfo = storeMixResponseDto.getDeliveryInfo();
            //coco自配送提前45分钟，禁止下单 代码已删除
            //外卖起送条件（1:杯数，2:金额）
            if (!Arrays.asList(1, 2).contains(deliveryInfo.getDeliveryType())) {
                throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_CONDITION);
            }
            if (1 == deliveryInfo.getDeliveryType()) {
                int sum = shoppingCartGoodsDto.getProducts().stream().mapToInt(ShoppingCartGoodsDto.CartGoodsDetailDto::getQty).sum();
                if (sum < deliveryInfo.getFreeDeliveryCup()) {
                    throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_CUP);
                }
            }
            //订单金额小于起送费提示
            else if (2 == deliveryInfo.getDeliveryType()) {
                // fisherman 【ID1037103】【野翠山】【B】外卖起送价规则取订单总金额  这特么用sdk就很吊, 得重新调用接口
                // 先暂时这么写, 到时候需要优化这一块 对于门店的请求操作
//                StoreInfoRequestDto.QueryInfo query = new StoreInfoRequestDto.QueryInfo();
//                query.setQueryDeliveryInfo(Boolean.TRUE);
//                StoreMixResponseDto storemixDto = storeService.getStoremixDto(createOrderVo.getPartnerId(), createOrderVo.getShopId(), query);
//                DeliveryInfoDTO deliveryInfo = storeMixResponseDto.getDeliveryInfo();
                Long deliveryLimitAmount = StringUtils.isBlank(deliveryInfo.getMinOrderPrice()) ? 0L : Long.parseLong(deliveryInfo.getMinOrderPrice());
                Long totalAmount = shoppingCartGoodsDto.getTotalAmount();
                if (Objects.nonNull(deliveryInfo) && Objects.nonNull(deliveryInfo.getExpandFields())) {
                    DeliveryInfoExpFields expandFields = deliveryInfo.getExpandFields();
                    if (Objects.equals(expandFields.getDeliveryAmountType(),"1")) {
                        //原价起送
                        totalAmount = shoppingCartGoodsDto.getOriginalTotalAmount();
                    }
                }
                if (deliveryLimitAmount.compareTo(totalAmount) > 0) {
                    throw new ServiceException(ResponseResult.STORE_DISCONTENT_DELIVERY_FEE);
                }
            }

//            storeDeliveryInfoDto.setEnableTakeaway(true);
            // 校验收货地址是否可配送 fisherman -> 获取门店预计送达时间
            builderUserDeliveryInfoDto(createOrderBO, deliveryInfo);
        }
        return pushOrderTime;
    }

    /**
     * 预定单的 额外校验:
     * 是否支持预定单         完成
     * 预定单校验是否在预计开业时间范围内,  ?
     * 营业结束前十分钟,不允许下预约单(上面有代码,可以复用)
     * 下面俩参数 在新的 /api/v2/organization/getStoreMix 可以一次性查出来 后续人员需要优化
     *
     * @param queryBusinessInfoNew
     * @param storeResponseDto
     */
    private void checkAdvanceOrderExpectTime(BusinessInfoDto queryBusinessInfoNew, StoreResponseDto storeResponseDto, Date takeMealDateTime) {
        if (Objects.isNull(queryBusinessInfoNew)) {
            return;
        }
        if (ObjectUtils.notEqual(queryBusinessInfoNew.getExpandFields().getPreOrderSwitch(), 1)) {
            // 没开启 抛出异常
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_ADVANCE);
        }

        // fisherman 预计 营业时间范围校验 begin
        this.getBusinessTimeByType(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHours(),takeMealDateTime);
        //预计 营业时间范围校验 end

        // 营业结束前校验  结束时间前十分钟可以下单 begin
        List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
        if (CollectionUtils.isEmpty(todayBusinessTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }

        Date createOrder = DateUtil.addMinutes(new Date(), 10);
        int diffDay = DateUtils.diffDay(new Date(), takeMealDateTime);
        for (String todayTime : todayBusinessTimes) {
            //每段营业时间校验
            BusinessDate businessDate2 = this.getStoreBusinessDate(todayTime, diffDay);
            if (createOrder.after(businessDate2.getEndDate())) {
                throw new ServiceException(ResponseResult.STORE_SELF_ERROR_10);
            }
        }
    }

    /**
     * 是否是 预定单
     *
     * @param bizType=7 就是预定单
     * @return true 预定单
     */
    private boolean getIsAdvanceOrder(Integer bizType) {
        return Objects.nonNull(bizType)
                && BizTypeEnum.ADVANCE_ORDER.getBizType().compareTo(bizType) == 0;
    }


    public void checkOrderExpectTime(CreateOrderVo createOrderVo, StoreResponseDto storeResponseDto, Date takeMealDateTime) {
        if (takeMealDateTime == null) {
            return;
        }
        //获取门店当天营业时间
        Date todayEndDate = null;
        List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
        if (CollectionUtils.isEmpty(todayBusinessTimes)) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        Date date = new Date();
        int diffDay = DateUtils.diffDay(date, takeMealDateTime);
        BusinessDate businessDate = getStoreBusinessDate(todayBusinessTimes.get(todayBusinessTimes.size() - 1), diffDay);
        todayEndDate = businessDate.getEndDate();
        //在当天营业时间内
        boolean expectTimeInTodayBusinessTime = true;
        Date newDate = DateUtil.convert2Date(date, DateUtil.FORMAT_yyyyMMdd_date);
        newDate = DateUtil.addDays(newDate, 1);
        //隔天预约(在明日凌晨之后且在门店营业结束之后)
        if (takeMealDateTime.before(todayEndDate) && takeMealDateTime.after(newDate)) {
            expectTimeInTodayBusinessTime = false;
        }
        if (expectTimeInTodayBusinessTime) {
            boolean inTodayBusinessTime = true;
            for (String todayTime : todayBusinessTimes) {
                //每段营业时间校验
                BusinessDate businessDate2 = getStoreBusinessDate(todayTime, diffDay);
                if (takeMealDateTime.getTime() >= businessDate2.getStartDate().getTime()
                        && takeMealDateTime.getTime() <= businessDate2.getEndDate().getTime()) {
                    inTodayBusinessTime = false;
                    break;
                }
            }
            if (inTodayBusinessTime) {
                throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVAILD);
            }
        }
        //隔天预约
        if (!expectTimeInTodayBusinessTime) {
            List<String> nextDayBusinessTimes = storeCenterService.getNextDayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
            boolean inNextDayBusinessTime = true;
            for (String nextDayTime : nextDayBusinessTimes) {
                BusinessDate storeNextBusinessDate = getStoreBusinessDate(nextDayTime, diffDay);
                if (takeMealDateTime.getTime() >= storeNextBusinessDate.getStartDate().getTime()
                        && takeMealDateTime.getTime() <= storeNextBusinessDate.getEndDate().getTime()) {
                    inNextDayBusinessTime = false;
                    break;
                }
            }
            if (inNextDayBusinessTime) {
                throw new ServiceException(ResponseResult.ORDER_TAKEMEALTIME_INVALID);
            }
        }

        if (CreateOrderType.TAKE_OUT.getCode().equals(createOrderVo.getOrderType())) {
            checkTakeOutTime(storeResponseDto, date, takeMealDateTime, expectTimeInTodayBusinessTime);
        }
    }

    /**
     * 检验订单是否在外卖时间内
     *
     * @param storeResponseDto              店铺信息
     * @param now                           当前时间
     * @param takeMealDateTime              预约单送达时间/即时单下单时间
     * @param expectTimeInTodayBusinessTime 是否在当日营业时间内
     */
    private void checkTakeOutTime(StoreResponseDto storeResponseDto, Date now, Date takeMealDateTime, boolean expectTimeInTodayBusinessTime) {
        String deliveryStr = storeResponseDto.getDeliveryHoursDay().replace("-", ",")
                .replace("_", ",");
        String[] deliverys = deliveryStr.split(",");
        Date deliveryStartDate = null;
        Date deliveryEndDate = null;
        if (deliverys.length == 2) {
            SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
            String startDateTimeStr = yyyyMMdd.format(now) + " " + deliverys[0] + ":00";
            String endDateTimeStr = yyyyMMdd.format(now) + " " + deliverys[1] + ":00";
            try {
                deliveryStartDate = hhmmss.parse(startDateTimeStr);
                deliveryEndDate = hhmmss.parse(endDateTimeStr);
            } catch (ParseException e) {
                AppLogUtil.errorLog("getStoreDeliveryInfo_error", endDateTimeStr, null,e);
            }
        }
        if (deliveryStartDate == null || deliveryEndDate == null) {
            throw new ServiceException(ResponseResult.ORDER_CREATE_TIME_NOT_DELIVERY);
        }
        // 校验预约配送时间
        if (expectTimeInTodayBusinessTime && (takeMealDateTime.before(deliveryStartDate) || takeMealDateTime.after(deliveryEndDate))) {
            throw new ServiceException(ResponseResult.ORDER_CREATE_TIME_NOT_DELIVERY);
        }
        Date nextDeliveryStartDate = DateUtil.addDays(deliveryStartDate, 1);
        Date nextDeliveryEndDate = DateUtil.addDays(deliveryEndDate, 1);
        // 隔日预约外卖校验预约配送时间
        if (!expectTimeInTodayBusinessTime && (takeMealDateTime.before(nextDeliveryStartDate) || takeMealDateTime.after(nextDeliveryEndDate))) {
            throw new ServiceException(ResponseResult.ORDER_CREATE_TIME_NOT_DELIVERY);
        }
    }

    public Date getOrderExpectTime(String takeMealFlag, String takeMealTimes, String expectTime,
                                   CreateOrderType createOrderType, Integer serviceTime, StoreResponseDto storeResponseDto) {
        Date takeMealDateTime = null;
        //0=到店单我已到店、外卖单尽快送出
        if (StringUtils.isNotBlank(takeMealFlag) && "0".equals(takeMealFlag)) {
            return takeMealDateTime;
        }
        if (StringUtils.isBlank(takeMealTimes) && StringUtils.isBlank(expectTime)) {
            return takeMealDateTime;
        }
        //兼容门店隔日预约单格式修改，HH:mm变yyyy-MM-dd HH:mm，前端未升级，未按要求传
        if (StringUtils.isNotBlank(takeMealTimes) && takeMealTimes.length() > 5) {
            expectTime = takeMealTimes + ":00";
        }

        Date date = new Date();
        //takeMealTimes格式必须为HH:mm
        if (StringUtils.isNotBlank(takeMealTimes) && takeMealTimes.length() <= 5) {
            StringBuffer takeMealTime = new StringBuffer("");
            takeMealTime = takeMealTime.append(DateUtil.convert2String(date, "yyyy-MM-dd"))
                    .append(" ").append(takeMealTimes).append(":00");
            takeMealDateTime = DateUtil.convert2Date(takeMealTime.toString(), "yyyy-MM-dd HH:mm:ss");
            Date newDate = DateUtil.convert2Date(date, DateUtil.FORMAT_yyyyMMdd_date);
            newDate = DateUtil.addDays(newDate, 1);

            //获取门店当天营业结束时间
            Date todayEndDate = null;
            List<String> todayBusinessTimes = storeCenterService.getTodayBusinessTime(Integer.parseInt(storeResponseDto.getBusinessType()), storeResponseDto.getBusinessHoursDay());
            if (CollectionUtils.isEmpty(todayBusinessTimes)) {
                throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
            }
            BusinessDate businessDate = getStoreBusinessDate(todayBusinessTimes.get(todayBusinessTimes.size() - 1), 0);
            todayEndDate = businessDate.getEndDate();

            //隔天营业的预约时间处理  计算出预约时间在当前时间之前，预约时间加1天 newDate.before(todayEndDate)=隔天营业
            if (takeMealDateTime != null && takeMealDateTime.before(date) && newDate.before(todayEndDate)) {
                takeMealDateTime = DateUtil.addDays(takeMealDateTime, 1);
            }
        }
        if (StringUtils.isNotBlank(expectTime)) {
            takeMealDateTime = DateUtil.convert2Date(expectTime, "yyyy-MM-dd HH:mm:ss");
        }
        //当顾客指定送达时间小于当前时间,订单记录类型为即时单
        if (takeMealDateTime != null && takeMealDateTime.before(date)) {
            takeMealDateTime = null;
        }
        //当顾客指定送达时间小于当前时间+提前预约时间时，订单记录类型为即时单
        if (CreateOrderType.TAKE_OUT.equals(createOrderType) && takeMealDateTime != null
                && serviceTime != null && takeMealDateTime.before(DateUtil.addMinutes(date, serviceTime))) {
            takeMealDateTime = null;
        }
        return takeMealDateTime;
    }


    public ShoppingCartGoodsDto getShoppingCartGoodsDto(CreateOrderVo createOrderVo) {
//        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = null;
//        if (createOrderVo.getBuyMemberCard() != null) {
//            buyMemberCard = new ShoppingCartInfoRequestVo.BuyMemberCard();
//            buyMemberCard.setPaidId(createOrderVo.getBuyMemberCard().getPaidId());
//            buyMemberCard.setRuleId(createOrderVo.getBuyMemberCard().getRuleId());
//        }
        String partnerId = createOrderVo.getPartnerId();
        ShoppingCartInfoRequestVo shoppingCartInfoRequestVo = ShoppingCartInfoRequestVo.builder()
                .partnerId(partnerId)
                .shopId(createOrderVo.getShopId())
                .version(createOrderVo.getVersion())
                .sessionId(createOrderVo.getSessionId())
                .orderType(createOrderVo.getOrderType())
                .reachStoreType(createOrderVo.getReachStoreType())
                .flag(CouponFlag.NO.getCode())
                .receiveId(createOrderVo.getReceiveId())
                .useCustomerScore(createOrderVo.getUseCustomerScore())
//                .buyMemberCard(null)
                .menuType(createOrderVo.getMenuType())
                .useCouponFlag(1)//结算页
                //.flag(1)
                // 预定单类型传递 购物车中进行查询
                .bizType(createOrderVo.getBizType())
                .build();
        shoppingCartInfoRequestVo.setTrackingNo(LogThreadLocal.getTrackingNo());
        shoppingCartInfoRequestVo.setEnableSharing(createOrderVo.getEnableSharing());
        // 如果使用优惠券或者商品券，校验 couponCode
//        if (StringUtils.isNotBlank(createOrderVo.getCouponCode())) {
//            // 校验couponCode
//            GetCouponDetailResponseDto getCouponDetailResponseDto = couponService.getMemberCoupon(GetMemberCouponRequestVo.builder()
//                    .partnerId(createOrderVo.getPartnerId())
//                    .couponCode(createOrderVo.getCouponCode()).build());
//            if (Objects.equals(getCouponDetailResponseDto, null) || CollectionUtils.isEmpty(getCouponDetailResponseDto.getDetails())
//                    || getCouponDetailResponseDto.getDetails().get(0).getActive() == null
//                    || getCouponDetailResponseDto.getDetails().get(0).getActive().getActiveCode() == null) {
//                // 返回信息为空
//                throw new ServiceException(ResponseResult.COUPON_GETINFO_INVAILD);
//            }
//            List<GetCouponDetailResponseDto.ActiveRedeemTimeInterval> activeRedeemTimeIntervalList = getCouponDetailResponseDto.getDetails().get(0).getActiveRedeemTimeIntervalList();
//            checkCouonRedeemTime(activeRedeemTimeIntervalList);
//            String activeCode = getCouponDetailResponseDto.getDetails().get(0).getActive().getActiveCode();
//            // 校验点餐方式,查询购物车接口内部已校验
//            shoppingCartInfoRequestVo.setCouponCode(createOrderVo.getCouponCode());
//            // 活动code
//            shoppingCartInfoRequestVo.setActivityCode(activeCode);
//            shoppingCartInfoRequestVo.setCardCode(createOrderVo.getCardCode());
//        }

        Set<String> codes = new HashSet<>();
        if (StringUtils.isNotBlank(createOrderVo.getCouponCode())) {
            codes.add(createOrderVo.getCouponCode());
        }
        if (CollectionUtils.isNotEmpty(createOrderVo.getCouponCodes())) {
            for (CreateOrderCouponCodeVo createOrderCouponCodeVo : createOrderVo.getCouponCodes()){
                codes.add(createOrderCouponCodeVo.getCouponCode());
            }
        }
        // 如果批量使用优惠券或者商品券，校验 couponCode
        List<ShoppingCartInfoRequestVo.couponCode> couponCodes = new ArrayList();
        if (CollectionUtils.isNotEmpty(codes)) {
            StringBuilder queryCodes = new StringBuilder();
            for (String code : codes){
                queryCodes = queryCodes.append(code).append(",");
            }
            // 校验couponCode
            GetCouponDetailResponseDto getCouponDetailResponseDto = couponService.getMemberCoupon(GetMemberCouponRequestVo.builder()
                    .partnerId(partnerId)
                    .couponCode(queryCodes.toString()).build());
            if (Objects.equals(getCouponDetailResponseDto, null) || CollectionUtils.isEmpty(getCouponDetailResponseDto.getDetails())
                    || getCouponDetailResponseDto.getDetails().get(0).getActive() == null
                    || getCouponDetailResponseDto.getDetails().get(0).getActive().getActiveCode() == null) {
                // 返回信息为空
                throw new ServiceException(ResponseResult.COUPON_GETINFO_INVAILD);
            }
            if(codes.size() != getCouponDetailResponseDto.getDetails().size()){
                throw new ServiceException(ResponseResult.COUPON_QUERY_ERROR);
            }
            int i = 1;
            for (GetCouponDetailResponseDto.Details details : getCouponDetailResponseDto.getDetails()){
                //券的可用时间段校验，点餐和结算页虽然有校验，但无法确定会立马下单，避免在创建订单成功后锁定优惠券失败，创建无效订单
                checkCouonRedeemTime(details.getActiveRedeemTimeIntervalList());
                ShoppingCartInfoRequestVo.couponCode coupon = new ShoppingCartInfoRequestVo.couponCode();
                coupon.setCouponCode(details.getCode());
                coupon.setActivityCode(details.getActive().getActiveCode());
                coupon.setIndex(i);
                i = i+1;
                coupon.setCouponType(details.getType());
                couponCodes.add(coupon);
            }
        }
        shoppingCartInfoRequestVo.setCouponCodes(couponCodes);
        if (StringUtils.isEmpty(shoppingCartInfoRequestVo.getCardCode())) {
            shoppingCartInfoRequestVo.setCardCode(createOrderVo.getCardCode());
        }
        // 通过购物车获取优惠信息
        GetShoppingCartGoodsApportionDto requestDto = new GetShoppingCartGoodsApportionDto();
        // 设置用户选择的买一赠一商品信息
        shoppingCartInfoRequestVo.setChooseGoods(JSONArray.parseArray(JSONObject.toJSONString(createOrderVo.getChooseGoods()), ShoppingCartInfoRequestVo.ChooseGood.class));
        requestDto.setShoppingCartInfoRequestVo(shoppingCartInfoRequestVo);
        //加价购商品 校验放购物车校验
        requestDto.setPremiumExchangeActivity(createOrderVo.getPremiumExchangeActivity());
        // 若为拼单类型，购物车信息从新的拼单购物车获取 update by miaohui for 【ID1010972】 多人拼单
        cn.freemud.base.entity.BaseResponse<ShoppingCartGoodsDto> apportionResponse;
        if (this.isCollageOrder(createOrderVo)) {
            apportionResponse = shoppingCartClient.getCollageShoppingCartGoodsApportion(requestDto);
        } else {
            apportionResponse = shoppingCartClient.getShoppingCartGoodsApportionNew(requestDto);
        }

        // 这个是专门的给coco使用的验证券的逻辑
        if (ObjectUtils.equals(ResponseCodeConstant.COCO_RESPONSE_COUPON_ERR_STR, apportionResponse.getCode())) {
            throw new ServiceException(ResponseResult.COCO_COUPON_VALIDATOR_FAIL, apportionResponse.getMessage());
        }
        if (ObjectUtils.equals(ResponseCodeConstant.USER_HAVE_NO_COUPON, apportionResponse.getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_USER_HAVE_NO_COUPON, apportionResponse.getMessage());
        }

        if (!ObjectUtils.equals(ResponseCodeConstant.RESPONSE_SUCCESS_STR, apportionResponse.getCode())) {
            ResponseResult responseResult = ResponseResult.getResponseResult(apportionResponse.getCode());
            throw new ServiceException(responseResult != null ? responseResult : ResponseResult.SHOPPING_CART_GETINFO_ERROR);
        }
        if (apportionResponse.getResult() == null || CollectionUtils.isEmpty(apportionResponse.getResult().getProducts())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        ShoppingCartGoodsDto shoppingCartGoodsDto = apportionResponse.getResult();
        if (shoppingCartGoodsDto.getOriginalTotalAmount() == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }


        // 拼单处理
        if (this.isCollageOrder(createOrderVo)) {
            // 处理拼单加购人信息
            List<ShoppingCartGoodsDto.CartGoodsDetailDto> products = shoppingCartGoodsDto.getProducts();
            ShoppingCartGoodsDto.CartGoodsDetailDto createUserGood = products.stream().filter(good -> createOrderVo.getUserId().equals(good.getUserId())).findFirst().orElse(null);

            if (null == createUserGood) {
                // 若拼单发起人未购买商品，则将赠品按购物车行分给加购人
                products.stream().filter(good -> null == good.getUserId()).collect(Collectors.toList()).forEach(cartGoodsNullUser -> {
                    ShoppingCartGoodsDto.CartGoodsDetailDto parentGood = products.stream().filter(good -> good.getCartGoodsUid().equals(cartGoodsNullUser.getCartGoodsUid())).findFirst().orElse(null);
                    cartGoodsNullUser.setUserId(parentGood == null ? createOrderVo.getUserId() : parentGood.getUserId());
                    cartGoodsNullUser.setOpenId(parentGood == null ? null : parentGood.getOpenId());
                    cartGoodsNullUser.setUserName(parentGood == null ? null : parentGood.getUserName());
                    cartGoodsNullUser.setPhotoUrl(parentGood == null ? null : parentGood.getPhotoUrl());
                });
            } else {
                products.stream().filter(good -> null == good.getUserId()).collect(Collectors.toList()).forEach(cartGoodsNullUser -> {
                    cartGoodsNullUser.setUserId(createUserGood.getUserId());
                    cartGoodsNullUser.setOpenId(createUserGood.getOpenId());
                    cartGoodsNullUser.setUserName(createUserGood.getUserName());
                    cartGoodsNullUser.setPhotoUrl(createUserGood.getPhotoUrl());
                });
            }
        }

        return shoppingCartGoodsDto;
    }

    private void checkCouonRedeemTime(List<GetCouponDetailResponseDto.ActiveRedeemTimeInterval> activeRedeemTimeIntervalList) {
        boolean verificationPassed = false;
        if (CollectionUtils.isNotEmpty(activeRedeemTimeIntervalList)) {
            for (GetCouponDetailResponseDto.ActiveRedeemTimeInterval dateLimit : activeRedeemTimeIntervalList) {
                boolean dayCheck = true;
                String weekday = dateLimit.getWeekday(); // 日期限制 0011100 周日开始,0表示不可用
                if (StringUtils.isNotBlank(weekday)) { // 存在校验周几
                    char[] chars = weekday.toCharArray();
                    int dayOfWeek = LocalDate.now().getDayOfWeek().getValue();  // 从周一开始
                    if (dayOfWeek == 7) {
                        dayOfWeek = 0;
                    }
                    if (Integer.parseInt(String.valueOf(chars[dayOfWeek])) == 0) { //限制
                        dayCheck = false;
                    }
                }
                boolean timeCheck = true;
                String begintime = dateLimit.getBegintime(); // 开始时间  00:00:00
                String endtime = dateLimit.getEndtime();  // 结束时间 12:59:59
                if (StringUtils.isNotBlank(begintime) && StringUtils.isNotBlank(endtime)) { // 存在校验时段
                    String[] beginTimeArr = begintime.split(":");
                    String[] endTimeArr = endtime.split(":");
                    LocalTime beginLocalTime = LocalTime.of(Integer.valueOf(beginTimeArr[0]), Integer.valueOf(beginTimeArr[1]), Integer.valueOf(beginTimeArr[2]));
                    LocalTime endLocalTime = LocalTime.of(Integer.valueOf(endTimeArr[0]), Integer.valueOf(endTimeArr[1]), Integer.valueOf(endTimeArr[2]));
                    LocalTime now = LocalTime.now();
                    if (now.isBefore(beginLocalTime) || now.isAfter(endLocalTime)) {
                        timeCheck = false;
                    }
                }
                if (dayCheck && timeCheck) {
                    verificationPassed = true;
                    break;
                }
            }
        } else {
            verificationPassed = true;
        }
        if (!verificationPassed) {
            throw new ServiceException(ResponseResult.COUPON_DATETIME_INVAILD);
        }

    }

    /**
     * 获取门店配送信息
     */
    @Deprecated
    public StoreDeliveryInfoDto getStoreDeliveryInfo(StoreResponseDto storeResponseDto,
                                                     AssortmentOpenPlatformIappWxappConfig openPlatformIappWxappConfig, String wxAppid) {
        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(storeResponseDto.getPartnerId());
        storeDeliveryInfoDto.setStoreId(storeResponseDto.getStoreCode());
        storeDeliveryInfoDto.setStoreName(storeResponseDto.getStoreName());
        storeDeliveryInfoDto.setStoreNameEn(storeResponseDto.getStoreNameEn());
        // 查询外卖配送信息
        AssortmentOpenPlatformPartnerStoreDeliveryConfig deliveryConfig = deliveryConfigManager.findByPartnerIdAndStoreCode(storeResponseDto.getPartnerId(),
                storeResponseDto.getStoreCode());
        if (deliveryConfig == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
        }
        // 判断门店是否启用外卖，只有当小程序开通外卖，且门店开通外卖,设置 外卖配送时间 才开启外卖功能
        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(storeResponseDto.getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponseDto.getDeliveryHoursDay());
        storeDeliveryInfoDto.setLongitude(storeResponseDto.getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponseDto.getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponseDto.getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponseDto.getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponseDto.getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }
        // 只有小程序设置了外卖，并且开通了第三方配送账户，才是第三方配送单
        if (openPlatformIappWxappConfig == null) {
            openPlatformIappWxappConfig = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(wxAppid);
        }
        if (openPlatformIappWxappConfig == null) {
            storeDeliveryInfoDto.setDeliveryType("self");
            storeDeliveryInfoDto.setPushOrderTime(0);
        } else {
            //如果是coco查询配送服务判断是平台配送还是自配送
//            if (cocoPartnerId.equals(storeResponseDto.getPartnerId())) {
//                GetDeliveryFlagRequest getDeliveryFlagRequest = new GetDeliveryFlagRequest();
//                getDeliveryFlagRequest.setPartnerId(storeResponseDto.getPartnerId());
//                getDeliveryFlagRequest.setStoreId(storeResponseDto.getStoreId());
//                DeliveryBaseResponse<GetDeliveryFlagResponseDto> deliveryBaseResponse = deliveryFeiginClient.getThirdDeliveryFlag(getDeliveryFlagRequest);
//                if (deliveryBaseResponse.getCode() == 100 && deliveryBaseResponse.getData() != null && deliveryBaseResponse.getData().isThirdDeliveryFlag()) {
//                    storeDeliveryInfoDto.setDeliveryType("third");
//                    storeDeliveryInfoDto.setPushOrderTime(0);
//                } else {
//                    storeDeliveryInfoDto.setDeliveryType("self");
//                    storeDeliveryInfoDto.setPushOrderTime(0);
//                }
//            } else {
                if (ObjectUtils.equals(openPlatformIappWxappConfig.getTakeType(), 1)) {
                    storeDeliveryInfoDto.setDeliveryType("self");
                    storeDeliveryInfoDto.setPushOrderTime(0);
                } else {
                    storeDeliveryInfoDto.setDeliveryType("third");
                    storeDeliveryInfoDto.setPushOrderTime(0);
//                }
            }
        }
        return storeDeliveryInfoDto;
    }



    /**
     * 获取门店配送信息
     */
//    public StoreDeliveryInfoDto getNewStoreDeliveryInfo(StoreResponseDto storeResponseDto) {
//        String trackingNo = LogThreadLocal.getTrackingNo();
//        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
//        storeDeliveryInfoDto.setPartnerId(storeResponseDto.getPartnerId());
//        storeDeliveryInfoDto.setStoreId(storeResponseDto.getStoreCode());
//        storeDeliveryInfoDto.setStoreName(storeResponseDto.getStoreName());
//        // 查询外卖配送信息
//        QueryDeliveryRequest queryDeliveryRequest = new QueryDeliveryRequest();
//        queryDeliveryRequest.setPartnerId(storeResponseDto.getPartnerId());
//        queryDeliveryRequest.setStoreCode(storeResponseDto.getStoreCode());
//        BaseResponse<QueryDeliverDetailResponse> queryDeliverDetailResponse = storeCenterService.queryDeliverDetail(queryDeliveryRequest, trackingNo);
//        if (queryDeliverDetailResponse == null || !ResponseResult.SUCCESS.getCode().equals(queryDeliverDetailResponse.getCode()) || queryDeliverDetailResponse.getData() == null) {
//            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
//        }
//        QueryDeliverDetailResponse deliveryDetail = queryDeliverDetailResponse.getData();
//        // 判断门店是否启用外卖，只有当小程序开通外卖，且门店开通外卖,设置 外卖配送时间 才开启外卖功能
//        storeDeliveryInfoDto.setDeliveryLimitAmount(StringUtils.isBlank(deliveryDetail.getMinOrderPrice()) ? 0L : Long.parseLong(deliveryDetail.getMinOrderPrice()));
//        storeDeliveryInfoDto.setDeliveryAmount(StringUtils.isBlank(deliveryDetail.getDeliveryFee()) ? 0L : Long.parseLong(deliveryDetail.getDeliveryFee()));
//        storeDeliveryInfoDto.setDefaultDeliveryRange(StringUtils.isBlank(deliveryDetail.getDeliveryRange()) ? 0L : Long.parseLong(deliveryDetail.getDeliveryRange()));
//        storeDeliveryInfoDto.setAddRangeAmount(StringUtils.isBlank(deliveryDetail.getAddRangeAmount()) ? 0L : Long.parseLong(deliveryDetail.getAddRangeAmount()));
//        storeDeliveryInfoDto.setAddRangeCount(StringUtils.isBlank(deliveryDetail.getAddRange()) ? 0L : Long.parseLong(deliveryDetail.getAddRange()));
//        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponseDto.getDistributionScope()));
//        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponseDto.getDeliveryHoursDay());
//        storeDeliveryInfoDto.setLongitude(storeResponseDto.getLongitude());
//        storeDeliveryInfoDto.setLatitude(storeResponseDto.getLatitude());
//        storeDeliveryInfoDto.setScopeConfig(storeResponseDto.getScopeConfig());
//        if (StringUtils.isNotEmpty(storeResponseDto.getDeliveryRadius())) {
//            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponseDto.getDeliveryRadius()));
//        } else {
//            storeDeliveryInfoDto.setDeliveryRadius(0);
//        }
//        // 只有小程序设置了外卖，并且开通了第三方配送账户，才是第三方配送单 不可能为空，调用地方已查
////        if (openPlatformIappWxappConfig == null) {
////            openPlatformIappWxappConfig = openPlatformIappWxappConfigManager.selectIappWxappConfigByWxAppId(wxAppid);
////        }
//        storeDeliveryInfoDto.setDeliveryType("self");
//        storeDeliveryInfoDto.setPushOrderTime(0);
////        if (openPlatformIappWxappConfig == null) {
////            storeDeliveryInfoDto.setDeliveryType("self");
////            storeDeliveryInfoDto.setPushOrderTime(0);
////        } else {
//            //如果是coco查询配送服务判断是平台配送还是自配送
////            if (cocoPartnerId.equals(storeResponseDto.getPartnerId())) {
////                GetDeliveryFlagRequest getDeliveryFlagRequest = new GetDeliveryFlagRequest();
////                getDeliveryFlagRequest.setPartnerId(storeResponseDto.getPartnerId());
////                getDeliveryFlagRequest.setStoreId(storeResponseDto.getStoreId());
////                DeliveryBaseResponse<GetDeliveryFlagResponseDto> deliveryBaseResponse = deliveryFeiginClient.getThirdDeliveryFlag(getDeliveryFlagRequest);
////                if (deliveryBaseResponse.getCode() == 100 && deliveryBaseResponse.getData() != null && deliveryBaseResponse.getData().isThirdDeliveryFlag()) {
////                    storeDeliveryInfoDto.setDeliveryType("third");
////                    storeDeliveryInfoDto.setPushOrderTime(0);
////                } else {
////                    storeDeliveryInfoDto.setDeliveryType("self");
////                    storeDeliveryInfoDto.setPushOrderTime(0);
////                }
////            } else {
////                if (ObjectUtils.equals(openPlatformIappWxappConfig.getTakeType(), 1)) {
////                    storeDeliveryInfoDto.setDeliveryType("self");
////                    storeDeliveryInfoDto.setPushOrderTime(0);
////                } else {
////                    storeDeliveryInfoDto.setDeliveryType("third");
////                    storeDeliveryInfoDto.setPushOrderTime(0);
////                }
////            }
////        }
//        storeDeliveryInfoDto.setDeliveryCondition(deliveryDetail.getDeliveryType());
//        storeDeliveryInfoDto.setFreeDeliveryCup(deliveryDetail.getFreeDeliveryCup());
//        return storeDeliveryInfoDto;
//    }

    /**
     * 获取配送范围内集合
     */
    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;
    }

    /**
     * 校验收货地址是否可配送
     */
//    public void checkReceiveAddress(StoreDeliveryInfoDto storeDeliveryInfoDto, CreateOrderVo createOrderVo, String storeCode) {
//        //校验收货地址是否可配送
//        String receiveId = createOrderVo.getReceiveId();
//        String trackingNo = LogThreadLocal.getTrackingNo();
//        QueryReceiveAddressRequest request = new QueryReceiveAddressRequest(receiveId, storeDeliveryInfoDto.getPartnerId());
//        BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(request, trackingNo);
//        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
//            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR);
//        }
//        QueryReceiveAddressResponse receiveAddressResult = queryReceiveAddressResponse.getData();
//
//        //组装代码移出来了
//        UserDeliveryInfoDto userDeliveryInfoDto = UserDeliveryInfoDto.builder()
//                .userLongitude(receiveAddressResult.getLongitude())
//                .userLatitude(receiveAddressResult.getLatitude())
//                .deliveryLimitAmount(storeDeliveryInfoDto.getDeliveryLimitAmount())
//                .userEnableTakeaway(true)
//                .realDeliveryAmount(0L)
//                .storeId(storeDeliveryInfoDto.getStoreId())
//                .storeName(storeDeliveryInfoDto.getStoreName())
//                .storeDeliveryInfoDto(storeDeliveryInfoDto)
//                .build();
////        if (!userDeliveryInfoDto.getUserEnableTakeaway()) {
////            throw new ServiceException(ResponseResult.ORDER_TAKE_OUT_ADDRESS_NOT_DELIVERY);
////        }
//        if (BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(createOrderVo.getMenuType())) {
//            /**
//             * @see StoreDeliveryMethod
//             */
//            String deliveryTypeCode = this.checkDeliveryType(createOrderVo, storeCode, trackingNo);
//            userDeliveryInfoDto.getStoreDeliveryInfoDto().setDeliveryType(deliveryTypeCode);
//
//            // 【ID1030916】订单查询门店获取预计送达时间 并且不是预约单
//            if (StringUtils.isEmpty(createOrderVo.getExpectTime())
//                    && !this.getIsAdvanceOrder(createOrderVo.getBizType())) {
//                userDeliveryInfoDto.setEstimateDeliveryCompleteTime(getEstimateDeliveryCompleteTime(receiveAddressResult.getLatitude(), receiveAddressResult.getLongitude(), storeDeliveryInfoDto.getPartnerId(), storeDeliveryInfoDto.getStoreId()));
//            }
//        }
//        userDeliveryInfoDto.setReceiveUserName(receiveAddressResult.getReceiveName());
//        userDeliveryInfoDto.setReceiveMobile(StringUtils.isEmpty(receiveAddressResult.getMobile()) ? receiveAddressResult.getReceiveMobile() : receiveAddressResult.getMobile());
//        String receiveAddress = receiveAddressResult.getReceiveAddress();
//        if (StringUtils.isNotBlank(receiveAddress)) {
//            userDeliveryInfoDto.setReceiveAddress(receiveAddress);
//            if (receiveAddress.contains("officeName") && receiveAddress.contains("address")) {
//                JSONObject jsonObject = JSONObject.parseObject(receiveAddress);
//                userDeliveryInfoDto.setReceiveOfficeName(jsonObject.getString("officeName"));
//                userDeliveryInfoDto.setReceiveAddress(jsonObject.getString("address"));
//            }
//        }
//        createOrderVo.setUserName(receiveAddressResult.getReceiveName());
//        createOrderVo.setMobile(StringUtils.isEmpty(receiveAddressResult.getMobile()) ? receiveAddressResult.getReceiveMobile() : receiveAddressResult.getMobile());
//        createOrderVo.setUserDeliveryInfoDto(userDeliveryInfoDto);
//    }

    public void builderUserDeliveryInfoDto(CreateOrderBONew createOrderBO,DeliveryInfoDTO deliveryInfo) {
        CreateOrderVo createOrderVo = createOrderBO.getCreateOrderVo();
        StoreMixResponseDto storeMixResponseDto = createOrderBO.getStoreMixResponseDto();
        StoreResponseDto storeResponseDto = storeMixResponseDto.getStoreInfo();

        //校验收货地址是否可配送
        String receiveId = createOrderVo.getReceiveId();
        String trackingNo = LogThreadLocal.getTrackingNo();
        QueryReceiveAddressRequest request = new QueryReceiveAddressRequest(receiveId, createOrderVo.getPartnerId());
        BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(request, trackingNo);
        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR);
        }
        QueryReceiveAddressResponse receiveAddressResult = queryReceiveAddressResponse.getData();

        StoreDeliveryInfoDto storeDeliveryInfoDto = builderStoreDeliveryInfoDto(createOrderBO, deliveryInfo);
        //组装代码移出来了
        UserDeliveryInfoDto userDeliveryInfoDto = UserDeliveryInfoDto.builder()
                .userLongitude(receiveAddressResult.getLongitude())
                .userLatitude(receiveAddressResult.getLatitude())
//                .deliveryLimitAmount(deliveryInfo.getMinOrderPrice())
                .userEnableTakeaway(true)
                .realDeliveryAmount(0L)
                .storeId(storeResponseDto.getStoreCode())
                .storeName(storeResponseDto.getStoreName())
                .storeDeliveryInfoDto(storeDeliveryInfoDto)
                .build();
//        if (!userDeliveryInfoDto.getUserEnableTakeaway()) {
//            throw new ServiceException(ResponseResult.ORDER_TAKE_OUT_ADDRESS_NOT_DELIVERY);
//        }
        if (BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(createOrderVo.getMenuType())) {
            /**
             * @see StoreDeliveryMethod
             */
            String deliveryTypeString = storeDeliveryInfoDto.getDeliveryTypeString();
            userDeliveryInfoDto.getStoreDeliveryInfoDto().setDeliveryType(deliveryTypeString);

            // 【ID1030916】订单查询门店获取预计送达时间 并且不是预约单
            if (StringUtils.isEmpty(createOrderVo.getExpectTime())
                    && !this.getIsAdvanceOrder(createOrderVo.getBizType())) {
                userDeliveryInfoDto.setEstimateDeliveryCompleteTime(getEstimateDeliveryCompleteTime(receiveAddressResult.getLatitude(), receiveAddressResult.getLongitude(), storeDeliveryInfoDto.getPartnerId(), storeDeliveryInfoDto.getStoreId()));
            }
        }
        userDeliveryInfoDto.setReceiveUserName(receiveAddressResult.getReceiveName());
        userDeliveryInfoDto.setReceiveMobile(StringUtils.isEmpty(receiveAddressResult.getMobile()) ? receiveAddressResult.getReceiveMobile() : receiveAddressResult.getMobile());
        String receiveAddress = receiveAddressResult.getReceiveAddress();
        if (StringUtils.isNotBlank(receiveAddress)) {
            userDeliveryInfoDto.setReceiveAddress(receiveAddress);
            if (receiveAddress.contains("officeName") && receiveAddress.contains("address")) {
                JSONObject jsonObject = JSONObject.parseObject(receiveAddress);
                userDeliveryInfoDto.setReceiveOfficeName(jsonObject.getString("officeName"));
                userDeliveryInfoDto.setReceiveAddress(jsonObject.getString("address"));
            }
        }
        createOrderVo.setUserName(receiveAddressResult.getReceiveName());
        createOrderVo.setMobile(StringUtils.isEmpty(receiveAddressResult.getMobile()) ? receiveAddressResult.getReceiveMobile() : receiveAddressResult.getMobile());
        createOrderVo.setUserDeliveryInfoDto(userDeliveryInfoDto);
        createOrderBO.setUserDeliveryInfoDto(userDeliveryInfoDto);
    }

    public StoreDeliveryInfoDto builderStoreDeliveryInfoDto(CreateOrderBONew createOrderBO,DeliveryInfoDTO deliveryDetail) {
        StoreMixResponseDto storeMixResponseDto = createOrderBO.getStoreMixResponseDto();
        StoreResponseDto storeResponseDto = storeMixResponseDto.getStoreInfo();

        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(storeResponseDto.getPartnerId());
        storeDeliveryInfoDto.setStoreId(storeResponseDto.getStoreCode());
        storeDeliveryInfoDto.setStoreName(storeResponseDto.getStoreName());
        storeDeliveryInfoDto.setDeliveryLimitAmount(StringUtils.isBlank(deliveryDetail.getMinOrderPrice()) ? 0L : Long.parseLong(deliveryDetail.getMinOrderPrice()));
        storeDeliveryInfoDto.setDeliveryAmount(StringUtils.isBlank(deliveryDetail.getDeliveryFee()) ? 0L : Long.parseLong(deliveryDetail.getDeliveryFee()));
        storeDeliveryInfoDto.setDefaultDeliveryRange(StringUtils.isBlank(deliveryDetail.getDeliveryRange()) ? 0L : Long.parseLong(deliveryDetail.getDeliveryRange()));
        storeDeliveryInfoDto.setAddRangeAmount(deliveryDetail.getAddRangeAmount() == null ? 0L : deliveryDetail.getAddRangeAmount().longValue());
        storeDeliveryInfoDto.setAddRangeCount(StringUtils.isBlank(deliveryDetail.getAddRange()) ? 0L : Long.parseLong(deliveryDetail.getAddRange()));
        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponseDto.getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponseDto.getDeliveryHoursDay());
        storeDeliveryInfoDto.setLongitude(storeResponseDto.getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponseDto.getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponseDto.getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponseDto.getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponseDto.getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }
        storeDeliveryInfoDto.setDeliveryType("self");
        storeDeliveryInfoDto.setPushOrderTime(0);
        storeDeliveryInfoDto.setDeliveryCondition(deliveryDetail.getDeliveryType());
        storeDeliveryInfoDto.setFreeDeliveryCup(deliveryDetail.getFreeDeliveryCup());

        String method = StoreDeliveryMethod.SELF.getCode();
        if(deliveryDetail.getDeliveryMethod() != null){
            method = deliveryDetail.getDeliveryMethod().toString();
        }
        String code = StoreDeliveryMethod.getCodeByType(method);
        storeDeliveryInfoDto.setDeliveryTypeString(code);
        return storeDeliveryInfoDto;
    }


    /**
     * 获取 用户预计送达时间 距离
     *
     * @param userLat   用户纬度
     * @param userLong  用户经度
     * @param partnerId 商户号
     * @param storeCode 门店号
     * @return
     */
    private Date getEstimateDeliveryCompleteTime(String userLat,
                                                 String userLong,
                                                 String partnerId,
                                                 String storeCode) {
        boolean check = StringUtils.isEmpty(userLat) ||
                StringUtils.isEmpty(userLong) ||
                StringUtils.isEmpty(partnerId) ||
                StringUtils.isEmpty(storeCode);
        if (check) {
            throw new ServiceException(ResponseResult.PARAMETER_MISSING);
        }
        // 调用门店接口 获取时间  Fisherman
        GetEstimateDeliveryRequest request = GetEstimateDeliveryRequest.builder().latitude(userLat).longitude(userLong).build();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeCode);
        StoreCBaseResponse<StoreCBaseResponseDto> responseDto = storeBaseApiClient.queryDeliverDetail(request);
        if (responseDto == null) {
            throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }

        if (!ResponseResult.SUCCESS.getCode().equals(responseDto.getCode()) || responseDto.getResult() == null) {
            throw new ServiceException(ResponseResult.STORE_QUERYEXPECTARRIVETIME);
        }
        return responseDto.getResult().getExpectArriveTime();
    }


    /**
     * 校验卡是否是该会员的
     */
    public List<GetSvcInfoByMemberIdResponseVo> checkCardCode(String partnerId, String memberId, Set<String> cardCodes) {
        if (CollectionUtils.isEmpty(cardCodes)) {
            return null;
        }
        StatisticalScoreRequestVo request = new StatisticalScoreRequestVo();
        request.setPartnerId(partnerId);
        request.setMemberId(memberId);
        request.setApplyType(-1);
        CustomerPropertyBaseResponse<List<GetSvcInfoByMemberIdResponseVo>> responseDTO = customerPropertyClient.getMemberCards(request);
        if (!ResponseResult.SUCCESS.getCode().equals(responseDTO.getCode()) || responseDTO.getData() == null
                || responseDTO.getData().size() == 0) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        List<GetSvcInfoByMemberIdResponseVo> memberDatas = responseDTO.getData().stream().filter(data -> data.getStatusFlag() == 0).collect(Collectors.toList());
        Set<String> memberCardCodes = memberDatas.stream().map(GetSvcInfoByMemberIdResponseVo :: getCardCode).collect(Collectors.toSet());
        if(!memberCardCodes.containsAll(cardCodes)){
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        return memberDatas;
    }

    public void checkOrderByStore(StoreResponseDto storeResponseDto) {
        // 校验门店是否停业 1 营业 2 停业 3 繁忙置休
        if (storeResponseDto.getActiveFlag() == null || storeResponseDto.getActiveFlag() != 1) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
//        //设置营业开始和结束时间
//        String businessHourStr = storeResponseDto.getBusinessHoursDay().replace("-", ",").replace("_", ",");
//        String[] businessHours = businessHourStr.split(",");
//        if (businessHours.length != 2) {
//            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
//        }
//        Date date = new Date();
//        String startDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[0] + ":00";
//        String endDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
//        Date startDateTime ;
//        Date endDateTime ;
//        startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
//        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        try {
//            endDateTime = hhmmss.parse(endDateTimeStr);
//        } catch (ParseException e) {
//            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
//        }
//        //隔天营业时间处理
//        if(startDateTime.after(endDateTime)){
//            endDateTime = DateUtil.addDays(endDateTime,1);
//        }
//        storeResponseDto.setBusinessHoursDayStartTime(startDateTime);
//        storeResponseDto.setBusinessHoursDayEndTime(endDateTime);
//
//        // 校验门店是否打烊，打烊了则不让操作
//        if (storeResponseDto.getBusinessHoursDayStartTime() == null
//                || storeResponseDto.getBusinessHoursDayEndTime() == null) {
//            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
//        }
    }

    /**
     * 判断是否为拼单订单
     *
     * @param createOrderVo
     * @return
     */
    private boolean isCollageOrder(CreateOrderVo createOrderVo) {
        return createOrderVo.getMarketingType() != null && MarketTypeEnum.COLLAGE.getIndex().byteValue() == createOrderVo.getMarketingType();
    }

    /**
     * 校验配送信息
     * 这里可以获取用户的  预计送达时间
     *
     * @param createOrderVo
     * @param storeCode
     * @param trackingNo
     * @return
     */
//    public String checkDeliveryType(CreateOrderVo createOrderVo, String storeCode, String trackingNo) {
//        String code = "";
//        QueryDeliveryRequest request = new QueryDeliveryRequest();
//        request.setStoreCode(storeCode);
//        request.setPartnerId(createOrderVo.getPartnerId());
//        request.setUserLatitude(createOrderVo.getLatitude());
//        request.setUserLongitude(createOrderVo.getLongitude());
//        BaseResponse<QueryDeliverDetailResponse> query = storeCenterService.queryDeliverDetail(request, trackingNo);
//        if (null == query || !ResponseResult.SUCCESS.getCode().equals(query.getCode())) {
//            throw new ServiceException(ResponseResult.STORE_DDELIVERY_METHOD);
//        }
//        String method = query.getData().getDeliveryMethod();
//        //StoreDeliveryMethod.
//        code = StoreDeliveryMethod.getCodeByType(method);
//        if (StringUtils.isBlank(code)) {
//            throw new ServiceException(ResponseResult.STORE_DDELIVERY_METHOD);
//        }
//        return code;
//    }

    /**
     *  fisherman 预定单营业时间校验
     * @param businessType
     * @param businessHoursDay
     * @param takeMealDateTime
     */
    private void getBusinessTimeByType(Integer businessType, String businessHoursDay, Date takeMealDateTime) {
        if (businessType == null) {
            throw new ServiceException(ResponseResult.STORE_DATE_ERROR);
        }
        if (businessType.compareTo(1) == 0) {
            this.getBusinessTimeByType1(businessHoursDay, takeMealDateTime);
        } else if (businessType.compareTo(2) == 0) {
            this.getBusinessTimeByType2(businessHoursDay, takeMealDateTime);
        }
    }

    private void getBusinessTimeByType2(String businessHoursDay, Date takeMealDateTime) {
        String[] splitArr = businessHoursDay.split("；");
        // 取值
        // 获取当前星期几,  0 表示 周日
        int weekDay = DateUtil.getWeekDay(takeMealDateTime);
        int index = weekDay - 1;
        index = index < 0 ? splitArr.length - 1 : index;
        // 数组里面取值  00-00 就是没设置
        String businessHours = splitArr[index];
        if ("00: 00-00: 00".equals(businessHours)) {
            // 不在营业时间范围
            throw new ServiceException(ResponseResult.STORE_NO_OPEN);
        }
        // 获取营业时间
        int weekDay1 = this.getWeekDay(new Date(), takeMealDateTime);
        BusinessDate storeBusinessDate = this.getStoreBusinessDate(businessHours, weekDay1);

        // 检验 是否在营业时间 范围内
        if (takeMealDateTime.before(storeBusinessDate.getStartDate()) || takeMealDateTime.after(storeBusinessDate.getEndDate())) {
            // 不在营业时间范围
            throw new ServiceException(ResponseResult.STORE_NO_OPEN);
        }
    }

    public BusinessDate getStoreBusinessDate(String businessHoursDay, int today) {
        BusinessDate businessDate = new BusinessDate();
        //设置营业开始和结束时间
        String businessHourStr = businessHoursDay.replace("-", ",").replace("_", ",");
        String[] businessHours = businessHourStr.split(",");
        if (businessHours.length != 2) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        Date date = DateUtil.addDays(new Date(), today);
        String startDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[0] + ":00";
        String endDateTimeStr = DateUtil.convert2String(date, DateUtil.FORMAT_YMD) + " " + businessHours[1] + ":00";
        Date startDateTime;
        Date endDateTime;
        startDateTime = DateUtil.convert2Date(startDateTimeStr, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
        //判断营业开始时间是24:00点
        if (startDateTime == null) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        SimpleDateFormat hhmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            endDateTime = hhmmss.parse(endDateTimeStr);
        } catch (ParseException e) {
            throw new ServiceException(ResponseResult.STORE_BUSINESS_HOUR_ERROR);
        }
        //隔天营业时间处理
        if (startDateTime.after(endDateTime)) {
            endDateTime = DateUtil.addDays(endDateTime, 1);
        }
        // 校验门店是否打烊，打烊了则不让操作
        if (endDateTime == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_STOP_BUSINESS);
        }
        businessDate.setStartDate(startDateTime);
        businessDate.setEndDate(endDateTime);
        return businessDate;
    }


    /**
     * 获取 2个时间之间的天数
     *
     * @return
     */
    private int getWeekDay(Date begin, Date end) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(end);
        int endDay = calendar.get(Calendar.DAY_OF_YEAR);

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(begin);
        int begDay = calendar2.get(Calendar.DAY_OF_YEAR);
        return endDay - begDay;
    }

    private void getBusinessTimeByType1(String businessHoursDay, Date takeMealDateTime) {
        String[] splitArr = businessHoursDay.split("；");
        boolean isBusinessTime = false;
        int diffDay = DateUtils.diffDay(new Date(), takeMealDateTime);
        for (String businessHours : splitArr) {
            if ("00: 00-00: 00".equals(businessHours)) {
                // 不在营业时间范围
                throw new ServiceException(ResponseResult.STORE_NO_OPEN);
            }
            // 获取营业时间
            BusinessDate storeBusinessDate = getStoreBusinessDate(businessHours, diffDay);
            // 检验 是否在营业时间 范围内
            if (takeMealDateTime.after(storeBusinessDate.getStartDate()) && takeMealDateTime.before(storeBusinessDate.getEndDate())) {
                // 在营业时间范围
                isBusinessTime = true;
            }
        }
        if (!isBusinessTime) {
            throw new ServiceException(ResponseResult.STORE_NO_OPEN);
        }
    }

    public UnifiedOrderRequestDto convert2UnifiedOrderRequestDto(OrderInfoReqs orderInfo, String openId, Long cashPrice,
                                                                 Long clientCode, String reverseNotifyiDcUrl, String payTimeOutTime) {

        String partnerId = orderInfo.getPartnerId();
        String storeId = orderInfo.getStoreId();
        String appId = orderInfo.getAppId();

        //现金支付唤起线上支付
        UnifiedOrderRequestDto requestDto = new UnifiedOrderRequestDto();
        requestDto.setTransId(orderInfo.getOrderCode());
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        requestDto.setAmount(cashPrice);

        String businessDate = DateUtil.convert2String(new Date(), "yyyyMMdd");
        requestDto.setBusinessDate(businessDate);
        requestDto.setClientCode(clientCode);
        requestDto.setFoodOrderType(getFoodOrderType(1));
        requestDto.setNotifyUrl(reverseNotifyiDcUrl);
        requestDto.setOpenId(openId);
        requestDto.setPayTimeOutTime(payTimeOutTime);
        List<PayProductDto> productBeans = new ArrayList<>();
        String payProductName = "";
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(orderInfo.getOrderItemList())) {

            for (OrderItemResp orderProductBean : orderInfo.getOrderItemList()) {
                PayProductDto productBean = new PayProductDto();
                productBean.setId(orderProductBean.getProductId());
                productBean.setQuantity(orderProductBean.getProductQuantity());
                productBean.setPrice(orderProductBean.getProductPrice().longValue());
                if (StringUtils.isNotBlank(payProductName)) {
                    payProductName = orderProductBean.getProductName();
                } else if (payProductName.endsWith("...")) {
                    //不处理
                } else {
                    payProductName = payProductName + "...";
                }
                productBean.setName(orderProductBean.getProductName());
                productBeans.add(productBean);
            }
        }
        requestDto.setProducts(productBeans);
        requestDto.setBody(payProductName);
        requestDto.setSubAppid(orderInfo.getAppId());
        //支付类型编码 TWX:微信 TZFB:支付宝
        requestDto.setPayTypeCode(convertPayTypeCode(orderInfo.getOrderClient().toString()));
        return requestDto;
    }

    /**
     * 支付类型编码 TWX:微信 TZFB:支付宝
     */
    public String convertPayTypeCode(String orderClient) {
        String payTypeCode = "";
        switch (orderClient) {
            case "2":
                payTypeCode = "TWX";
                break;
            case "3":
                payTypeCode = "TZFB";
                break;
            default:
                break;
        }
        return payTypeCode;
    }

    /**
     * 预支付接口获取类型
     * @return
     */
    private String getFoodOrderType(Integer orderType) {
        //1=外卖 4=自提，5=堂食
        //qr_order（店内扫码点餐）,pre_order（预点到店自提）,home_delivery （外送到家）
        String foodOrderType;
        switch (orderType) {
            case 1:
                foodOrderType = "home_delivery";
                break;
            case 4:
                foodOrderType = "pre_order";
                break;
            case 5:
            default:
                foodOrderType = "qr_order";
                break;
        }
        return foodOrderType;
    }

    public void convent2CreateOrderResponseVo(CreateOrderResponseVo createOrderResponseVo, String appId, UnifiedPayResponseDto response){
        createOrderResponseVo.setWxappId(appId);
        createOrderResponseVo.setFmId(response.getFmId());
        createOrderResponseVo.setPaySuccess(false);
        String payOrderDto = response.getPayOrder();
        PayOrderDto payOrder = JSONObject.parseObject(payOrderDto, PayOrderDto.class);
        if (payOrder != null) {
            createOrderResponseVo.setTimestamp(payOrder.getTimestamp());
            createOrderResponseVo.setNonceStr(payOrder.getNonceStr());
            createOrderResponseVo.setPackageX(payOrder.getPackageX());
            createOrderResponseVo.setSignType(payOrder.getSignType());
            createOrderResponseVo.setSign(payOrder.getPaySign());
            createOrderResponseVo.setOrderStr(payOrder.getAliPayOrder());
        }
    }


}
