package cn.freemud.service.impl;

import cn.freemud.adapter.CreateOrderAdapter;
import cn.freemud.adapter.LightApplicationConvertToAssortmentSdkAdapter;
import cn.freemud.adapter.OrderAdapter;
import cn.freemud.amp.service.SendCouponService;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.CommonRedisKeyConstant;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.Active;
import cn.freemud.entities.bo.CreateOrderBONew;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.coupon.CouponResponseDTO;
import cn.freemud.entities.dto.coupon.FastBatchQueryTemplateInfoRequest;
import cn.freemud.entities.dto.coupon.FastTemplateInfoResponseVO;
import cn.freemud.entities.dto.order.CreatePrepayRequestDto;
import cn.freemud.entities.dto.order.UnifiedPayResponseDto;
import cn.freemud.entities.dto.pay.OrderPayResponse;
import cn.freemud.entities.dto.pay.PayOrderDto;
import cn.freemud.entities.dto.pay.UnifiedOrderRequestDto;
import cn.freemud.entities.dto.product.GetValidateProductInfoDto;
import cn.freemud.entities.dto.product.ProductInfo;
import cn.freemud.entities.dto.product.ValidateProductInfosDto;
import cn.freemud.entities.dto.promotion.CalculationDiscountGoodsDto;
import cn.freemud.entities.dto.promotion.CalculationDiscountRequestDto;
import cn.freemud.entities.dto.store.StoreMixResponseDto;
import cn.freemud.entities.live.WeChatReportVO;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.handler.WeChatLiveMsgHandle;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.manager.BuyProductOnceManager;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.CouponService;
import cn.freemud.service.OrderFactoryService;
import cn.freemud.service.business.OrderBusinessService;
import cn.freemud.service.thirdparty.CouponOnlineClient;
import cn.freemud.service.thirdparty.PromotionDiscountClient;
import cn.freemud.service.thirdparty.StoreItemClient;
import cn.freemud.utils.AppLogUtil;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformIappWxappStore;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartnerConfig;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformIappWxappStoreManager;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerConfigManager;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.log.ThirdPartyLog;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.entities.v1.ProductBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.CreateOrderSceneEnum;
import com.freemud.application.sdk.api.ordercenter.enums.*;
import com.freemud.application.sdk.api.ordercenter.request.OrderChangeStateReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest;
import com.freemud.application.sdk.api.ordercenter.request.create.DeliveryContactInfoCreateReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderItemCreateReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderSettlementCreateReq;
import com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp;
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.ordercenter.service.OrderSdkService;
import com.freemud.application.sdk.api.productcenter.service.MenuService;
import com.freemud.application.sdk.api.promotioncenter.response.PromotionResponseDTO;
import com.freemud.application.sdk.api.stockapi.request.UpdateStocksRequest;
import com.freemud.application.sdk.api.stockapi.service.StockSdkService;
import com.freemud.sdk.api.assortment.order.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.entities.promption.ActivityUpdateStockRequest;
import com.freemud.sdk.api.assortment.order.entities.promption.SubtractStockVO;
import com.freemud.sdk.api.assortment.order.enums.StockChangeType;
import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.response.order.BaseOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.CreateOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.PayAccessResponse;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import com.freemud.thirdparty.wechat.entities.vo.request.OrderCreateRequestVO;
import com.google.common.collect.Maps;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.freemud.application.sdk.api.ordercenter.enums.OrderType.*;
import static com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant.RESPONSE_SUCCESS_STR;

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

@Service
public class SellCouponOrderServiceImpl implements OrderFactoryService {

    @Autowired
    private CheckOrder checkOrder;
    @Autowired
    private MenuService menuService;
    @Autowired
    private OrderSdkService orderSdkService;
    //聚合订单服务
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;
    @Autowired
//    private StoreCenterService storeCenterService;
    private StoreServiceImpl storeService;
    @Autowired
    private OrderAdapter orderAdapter;
    @Autowired
    private CreateOrderAdapter createOrderAdapter;
    @Autowired
    private OrderSdkAdapter orderSdkAdapter;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SendCouponService sendCouponService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private StockSdkService stockSdkService;
    @Value("${coupon.app.id}")
    private String appId;
    @Autowired
    private StoreItemClient storeItemClient;

    @Value("#{${ngs.virtual.store.idmap:null}}")
    private Map<String, String> storeIdMap;
    @Value("${ngs.partnerId.easy}")
    private String easyPartnerId;
    @Value("${ngs.partnerId.supermarket}")
    private String supermarketPartnerId;


    @Value("#{'${buyProductOnce.partnerId}'.split(',')}")
    private List<String> buyProductOncePartnerIds;


    @Value("#{'${virtual.product.svc.pay.partnerId:}'.split(',')}")
    private List<String> virtualProductSvcPayPartnerId;

    private final String SUCCESS = "100";

    private final String ngsCouponProductId = "76161384";
    @Autowired
    private OrderBusinessService orderBusinessService;

    @Autowired
    private BuyProductOnceManager buyProductOnceManager;

    @Autowired
    private PromotionDiscountClient promotionDiscountClient;

    @Autowired
    private PayServiceImpl payService;

    @Value("${saas.reverseNotifyiDcUrl}")
    private String reverseNotifyiDcUrl;
    @Autowired
    private AssortmentOpenPlatformPartnerConfigManager openPlatformPartnerConfigManager;
    @Autowired
    private AssortmentOpenPlatformIappWxappStoreManager assortmentOpenPlatformIappWxappStoreManager;
    @Autowired
    private WeChatLiveMsgHandle weChatLiveMsgHandle;

    @Autowired
    private CouponOnlineClient couponOnlineClient;
    /**
     * 抖音卖券
     */
    @Override
    public BaseResponse createOrder(CreateOrderBONew createOrderBO) {
        CreateOrderVo createOrderVo = createOrderBO.getCreateOrderVo();

        if (StringUtils.isEmpty(createOrderVo.getSaleCouponPhone())) {
            // 买券手机号必填，否则无法发券
            return ResponseUtil.error(ResponseCodeConstant.RESPONSE_ERROR_STR, "请填写手机号");
        }
        // 查询用户信息
        AssortmentCustomerInfoVo userLoginInfoDto = checkOrder.checkOrderByMemberNew(createOrderVo.getSessionId());
        String trackingNo = LogThreadLocal.getTrackingNo();
        String partnerId = userLoginInfoDto.getPartnerId();
        String userId = userLoginInfoDto.getMemberId();
        String wxAppId = userLoginInfoDto.getWxAppId();
        if(CollectionUtils.isEmpty(createOrderVo.getProducts())){
            return ResponseUtil.error(ResponseCodeConstant.RESPONSE_ERROR_STR, "无商品信息");
        }
        String skuId = createOrderVo.getProducts().get(0).getSkuId();
        //10-抖音卖券门店
        AssortmentOpenPlatformIappWxappStore wxAppStore = payService.getIappWxappStoreInfo(wxAppId,AggregationTypeEnum.TYPE_10.getCode());
        if ((wxAppStore == null || wxAppStore.getClientCode() == null)) {
            return ResponseUtil.error(ResponseCodeConstant.RESPONSE_ERROR_STR, "支付门店未配置");
        }
        String storeId = wxAppStore.getStoreId();
        // 获取门店信息
        StoreMixResponseDto storeMixResponseDto = storeService.getStoreInfoNew(partnerId, storeId, false,false);
        if (storeMixResponseDto == null || storeMixResponseDto.getStoreInfo() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        StoreResponseDto storeResponse = storeMixResponseDto.getStoreInfo();

        GetProductInfoDto getProductInfoDto = new GetProductInfoDto();
        getProductInfoDto.setPartnerId(partnerId);
        getProductInfoDto.setShopId(storeId);
        getProductInfoDto.setProductInfoType(2);
        getProductInfoDto.setProductIds(Arrays.asList(skuId));
        getProductInfoDto.setChannel(BusinessTypeEnum.getByType(createOrderVo.getMenuType()).getCode());
        ProductInfosDto productInfosDto = storeItemClient.listProductInfos(getProductInfoDto);
        if (!ResponseCodeConstant.RESPONSE_SUCCESS.equals(productInfosDto.getErrcode()) || CollectionUtils.isEmpty(productInfosDto.getData().getProducts())) {
            AppLogUtil.infoLog("查询商品信息失败，getProductInfoDto，baseResponse",getProductInfoDto,productInfosDto);
            return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
        }

        //卖券订单biztype默认传入6
        BaseResponse createOrderRequestResponse = checkOrderCoupon(userLoginInfoDto, storeResponse, trackingNo, createOrderVo.getMenuType(), BizTypeEnum.SALE_COUPON.getBizType(), partnerId, storeId, skuId,createOrderVo.getCardCode(),createOrderVo.getScene());
        if (createOrderRequestResponse == null || !ResponseResult.SUCCESS.getCode().equals(createOrderRequestResponse.getCode()) || createOrderRequestResponse.getResult() == null) {
            return createOrderRequestResponse;
        }

        CreateOrderRequest createOrderRequest = (CreateOrderRequest) createOrderRequestResponse.getResult();

        OrderBaseResp<OrderInfoReqs> orderInfoReqsBaseResponse = orderSdkService.createOrder(createOrderRequest, trackingNo);
        CreateOrderResponse createOrderResponse = orderSdkAdapter.convent2NEWOrderInfoReqs(orderInfoReqsBaseResponse);
        if (createOrderResponse == null || createOrderResponse.getErrcode() != 100) {
            return ResponseUtil.error(ResponseResult.ORDER_CREATE_ERROR);
        }else{
            OrderBeanV1 orderBean = createOrderResponse.getData();
            if(productInfosDto.getData().getProducts().get(0).getStockLimit() == 1){
                CreateOrderProductRequest productRequest = new CreateOrderProductRequest();
                productRequest.setSpecification(skuId);
                productRequest.setHasStockProudct(true);
                productRequest.setNumber(1);
                UpdateStocksRequest updateStocksRequest = orderSdkAdapter.getUpdateProductStock(
                        orderBean, Arrays.asList(productRequest), StockChangeType.REDUCE,createOrderVo.getMenuType());
                com.freemud.application.sdk.api.base.BaseResponse baseResponse = stockSdkService.reducesStocks(updateStocksRequest, "");
                ThirdPartyLog.infoConvertJson(System.currentTimeMillis(), System.currentTimeMillis(),
                        "updateStock", JSONObject.toJSONString(updateStocksRequest), JSONObject.toJSONString(baseResponse));
                if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, baseResponse.getCode())) {
                    //TODO 失败取消订单
                    CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                            AfterSalesType.SYSTEM_CANCEL, "商品库存不足", "", null);
                    BaseOrderResponse orderResponse = orderCenterSdkService.orderCancel(cancelOrderRequest);
                    return ResponseUtil.error(baseResponse.getCode(),"商品库存不足");
                }
            }
        }

        //创建支付
        CreatePrepayRequestDto createPrepayRequestDto = new CreatePrepayRequestDto();
        createPrepayRequestDto.setPartnerId(partnerId);
        createPrepayRequestDto.setTransId(orderInfoReqsBaseResponse.getResult().getOrderCode());
        createPrepayRequestDto.setWxAppId(userLoginInfoDto.getWxAppId());
        createPrepayRequestDto.setOpenId(userLoginInfoDto.getOpenId());
        createPrepayRequestDto.setCardCode(createOrderVo.getCardCode());
        createPrepayRequestDto.setPayCode(null);
        createPrepayRequestDto.setFatherOrderBean(createOrderResponse.getData());
        createPrepayRequestDto.setProductOrderBean(createOrderResponse.getData());
        createPrepayRequestDto.setTotalAmount(createOrderRequest.getSettlementAmount());
        createPrepayRequestDto.setCardAmount(0);
        createPrepayRequestDto.setChannel(PayChannelType.TIKTOKPAY.getEbcode());

        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        orderExtInfoDto.setOpenid(userLoginInfoDto.getOpenId());
        orderExtInfoDto.setAppid(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSessionId(createOrderVo.getSessionId());
        orderExtInfoDto.setVersion(createOrderVo.getVersion());
        // 扩展字段中存储 sessionKey
        orderExtInfoDto.setSessionKey(userLoginInfoDto.getSessionKey());
        orderExtInfoDto.setFormId(createOrderVo.getFormId());
        orderExtInfoDto.setFromAppId(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSaleCouponPhone(createOrderVo.getSaleCouponPhone());

        createPrepayRequestDto.setOrderExtInfoDTO(orderExtInfoDto);
        return ResponseUtil.success(payService.createPrepayOrder(createPrepayRequestDto));
    }

    /**
     * 获取用户所在的商户是否支持储值卡买券
     *
     * @param requestVo
     * @return
     */
    public BaseResponse svcConfig(SellCouponSvcConfigVo requestVo) {
        // 查询用户信息
        AssortmentCustomerInfoVo userLoginInfoDto = checkOrder.checkOrderByMemberNew(requestVo.getSessionId());
        if (CollectionUtils.isNotEmpty(virtualProductSvcPayPartnerId) && !virtualProductSvcPayPartnerId.contains(userLoginInfoDto.getPartnerId())) {
            return ResponseUtil.success(new SvcConfigResponse(false));
        }
        return ResponseUtil.success(new SvcConfigResponse(true));
    }

    /**
     * 卖券订单创建
     */
    public BaseResponse createOrder(SellCouponCreateOrderVo requestVo){
        // 查询用户信息
        AssortmentCustomerInfoVo userLoginInfoDto = checkOrder.checkOrderByMemberNew(requestVo.getSessionId());
        // 如果用户适用SVC 卡支付，则校验svc卡,
        Integer enableSharing = checkOrder.checkMemberSvcCard(userLoginInfoDto.getPartnerId(), userLoginInfoDto.getMemberId(), requestVo);
        String trackingNo = LogThreadLocal.getTrackingNo();
        String partnerId = userLoginInfoDto.getPartnerId();
        String storeId = requestVo.getShopId();
        String userId = userLoginInfoDto.getMemberId();
        String openId = userLoginInfoDto.getOpenId();
        String appId = userLoginInfoDto.getAppId();

        if (StringUtils.isNotBlank(requestVo.getCardCode()) && CollectionUtils.isNotEmpty(virtualProductSvcPayPartnerId) && !virtualProductSvcPayPartnerId.contains(partnerId)) {
            return ResponseUtil.error(ResponseResult.PAY_SVC_CONFIG_ERROR);
        }
        AssortmentOpenPlatformIappWxappStore wxAppStore = null;
        //微信视频号门店查询后台配置
        if(StringUtils.isEmpty(requestVo.getShopId()) && StringUtils.isNotBlank(requestVo.getScene()) && CreateOrderSceneEnum.verifySceneOrder.contains(requestVo.getScene())){
            wxAppStore = payService.getIappWxappStoreInfo(userLoginInfoDto.getWxAppId(),AggregationTypeEnum.TYPE_13.getCode());
            if (wxAppStore == null) {
                return ResponseUtil.error(ResponseCodeConstant.RESPONSE_ERROR_STR, "支付门店未配置");
            }
            storeId = wxAppStore.getStoreId();
        }

        // 获取门店信息
        StoreMixResponseDto storeMixResponseDto = storeService.getStoreInfoNew(partnerId, storeId, false,false);
        if (storeMixResponseDto == null || storeMixResponseDto.getStoreInfo() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        StoreResponseDto storeResponseDto = storeMixResponseDto.getStoreInfo();

        // 查询门店信息 营业时间、营业状态，服务器当前时间在营业时间内 点餐桌号
        checkOrder.checkOrderByStore(storeResponseDto);


        GetProductInfoDto getProductInfoDto = new GetProductInfoDto();
        getProductInfoDto.setPartnerId(partnerId);
        getProductInfoDto.setShopId(storeId);
        getProductInfoDto.setProductInfoType(2);
        getProductInfoDto.setProductIds(Arrays.asList(requestVo.getSkuId()));
        getProductInfoDto.setChannel(BusinessTypeEnum.getByType(requestVo.getMenuType()).getCode());
        ProductInfosDto productInfosDto = storeItemClient.listProductInfos(getProductInfoDto);
        if (!ResponseCodeConstant.RESPONSE_SUCCESS.equals(productInfosDto.getErrcode()) || CollectionUtils.isEmpty(productInfosDto.getData().getProducts())) {
            AppLogUtil.infoLog("查询商品信息失败，getProductInfoDto，baseResponse",getProductInfoDto,productInfosDto);
            return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
        }

        //通过商户号配置进阿波罗，识别哪些商户走仅限一次卖券业务 wanghanghang 0610
        //【P0】【业务 / 米食】【B端 / 万象 / 活动下架】商户618活动：一元买虚拟商品特殊处理活动下架，删除特殊增加字段 wanghanghang
        //处理方式，阿波罗配置商户改成空。没必要删除代码。保留后续此类活动还可继续使用
        if (buyProductOncePartnerIds != null && buyProductOncePartnerIds.contains(partnerId)) {
            try {
                ResponseResult checkRequest =  buyProductOnceManager.checkBuyProductOnce(productInfosDto.getData().getProducts(),partnerId,userId);
                if(!checkRequest.equals(ResponseResult.SUCCESS)){
                    return ResponseUtil.error(checkRequest);
                }
            }catch (Exception e){
                AppLogUtil.infoLog("校验用户每人每单限购一次异常",getProductInfoDto,productInfosDto);
            }
        }

        //卖券订单biztype默认传入6
        BaseResponse createOrderRequestResponse = checkOrderCoupon(userLoginInfoDto, storeResponseDto, trackingNo, requestVo.getMenuType(), 6, partnerId, storeId, requestVo.getSkuId(),requestVo.getCardCode(),requestVo.getScene());
        if (createOrderRequestResponse == null || !ResponseResult.SUCCESS.getCode().equals(createOrderRequestResponse.getCode()) || createOrderRequestResponse.getResult() == null) {
            return createOrderRequestResponse;
        }

        CreateOrderRequest createOrderRequest = (CreateOrderRequest) createOrderRequestResponse.getResult();
        createOrderRequest.setEnableSharing(enableSharing);
        //标准化平台虚拟商品特价活动计算，不包含蜜雪APP买虚拟商品
        List<SubtractStockVO> stockBeanDtos = calculationDiscount(partnerId, storeId, userLoginInfoDto.getMemberId(), productInfosDto.getData().getProducts().get(0), createOrderRequest);

        OrderBaseResp<OrderInfoReqs> orderInfoReqsBaseResponse = orderSdkService.createOrder(createOrderRequest, trackingNo);
        CreateOrderResponse createOrderResponse = orderSdkAdapter.convent2NEWOrderInfoReqs(orderInfoReqsBaseResponse);
        if (createOrderResponse == null || createOrderResponse.getErrcode() != 100) {
            return ResponseUtil.error(ResponseResult.ORDER_CREATE_ERROR);
        }else{
            OrderBeanV1 orderBean = createOrderResponse.getData();
            if(productInfosDto.getData().getProducts().get(0).getStockLimit() == 1){
                CreateOrderProductRequest productRequest = new CreateOrderProductRequest();
                productRequest.setSpecification(requestVo.getSkuId());
                productRequest.setHasStockProudct(true);
                productRequest.setNumber(1);
                UpdateStocksRequest updateStocksRequest = orderSdkAdapter.getUpdateProductStock(
                        orderBean, Arrays.asList(productRequest), StockChangeType.REDUCE,requestVo.getMenuType());
                com.freemud.application.sdk.api.base.BaseResponse baseResponse = stockSdkService.reducesStocks(updateStocksRequest, "");
                ThirdPartyLog.infoConvertJson(System.currentTimeMillis(), System.currentTimeMillis(),
                        "updateStock", JSONObject.toJSONString(updateStocksRequest), JSONObject.toJSONString(baseResponse));
                if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, baseResponse.getCode())) {
                    //TODO 失败取消订单
                    CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                            AfterSalesType.SYSTEM_CANCEL, "商品库存不足", "", null);
                    BaseOrderResponse orderResponse = orderCenterSdkService.orderCancel(cancelOrderRequest);
                    //异常清理掉key
                    //        //【P0】【业务 / 米食】【B端 / 万象 / 活动下架】商户618活动：一元买虚拟商品特殊处理活动下架，删除特殊增加字段 7.13 wanghanghang
//                    buyProductOnceManager.removeCheckBuyProductOnceKey(partnerId,userId,orderBean.getProductList().get(0).getProductId());
                    return ResponseUtil.error(baseResponse.getCode(),"商品库存不足");
                }
            }
            if(CollectionUtils.isNotEmpty(stockBeanDtos)){
                // 扣减活动库存
                ActivityUpdateStockRequest activityUpdateStockRequest = orderSdkAdapter.convert2ActivityUpdateStockRequest(orderBean, stockBeanDtos);
                // 原逻辑只检测扣减库存不为空时调用，现改为扣减库存不为空或参加活动不为空时调用
                if (activityUpdateStockRequest != null && (CollectionUtils.isNotEmpty(activityUpdateStockRequest.getStock()) || CollectionUtils.isNotEmpty(activityUpdateStockRequest.getActivityList()))) {
                    PromotionResponseDTO activityResponse = promotionDiscountClient.subtractStock(activityUpdateStockRequest);
                    if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, activityResponse.getStatusCode())) {
                        // 失败取消订单
                        CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                                AfterSalesType.SYSTEM_CANCEL, "活动库存不足", "", null);
                        BaseOrderResponse orderResponse = orderCenterSdkService.orderCancel(cancelOrderRequest);
                        return ResponseUtil.error(ResponseResult.ORDER_CREATE_ERROR.getCode(),"活动库存不足");
                    }
                }
            }

        }

        //创建支付
        CreatePrepayRequestDto createPrepayRequestDto = new CreatePrepayRequestDto();
        createPrepayRequestDto.setPartnerId(partnerId);
        createPrepayRequestDto.setTransId(orderInfoReqsBaseResponse.getResult().getOrderCode());
        createPrepayRequestDto.setWxAppId(userLoginInfoDto.getWxAppId());
        createPrepayRequestDto.setOpenId(userLoginInfoDto.getOpenId());
//        createPrepayRequestDto.setFaceCode(null);
        createPrepayRequestDto.setCardCode(requestVo.getCardCode());
        createPrepayRequestDto.setPayCode(null);
        createPrepayRequestDto.setFatherOrderBean(createOrderResponse.getData());
        createPrepayRequestDto.setProductOrderBean(createOrderResponse.getData());
        createPrepayRequestDto.setTotalAmount(createOrderRequest.getSettlementAmount());
        createPrepayRequestDto.setCardAmount(0);
        createPrepayRequestDto.setChannel(requestVo.getChannel());
//        createPrepayRequestDto.setStoreId(storeId);
        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        String deliveryHoursDayStart = "";
        String deliveryHoursDayEnd = "";
        if (StringUtils.isNotBlank(storeResponseDto.getDeliveryHoursDay())) {
            String[] days = storeResponseDto.getDeliveryHoursDay().split("-");
            if (days.length == 2) {
                deliveryHoursDayStart = DateUtil.convert2String(new Date(), DateUtil.FORMAT_yyyyMMdd_date) + " " + days[0] + ":00";
//                deliveryHoursDayEnd = DateUtil.convert2String(new Date(), DateUtil.FORMAT_yyyyMMdd_date) + " " + days[1] + ":00";
            }
        }
        orderExtInfoDto.setDeliveryHoursDayStart(deliveryHoursDayStart);
        orderExtInfoDto.setDeliveryHoursDayEnd(deliveryHoursDayEnd);
        orderExtInfoDto.setOpenid(userLoginInfoDto.getOpenId());
        orderExtInfoDto.setAppid(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSessionId(requestVo.getSessionId());
        Integer serviceTime = storeResponseDto.getServiceTime();
        if (Objects.equals(serviceTime, null)) {
            serviceTime = 50;
        }
        orderExtInfoDto.setServiceTime(serviceTime);
        orderExtInfoDto.setVersion(requestVo.getVersion());
        // 扩展字段中存储 sessionKey
        orderExtInfoDto.setSessionKey(userLoginInfoDto.getSessionKey());
        orderExtInfoDto.setFormId(requestVo.getFormId());
        orderExtInfoDto.setFromAppId(userLoginInfoDto.getWxAppId());
//        orderExtInfoDto.setUnDistribution(requestVo.getUnDistribution());
        createPrepayRequestDto.setOrderExtInfoDTO(orderExtInfoDto);
        if (StringUtils.isNotBlank(requestVo.getCardCode()) || createPrepayRequestDto.getTotalAmount() == 0) {
            return ResponseUtil.success(payService.createPrepayOrder(createPrepayRequestDto));
        }

        //查询虚拟商品卖券支付配置中的分账门店信息
        //如果需要分账查询支付配置中的分账门店信息，否则查询sdk
//        AssortmentOpenPlatformIappWxappStore wxAppStore = new AssortmentOpenPlatformIappWxappStore();
        if(createOrderRequest.getIsSplitAccount() != null && createOrderRequest.getIsSplitAccount() == 1){
            //11-虚拟卖券门店
            wxAppStore = payService.getIappWxappStoreInfo(userLoginInfoDto.getWxAppId(),AggregationTypeEnum.TYPE_11.getCode());
        }else if(wxAppStore == null){
            wxAppStore = assortmentOpenPlatformIappWxappStoreManager.selectWxappStoreByWxAppIdAndStoreId(userLoginInfoDto.getWxAppId(),storeId);
        }
        if ((wxAppStore == null || wxAppStore.getClientCode() == null)) {
            return ResponseUtil.error(ResponseCodeConstant.RESPONSE_ERROR_STR, "支付门店未配置");
        }
        createOrderRequest.setStoreId(storeId);
        //创建卖券预支付
        OrderInfoReqs result = orderInfoReqsBaseResponse.getResult();
        String orderCode = result.getOrderCode();
        CreateOrderResponseVo createOrderResponseVo = new CreateOrderResponseVo();
        createOrderResponseVo.setOid(orderCode);
        //线上现金支付，创建预支付订单，唤起支付
        com.freemud.application.sdk.api.base.BaseResponse<UnifiedPayResponseDto> response = null;
        Long payClientCode = Long.parseLong(wxAppStore.getClientCode());
        //实际支付金额
        Long cashPrice = createOrderRequest.getSettlementAmount();
        UnifiedOrderRequestDto requestDto = checkOrder.convert2UnifiedOrderRequestDto(result, openId, cashPrice, payClientCode, reverseNotifyiDcUrl, getPartnerPayOvertime(partnerId));
        requestDto.setStoreId(wxAppStore.getStoreId());
        response = payService.unifiedOrder(requestDto);
        if (!Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS_STR, response.getCode())) {
            return ResponseUtil.error(orderInfoReqsBaseResponse.getCode(), "支付异常");
        }
        if (!Objects.equals(ResponseCodeConstant.RESPONSE_SUCCESS, response.getData().getResultCode())) {
            return ResponseUtil.error(orderInfoReqsBaseResponse.getCode(), "支付异常," + response.getData().getResultMsg());
        }

        updateExtInfo(response.getData(), appId,createPrepayRequestDto);

        //唤起支付返回参数
        checkOrder.convent2CreateOrderResponseVo(createOrderResponseVo, appId, response.getData());

        // fisherman 视频卖券 需要拼装额外对象 给前端
        if (StringUtils.isNotBlank(requestVo.getScene()) && CreateOrderSceneEnum.verifySceneOrder.contains(requestVo.getScene())) {
            BaseResponse<WeChatReportVO> baseResponse = weChatLiveMsgHandle.reportOrder(createPrepayRequestDto, createOrderResponseVo, requestVo.getScene());
            if (ResponseResult.SUCCESS.getCode().equals(baseResponse.getCode())) {
                WeChatReportVO weChatReportVO = baseResponse.getResult();
                OrderCreateRequestVO requestVO = weChatReportVO.getRequestVO();
                createOrderResponseVo.setWxOrderInfo(requestVO);
            }else {
                return baseResponse;
            }
        }
        return ResponseUtil.success(createOrderResponseVo);
    }

    public void convent2OrderPayResponse(OrderPayResponse orderPayResponse, String appId, UnifiedPayResponseDto response
            ,CreatePrepayRequestDto createPrepayRequestDto){
        orderPayResponse.setWxAppid(appId);
        orderPayResponse.setFmId(response.getFmId());
        orderPayResponse.setOpenId(createPrepayRequestDto.getOpenId());
//        createOrderResponseVo.setEndTransId(response.getEndTransId());
//        createOrderResponseVo.setPaySuccess(false);
        String payOrderDto = response.getPayOrder();
        PayOrderDto payOrderBean = JSONObject.parseObject(payOrderDto, PayOrderDto.class);
        if (null != payOrderBean) {
            OrderPayResponse.PayOrderBean payBean = new OrderPayResponse.PayOrderBean();
            payBean.setAppid(payOrderBean.getAppid());
            payBean.setNonceStr(payOrderBean.getNonceStr());
            payBean.setPackageX(payOrderBean.getPackageX());
            payBean.setSign(payOrderBean.getPaySign());
            payBean.setSignType(payOrderBean.getSignType());
            payBean.setTimestamp(payOrderBean.getTimestamp());
            payBean.setAliPayOrder(payOrderBean.getAliPayOrder());
            orderPayResponse.setPayOrder(payBean);
            orderPayResponse.setThirdOrderId(payOrderBean.getThirdPartTradeNo());
            orderPayResponse.setThirdOrderToken(payOrderBean.getBizContent());
        }
        orderPayResponse.setPayChannelType(PayChannelType.WECHAT);
        if (orderPayResponse.getPayOrder() != null && StringUtils.isNotBlank(orderPayResponse.getPayOrder().getAliPayOrder())) {
            orderPayResponse.setPayChannelType(PayChannelType.ALIPAY);
        }
        //抖音支付
        if (PayChannelType.TIKTOKPAY.getIndex().toString().equalsIgnoreCase(createPrepayRequestDto.getProductOrderBean().getPayChannelType())) {
            orderPayResponse.setPayChannelType(PayChannelType.TIKTOKPAY);
        }
    }


    public void updateExtInfo(UnifiedPayResponseDto response , String appId,CreatePrepayRequestDto createPrepayRequestDto){
        OrderPayResponse orderPayResponse  = new OrderPayResponse();
        convent2OrderPayResponse(orderPayResponse, appId,response,createPrepayRequestDto);
        BaseResponse baseEditResponse = payService.updateOrderInfo(orderPayResponse, createPrepayRequestDto.getOrderExtInfoDTO(), createPrepayRequestDto.getProductOrderBean(), LogThreadLocal.getTrackingNo());
    }

    /**
     * 效验虚拟商品活动信息
     * @param userLoginInfoDto
     * @param storeResponse
     * @param trackingNo
     * @param menuType
     * @param bizType
     * @param partnerId
     * @param storeId
     * @param skuId
     * @param cardCode
     * @param scene  下单的场景
     * @return
     */
    public BaseResponse checkOrderCoupon(AssortmentCustomerInfoVo userLoginInfoDto,
                                         StoreResponseDto storeResponse,
                                         String trackingNo,
                                         String menuType,
                                         Integer bizType,
                                         String partnerId,
                                         String storeId,
                                         String skuId,String cardCode,
                                         String scene) {

        //校验虚拟商品是否在门店菜单
        GetValidateProductInfoDto getProductInfoDto = new GetValidateProductInfoDto();
        getProductInfoDto.setPartnerId(partnerId);
        getProductInfoDto.setStoreId(storeId);
        getProductInfoDto.setChannel(menuType);
        List<String> productIds = new ArrayList<>();
        productIds.add(skuId);
        getProductInfoDto.setProductIds(productIds);
        ValidateProductInfosDto productInfosDto = storeItemClient.validateShopContainProduct(getProductInfoDto);
        if (!Objects.equals(productInfosDto.getErrcode(), Integer.valueOf(ResponseResult.SUCCESS.getCode()))
                || productInfosDto.getData() ==null
                || CollectionUtils.isEmpty(productInfosDto.getData().getSuccessList())){
            return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_VAILD_ERROR);
        }

        /*GetProductInfoRequest request = new GetProductInfoRequest();
        request.setChannel(menuType);
        request.setPartnerId(partnerId);
        request.setProductInfoType(ProductInfoType.ALL.getCode());
        request.setShopId(storeId);
        request.setProductIds(productIds);
        //获取商品（里面的活动）
        com.freemud.application.sdk.api.base.BaseResponse<GetProductInfosResponse> productInfosByIds = menuService.getProductInfosByIds(request, trackingNo);
        if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(productInfosByIds.getCode()) || productInfosByIds.getData() == null || CollectionUtils.isEmpty(productInfosByIds.getData().getProducts())) {
            return ResponseUtil.error(ResponseResultEnum.GET_PRODUCT_INFOS_ERROR.getCode(), ResponseResultEnum.GET_PRODUCT_INFOS_ERROR.getMessage());
        }*/
        //查询商品信息sdk改feign
        GetProductInfoDto request = new GetProductInfoDto();
        request.setPartnerId(partnerId);
        request.setShopId(storeId);
        request.setProductInfoType(ProductInfoType.ALL.getCode());
        request.setProductIds(productIds);
        request.setChannel(menuType);
        ProductInfosDto productInfos = storeItemClient.listProductInfos(request);
        //获取虚拟商品中的券信息

        //效验商品券是否有效
        List<ProductBindingCouponType> productBindingCoupons = productInfos.getData().getProducts().get(0).getProductBindingCouponTypes();
        if (CollectionUtils.isEmpty(productBindingCoupons)) {
            return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
        }
        Set<String> activityCodes = new HashSet<>();
        for (ProductBindingCouponType productBindingCouponType : productBindingCoupons) {
            activityCodes.add(productBindingCouponType.getActivityCode());
        }
        //批量查询活动详情
        List<FastTemplateInfoResponseVO> activeDetailVOS = batchQueryActivityInfo(partnerId, activityCodes, trackingNo);
        if (CollectionUtils.isEmpty(activeDetailVOS) || activityCodes.size() != activeDetailVOS.size()) {
            return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
        }
        //优惠券是否失效
        Date now = new Date();
        for (FastTemplateInfoResponseVO activeDetailVO : activeDetailVOS) {
            if (activeDetailVO.getEffectiveEndTime() != null && activeDetailVO.getEffectiveEndTime().before(now)) {
                return ResponseUtil.error(ResponseResult.COUPON_INVAILD.getCode(),"您需要购买的券包，包含的优惠券券编号"+activeDetailVO.getTemplateCode()+"已过期，请联系门店尽快处理");
            }
            // endDate   领券结束时间 校验  当前时间小鱼endDate

            if (activeDetailVO.getReceiveStartTime() != null && now.before(activeDetailVO.getReceiveStartTime())) {
                return ResponseUtil.error(ResponseResult.COUPON_INVAILD.getCode(),"您需要购买的券包，包含的优惠券券编号"+activeDetailVO.getTemplateCode()+"未到领券时间，请联系门店尽快处理");
            }
            if (activeDetailVO.getReceiveEndTime() != null && now.after(activeDetailVO.getReceiveEndTime())) {
                return ResponseUtil.error(ResponseResult.COUPON_INVAILD.getCode(),"您需要购买的券包，包含的优惠券券编号"+activeDetailVO.getTemplateCode()+"领券时间已结束，请联系门店尽快处理");
            }
            // state = 1  ||  2  可以买
            if (activeDetailVO.getStatus() !=null) {
                Integer state = activeDetailVO.getStatus();
                if (!Objects.equals(state,1) && !Objects.equals(state,2)) {
                    return ResponseUtil.error(ResponseResult.COUPON_INVAILD.getCode(),"您需要购买的券包，包含的优惠券券编号"+activeDetailVO.getTemplateCode()+"已失效，请联系门店尽快处理");
                }
            }
        }
        //转换CreateOrderRequest对象
        CreateOrderRequest createOrderRequest = convent2NEWCreateOrderRequest(userLoginInfoDto,
                productInfos.getData(),
                activeDetailVOS,
                storeResponse,storeId,cardCode,skuId,menuType,bizType,scene);
        return ResponseUtil.success(createOrderRequest);
    }




    public BaseResponse ngsCouponOrderCreate(NgsSellCouponCreateOrderVo requestVo){
        // 查询用户信息、校验svc卡
        AssortmentCustomerInfoVo userLoginInfoDto = checkOrder.getMemberNew(requestVo.getSessionId());
        String trackingNo = LogThreadLocal.getTrackingNo();
        String partnerId = userLoginInfoDto.getPartnerId();
        // 构建创建订单入参
        CreateOrderRequest createOrderRequest = ngsConvent2NEWCreateOrderRequest(requestVo,userLoginInfoDto);
        OrderBaseResp<OrderInfoReqs> orderInfoReqsBaseResponse = orderSdkService.createOrder(createOrderRequest, trackingNo);
        CreateOrderResponse createOrderResponse = orderSdkAdapter.convent2NEWOrderInfoReqs(orderInfoReqsBaseResponse);
        if(createOrderResponse == null || createOrderResponse.getErrcode() != 100){
            return ResponseUtil.error(ResponseResult.ORDER_CREATE_ERROR);
        }
        //创建支付
        CreatePrepayRequestDto createPrepayRequestDto = new CreatePrepayRequestDto();
        createPrepayRequestDto.setPartnerId(partnerId);
        createPrepayRequestDto.setTransId(orderInfoReqsBaseResponse.getResult().getOrderCode());
        createPrepayRequestDto.setWxAppId(userLoginInfoDto.getWxAppId());
        createPrepayRequestDto.setOpenId(userLoginInfoDto.getOpenId());
        createPrepayRequestDto.setCardCode(requestVo.getCardCode());
        createPrepayRequestDto.setPayCode(null);
        createPrepayRequestDto.setFatherOrderBean(createOrderResponse.getData());
        createPrepayRequestDto.setProductOrderBean(createOrderResponse.getData());
        createPrepayRequestDto.setTotalAmount(createOrderRequest.getSettlementAmount());
        createPrepayRequestDto.setCardAmount(0);
        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        String deliveryHoursDayStart = "";
        String deliveryHoursDayEnd = "";
        orderExtInfoDto.setDeliveryHoursDayStart(deliveryHoursDayStart);
        orderExtInfoDto.setDeliveryHoursDayEnd(deliveryHoursDayEnd);
        orderExtInfoDto.setOpenid(userLoginInfoDto.getOpenId());
        orderExtInfoDto.setAppid(userLoginInfoDto.getWxAppId());
        orderExtInfoDto.setSessionId(requestVo.getSessionId());
        Integer serviceTime = 0;
        if (Objects.equals(serviceTime, null)) {
            serviceTime = 50;
        }
        orderExtInfoDto.setServiceTime(serviceTime);
        orderExtInfoDto.setVersion(requestVo.getVersion());
        // 扩展字段中存储 sessionKey
        orderExtInfoDto.setSessionKey(userLoginInfoDto.getSessionKey());
        orderExtInfoDto.setFromAppId(userLoginInfoDto.getWxAppId());

        String date = DateUtil.convert2String(new Date(), "yyyyMMdd");
        String key = this.getFolwNo(requestVo.getAppId(), date);

        int flowno = 0;
        RedisTemplate redisTemplate = redisCache.getRedisTemplate();

        if (redisTemplate.opsForValue().setIfAbsent(key, 0)) {
            redisTemplate.expire(key, 24, TimeUnit.HOURS);
        } else {
            flowno = redisTemplate.opsForValue().increment(key, 1).intValue();
        }
        String stationid = getStationId(date, requestVo.getAppId(), flowno);

        orderExtInfoDto.setStationId(stationid);

        createPrepayRequestDto.setOrderExtInfoDTO(orderExtInfoDto);
        return ResponseUtil.success(payService.createPrepayOrder(createPrepayRequestDto));

    }

    private String getStationId(String date, String appid, int flowno) {
        String stationid = "";
        int length = String.valueOf(flowno).length();
        if (easyPartnerId.equals(appid)){
            stationid = date + "6600000001";
            for (int i = 0; i < 5 - length; i++){
                stationid += "0";
            }
            stationid += flowno;
        } else if (supermarketPartnerId.equals(appid)) {
            stationid = date + "9988800001";
            for (int i = 0; i < 5 - length; i++){
                stationid += "0";
            }
            stationid += flowno;
        }
        return stationid;
    }

    private String getFolwNo(String partnerId, String date){
        return CommonRedisKeyConstant.NGS_FLOWNO_PARTNER_DATE_NO + ":" + partnerId + ":" + date;
    }

    /**
     * 批量查询活动详情
     *
     * @param partnerId
     * @param activityCodes
     * @param trackingNo
     * @return
     */
    private List<FastTemplateInfoResponseVO> batchQueryActivityInfo(String partnerId, Set<String> activityCodes, String trackingNo) {

        FastBatchQueryTemplateInfoRequest request = new FastBatchQueryTemplateInfoRequest();
        request.setPartnerId(partnerId);
        request.setTemplateCode(activityCodes);
        request.setTrackingNo(trackingNo);

        CouponResponseDTO<List<FastTemplateInfoResponseVO>> responseDTO = couponOnlineClient.fastBatchQueryTemplateInfo(request);
        if (responseDTO == null
                || !Objects.equals(responseDTO.getStatusCode(),100)
                || CollectionUtils.isEmpty(responseDTO.getResult())) {
            return null;
        }

        List<FastTemplateInfoResponseVO> result = responseDTO.getResult();
        return result;
    }




    /**
     * 转换对象，从购买优惠券业务提出重写
     * @param userLoginInfoDto
     * @param dataBean
     * @param activeDetailVOS
     * @param storeInfo
     * @param shopId
     * @param cardCode
     * @param skuId
     * @param channel
     * @param bizType
     * @return
     */
    private CreateOrderRequest convent2NEWCreateOrderRequest(AssortmentCustomerInfoVo userLoginInfoDto,
                                                             ProductInfosDto.DataBean dataBean,List<FastTemplateInfoResponseVO> activeDetailVOS,
                                                             StoreResponseDto storeInfo,
                                                             String shopId,
                                                             String cardCode,
                                                             String skuId,
                                                             String channel,
                                                             Integer bizType,
                                                             String scene){
        CreateOrderRequest request = new CreateOrderRequest();
        Integer orderClient = OrderClientType.SAAS.getIndex();
        request.setPayChannel(PayChannelType.WECHAT.getIndex().toString());
        request.setPayChannelName(PayChannelType.WECHAT.getName());
        request.setPayChannelType(PayChannelType.WECHAT.getIndex());
        if(UserLoginChannelEnum.ALIPAY.getCode().equals(userLoginInfoDto.getChannel())){
            orderClient = OrderClientType.ALIPAY.getIndex();
            request.setPayChannel(PayChannelType.ALIPAY.getEbcode());
            request.setPayChannelName(PayChannelType.ALIPAY.getName());
            request.setPayChannelType(PayChannelType.ALIPAY.getIndex());
        }
        if(UserLoginChannelEnum.APP.getCode().equals(userLoginInfoDto.getChannel())){
            orderClient = OrderClientType.APP.getIndex();
        }

        // fisherman  视频直播卖券 需要修改 orderclient
        if (StringUtils.isNotBlank(scene) && CreateOrderSceneEnum.verifySceneOrder.contains(scene)) {
            request.setMarketingType(MarketTypeEnum.WE_CHAT_LIVE_SELL.getIndex());
        }
        //抖音小程序
        if("5".equalsIgnoreCase(userLoginInfoDto.getChannel())) {
            request.setPayChannel(PayChannelType.TIKTOKPAY.toString());
            request.setPayChannelName(PayChannelType.TIKTOKPAY.getName());
            request.setPayChannelType(PayChannelType.TIKTOKPAY.getIndex());
            orderClient = OrderClientType.TIKTOKPAY.getIndex();
        }
        String partnerId = userLoginInfoDto.getPartnerId();
        request.setOrderClient(orderClient);
        request.setPartnerId(partnerId);
        request.setStoreId(shopId);
        //买券虚拟订单  不管APP卖券还是平台，依旧保留传入6
        request.setBizType(bizType);
        //1:线上支付 2:线下支付
        request.setPayType(1);
        request.setUserId(userLoginInfoDto.getMemberId());
        request.setUserName(userLoginInfoDto.getNickName());
        request.setStoreName(storeInfo.getStoreName());
        request.setThirdStoreId(storeInfo.getThirdPartCode());
        request.setOrderState(1);
        request.setPayState(1);
        if(StringUtils.isNotBlank(cardCode)){
            request.setPayChannel("10102");
            request.setPayChannelName("储值卡支付");
        }
        ProductInfo productBean = dataBean.getProducts().get(0);
        //订单原始金额，单位分
        //用户在界面上看到的支付金额
        request.setSettlementAmount(productBean.getFinalPrice());
        //实际支付现金金额，扣除支付自生优惠，单位分`
        request.setActualPayAmount(productBean.getFinalPrice());
        request.setOriginalAmount(productBean.getOriginalPrice());
        request.setOrderType(GENERAL_DINE_IN.getIndex());
        //商品信息转换
        List<OrderItemCreateReq> orderItemList = new ArrayList<>();
        OrderItemCreateReq orderItemCreateReq = new OrderItemCreateReq();
        orderItemCreateReq.setSalePrice(productBean.getFinalPrice());
        orderItemCreateReq.setProductPrice(productBean.getOriginalPrice());
        orderItemCreateReq.setSettlementPrice(productBean.getFinalPrice());
        orderItemCreateReq.setPartnerId(partnerId);
        orderItemCreateReq.setProductId(skuId);
        orderItemCreateReq.setProductSpec(skuId);
        orderItemCreateReq.setProductName(productBean.getName());
        orderItemCreateReq.setProductSpecName(productBean.getName());
        orderItemCreateReq.setProductPicUrl(productBean.getPicture());
        orderItemCreateReq.setProductSeq(1);
        // fisherman 卖券商品 设置 productType = 9
        orderItemCreateReq.setProductType(ProductType.VIRTUAL_PRODUCT.getCode());
        orderItemCreateReq.setProductCode(productBean.getProductCode());
        orderItemCreateReq.setThirdProductId(productBean.getCustomerCode());
        orderItemCreateReq.setProductQuantity(1);
        orderItemCreateReq.setOriginalProductType(productBean.getType());

        OrderProductAddInfoDto orderProductAddInfoDto = new OrderProductAddInfoDto();
        List<ProductBindingCouponType> productBindingCoupons = new ArrayList<>();
        for (ProductBindingCouponType productBindingCouponType : productBean.getProductBindingCouponTypes()){
            for (FastTemplateInfoResponseVO activeDetailVO : activeDetailVOS){
                if(productBindingCouponType.getActivityCode().equals(activeDetailVO.getTemplateCode())){
                    ProductBindingCouponType productBindingCouponType2 = new ProductBindingCouponType();
                    productBindingCouponType2.setActivityCode(productBindingCouponType.getActivityCode());
                    productBindingCouponType2.setNum(productBindingCouponType.getNum());
                    productBindingCouponType2.setActivityName(activeDetailVO.getTemplateName());
                    //新增是否分账，核销次数和券单价
                    productBindingCouponType2.setIsSplitAccount(productBindingCouponType.getIsSplitAccount());
                    //分账的券包对应所有券都是一致，要么分账，要么不分账，循环赋值都是相同的
                    request.setIsSplitAccount(productBindingCouponType.getIsSplitAccount());
                    productBindingCouponType2.setMaxRedeemTimes(productBindingCouponType.getMaxRedeemTimes());
                    productBindingCouponType2.setPrice(productBindingCouponType.getPrice());
                    productBindingCoupons.add(productBindingCouponType2);
                    break;
                }
            }
        }
        orderProductAddInfoDto.setSpuProductCode(productBean.getProductCode());
        orderProductAddInfoDto.setProductBindingCoupons(productBindingCoupons);
        orderProductAddInfoDto.setLinkedId(productBean.getLinkedId());
        orderItemCreateReq.setExtInfo(JSONObject.toJSONString(orderProductAddInfoDto));
        orderItemList.add(orderItemCreateReq);

        //商品信息赋值
        request.setOrderItemList(orderItemList);
        //收货人信息转换
        List<DeliveryContactInfoCreateReq> deliveryContactInfoList = new ArrayList<>();
        DeliveryContactInfoCreateReq deliveryContactInfoCreateReq = new DeliveryContactInfoCreateReq();
        //地址类型 1:订单地址 2:售后单地址 3:配送员信息
        deliveryContactInfoCreateReq.setRelateObjectType(1);
        //联系方式类型 1:取件 2:收件
        deliveryContactInfoCreateReq.setInfoType(1);
        deliveryContactInfoCreateReq.setContactsName(userLoginInfoDto.getNickName());
        deliveryContactInfoCreateReq.setMobile(userLoginInfoDto.getMobile());
        deliveryContactInfoCreateReq.setLatitude(null);
        deliveryContactInfoCreateReq.setLongitude(null);
        deliveryContactInfoCreateReq.setAddressDetail(null);
        deliveryContactInfoCreateReq.setProvince(null);
        deliveryContactInfoCreateReq.setCity(null);
        deliveryContactInfoCreateReq.setRegion(null);
        deliveryContactInfoList.add(deliveryContactInfoCreateReq);
        request.setDeliveryContactInfoList(deliveryContactInfoList);
        //保存门店渠道信息
        request.setOrderExtended(orderAdapter.saveStoreInfo(storeInfo));
        request.setOperator(userLoginInfoDto.getNickName());
        request.setAppId(userLoginInfoDto.getWxAppId());
        return request;

    }




    private CreateOrderRequest ngsConvent2NEWCreateOrderRequest(NgsSellCouponCreateOrderVo requestVo, AssortmentCustomerInfoVo userLoginInfoDto){



        CreateOrderRequest request = new CreateOrderRequest();
        Integer orderClient = OrderClientType.SAAS.getIndex();
        if(UserLoginChannelEnum.ALIPAY.getCode().equals(userLoginInfoDto.getChannel())){
            orderClient = OrderClientType.ALIPAY.getIndex();
        }
        if(UserLoginChannelEnum.APP.getCode().equals(userLoginInfoDto.getChannel())){
            orderClient = OrderClientType.APP.getIndex();
        }
        String partnerId = userLoginInfoDto.getPartnerId();
        String requestVoAppId = requestVo.getAppId();

        request.setOrderClient(orderClient);
        request.setPartnerId(partnerId);
        request.setStoreId(storeIdMap.get(requestVoAppId));
        //买券虚拟订单
        request.setBizType(6);
        //1:线上支付 2:线下支付
        request.setPayType(1);
        request.setUserId(userLoginInfoDto.getMemberId());
        request.setUserName(userLoginInfoDto.getNickName());
        request.setStoreName("虚拟门店");
        request.setThirdStoreId("");
        request.setOrderState(1);
        request.setPayState(1);
        if(StringUtils.isNotBlank(requestVo.getCardCode())){
            request.setPayChannel("10102");
            request.setPayChannelName("储值卡支付");
        }
        // TODO 商品信息 从券码查
        // TODO 通过活动号查询金额
        String activityCode = requestVo.getActivityCode();
        BatchQueryActivityInfoRequestDto queryActivityInfoRequestDto = new BatchQueryActivityInfoRequestDto();
        queryActivityInfoRequestDto.setActiveCode(Arrays.asList(activityCode));
        queryActivityInfoRequestDto.setPartnerId(Integer.valueOf(partnerId));
        BatchQueryActivityInfoResponseDto batchQueryActivityInfoResponseDto = couponService.batchQueryActivityInfo(queryActivityInfoRequestDto);
        Active active = batchQueryActivityInfoResponseDto.getActivities().get(0);

        // GetMenuCategoryInfoResponse.RootNodeBean.ChildrenBeanFirst.ChildrenBeanSecond.ProductBean productBean = productInfosResponse.getProducts().get(0);
        //订单原始金额，单位分
        //用户在界面上看到的支付金额


        request.setSettlementAmount(active.getSalePrice().longValue());
        //实际支付现金金额，扣除支付自生优惠，单位分`
        request.setActualPayAmount(active.getSalePrice().longValue());
        request.setOriginalAmount(active.getVoucherFaceValue().longValue());
        request.setOrderType(GENERAL_DINE_IN.getIndex());
        //商品信息转换
        List<OrderItemCreateReq> orderItemList = new ArrayList<>();
        OrderItemCreateReq orderItemCreateReq = new OrderItemCreateReq();
        orderItemCreateReq.setSalePrice(active.getSalePrice().longValue());
        orderItemCreateReq.setProductPrice(active.getVoucherFaceValue().longValue());
        orderItemCreateReq.setSettlementPrice(active.getSalePrice().longValue());
        orderItemCreateReq.setPartnerId(partnerId);

        orderItemCreateReq.setProductId(activityCode);
        orderItemCreateReq.setProductSpec(activityCode);
        orderItemCreateReq.setProductName(active.getActiveName());
        orderItemCreateReq.setProductSpecName(active.getActiveName());
        orderItemCreateReq.setProductSeq(1);
        orderItemCreateReq.setProductCode(activityCode);
        orderItemCreateReq.setThirdProductId("");
        orderItemCreateReq.setProductQuantity(1);

        OrderProductAddInfoDto orderProductAddInfoDto = new OrderProductAddInfoDto();
        List<ProductBindingCouponType> productBindingCoupons = new ArrayList<>();
        ProductBindingCouponType productBindingCouponType2 = new ProductBindingCouponType();
        productBindingCouponType2.setActivityCode(active.getActiveCode());
        productBindingCouponType2.setNum(active.getAccountSendOutAmount());
        productBindingCouponType2.setActivityName(active.getActiveName());
        productBindingCoupons.add(productBindingCouponType2);
        orderProductAddInfoDto.setProductBindingCoupons(productBindingCoupons);
        orderItemCreateReq.setExtInfo(JSONObject.toJSONString(orderProductAddInfoDto));
        orderItemList.add(orderItemCreateReq);

        //商品信息赋值
        request.setOrderItemList(orderItemList);
        //收货人信息转换
        List<DeliveryContactInfoCreateReq> deliveryContactInfoList = new ArrayList<>();
        DeliveryContactInfoCreateReq deliveryContactInfoCreateReq = new DeliveryContactInfoCreateReq();
        //地址类型 1:订单地址 2:售后单地址 3:配送员信息
        deliveryContactInfoCreateReq.setRelateObjectType(1);
        //联系方式类型 1:取件 2:收件
        deliveryContactInfoCreateReq.setInfoType(1);
        deliveryContactInfoCreateReq.setContactsName(userLoginInfoDto.getNickName());
        deliveryContactInfoCreateReq.setMobile(userLoginInfoDto.getMobile());
        deliveryContactInfoCreateReq.setLatitude(null);
        deliveryContactInfoCreateReq.setLongitude(null);
        deliveryContactInfoCreateReq.setAddressDetail(null);
        deliveryContactInfoCreateReq.setProvince(null);
        deliveryContactInfoCreateReq.setCity(null);
        deliveryContactInfoCreateReq.setRegion(null);
        deliveryContactInfoList.add(deliveryContactInfoCreateReq);
        request.setDeliveryContactInfoList(deliveryContactInfoList);
        //保存门店渠道信息
        request.setOperator(userLoginInfoDto.getNickName());
        request.setAppId(userLoginInfoDto.getWxAppId());
        return request;

    }

    /**
     *
     * @param message
     * @param confirmOrderDto
     * @param orderBeans
     * @return
     */
    public String paySuccessCallback(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, OrderBeanV1> orderBeans) {
        OrderBeanV1 orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());

        ConfirmOrderRequest var1 = LightApplicationConvertToAssortmentSdkAdapter.confirmOrderDtoConvertToConfirmOrderRequest(confirmOrderDto, orderBeans.get(OrderBeanType.MERMBERORDER.getCode()));
        var1.setPartnerId(orderBean.getCompanyId());
        var1.setUserId(orderBean.getUserId());
        var1.setStoreId(orderBean.getShopId());
        var1.setOrderType(orderBean.getOrderType());
        var1.setProductOrderCode(orderBean.getOid());
        var1.setPayDate(DateUtil.convert2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
        var1.setPayTransId(message.getOut_trade_no());
        var1.setOperator(orderBean.getUserName());
        var1.setEndTransId(message.getEndTransId());
        var1.setExtInfo(orderBean.getExtInfo());
        if(orderBean.getGmtExpect() != null && orderBean.getGmtExpect() != 0){
            var1.setExpectTime(DateUtil.convert2String(new Date(orderBean.getGmtExpect()),DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
        }
        try {
            // 订单支付成功
            PayAccessResponse payAccessResponse = orderBusinessService.payAccess(var1);
        }catch (Exception e){
            AppLogUtil.errorLog("sellCouponPayAccessError",JSONObject.toJSONString(var1),null,e);
        }
        //支付成功直接完成
        OrderChangeStateReq request = new OrderChangeStateReq();
        request.setOrderCode(orderBean.getOid());
        request.setOrderState(NewOrderStatus.COMPLETE.getIndex());
        request.setOperator(orderBean.getUserName());
        request.setPartnerId(orderBean.getCompanyId());
        request.setRemark("已完成");
        OrderBaseResp updateOrderStateResp = orderSdkService.updateOrderState(request, LogThreadLocal.getTrackingNo());
        orderSdkAdapter.convent2BaseOrderResponse(updateOrderStateResp);

        // fisherman 直播卖券-> 需要额外上报  时间来不及 有时间 这一块需要移到 异步调用
        try {
            weChatLiveMsgHandle.reportOrderStatus(orderBean, 1);
        }catch (Exception e){
            // 不要影响主流程
        }

        Map<String, Object> map = Maps.newTreeMap();
        map.put("code", 100);
        map.put("message", "success");
        return JSONObject.toJSONString(map);
    }


    /**
     * 查询促销优惠，赋值订单金额，商品优惠后金额，优惠记录
     */
    private List<SubtractStockVO> calculationDiscount(String partnerId, String storeId, String userId, ProductInfo products, CreateOrderRequest createOrderRequest){
        CalculationDiscountRequestDto calculationDiscountRequestDto = new CalculationDiscountRequestDto();
        calculationDiscountRequestDto.setStoreId(storeId);
        calculationDiscountRequestDto.setPartnerCode(partnerId);
        calculationDiscountRequestDto.setUserId(userId);
        List<CalculationDiscountGoodsDto> discountGoodsDtoList = new ArrayList<>();
        CalculationDiscountGoodsDto discountGoodsDto = new CalculationDiscountGoodsDto();
        // fix - > 调用促销没有 购物车行id 导致 促销优惠没有参与
        discountGoodsDto.setCartGoodsUid("no_cartGoodsUid");
        discountGoodsDto.setGoodsId(products.getPid());
        discountGoodsDto.setSpuId(products.getPid());
        discountGoodsDto.setGoodsQuantity(1);
        discountGoodsDto.setOriginalPrice(products.getFinalPrice().intValue());
        discountGoodsDtoList.add(discountGoodsDto);
        calculationDiscountRequestDto.setGoods(discountGoodsDtoList);

        //买券包调促销指定只计算限时特价    [2,21,29]  29.商品限购
        calculationDiscountRequestDto.setActivityTypes(Arrays.asList(ActivityTypeEnum.TYPE_2.getCode(), ActivityTypeEnum.TYPE_21.getCode(), ActivityTypeEnum.TYPE_29.getCode()));
        calculationDiscountRequestDto.setVer(1);
        calculationDiscountRequestDto.setApplication("isaas");
        ActivityCalculationDiscountResponseDto activityCalculationDiscountResponseDto = promotionDiscountClient.calculationDiscountSharing(calculationDiscountRequestDto);
        if (!ResponseResult.SUCCESS.getCode().equals(activityCalculationDiscountResponseDto.getStatusCode()) || activityCalculationDiscountResponseDto.getResult() == null) {
            // fisherman 商品限购虚拟券 服务端拦截校验
            if (Objects.equals(activityCalculationDiscountResponseDto.getStatusCode(),"80033")) {
                throw new ServiceException(activityCalculationDiscountResponseDto.getStatusCode(),activityCalculationDiscountResponseDto.getMsg());
            }
            return null;
        }
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult result = activityCalculationDiscountResponseDto.getResult();
        if(CollectionUtils.isEmpty(result.getDiscounts())){
            return null;
        }
        if(CollectionUtils.isNotEmpty(result.getGoods())){
            for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods good : result.getGoods()){
                if(good.getGoodsId().equals(products.getPid())){
                    if(CollectionUtils.isEmpty(good.getDiscounts())){
                        return result.getStocks();
                    }
                    List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> discounts = good.getDiscounts();
                    OrderSettlementCreateReq orderSettlementCreateReq = new OrderSettlementCreateReq();
                    Long discount = discounts.get(0).getDiscount();
                    orderSettlementCreateReq.setProductId(products.getPid());
                    orderSettlementCreateReq.setSettlementType(createOrderAdapter.getOrderSettlementType(discounts.get(0).getType()));
                    orderSettlementCreateReq.setSettlementAmount(products.getFinalPrice()-discount);
                    orderSettlementCreateReq.setShopDiscountAmount(discount);
                    orderSettlementCreateReq.setNumber(1);
                    orderSettlementCreateReq.setShopAmount(products.getFinalPrice()-discount);
                    orderSettlementCreateReq.setExternalObjectId(discounts.get(0).getActivityCode());
                    orderSettlementCreateReq.setIsOnline(true);
                    orderSettlementCreateReq.setExternalObjectName(discounts.get(0).getActivityName());
                    orderSettlementCreateReq.setNote(result.getDiscounts().get(0).getActivityName());
                    List<OrderSettlementCreateReq> orderSettlementCreateReqList = new ArrayList<>();
                    orderSettlementCreateReqList.add(orderSettlementCreateReq);
                    createOrderRequest.setOrderSettlementDetailList(orderSettlementCreateReqList);
                    createOrderRequest.setSettlementAmount(result.getTotalAmount());
                    createOrderRequest.setActualPayAmount(result.getTotalAmount());
                    createOrderRequest.getOrderItemList().get(0).setSettlementPrice(products.getFinalPrice()-discount);
                    createOrderRequest.getOrderItemList().get(0).setProductSharePrice(discount);
                }
            }
            return result.getStocks();
        }
        return null;
    }

    /**
     * 抖音卖券支付成功回调
     * 走自己的发券mq，支持失败补偿
     * @param orderBeans
     * @return
     */
    public String paySuccessCallbackForTiktok(PaysuccessNoticeMessage message, ConfirmOrderDto confirmOrderDto, Map<String, OrderBeanV1> orderBeans) {
        String result = this.paySuccessCallback(message, confirmOrderDto, orderBeans);
        OrderBeanV1 orderBean = orderBeans.get(OrderBeanType.SAASORDER.getCode());
        OrderInfoReqs orderInfo = new OrderInfoReqs();
        orderInfo.setOrderCode(orderBean.getOid());
        orderInfo.setPartnerId(orderBean.getCompanyId());
        orderInfo.setAppId(orderBean.getAppId());
        orderInfo.setBizType(orderBean.getBizType());
        // 拓展字段中有卖券手机号
        orderInfo.setExtInfo(orderBean.getExtInfo());
        // 支付渠道，用于识别抖音卖的订单
        orderInfo.setPayChannelType(orderBean.getPayChannelType());
        List<OrderItemResp> orderItemList = new ArrayList<>();
        for (ProductBeanV1 productBean : orderBean.getProductList()) {
            OrderItemResp orderItemResp = new OrderItemResp();
            // 这里存的是虚拟商品信息
            orderItemResp.setExtInfo(productBean.getExtInfo());
            orderItemList.add(orderItemResp);
        }
        orderInfo.setOrderItemList(orderItemList);
        //发券mq
        sendCouponService.sendCouponMq(orderInfo);
        return result;
    }

    /**
     * 获取商户支付超时时间
     * @param partnerId 商户Id
     * @return 超时时间
     */
    private String getPartnerPayOvertime(String partnerId) {
        return Optional.ofNullable(openPlatformPartnerConfigManager.selectPartnerConfigByPartnerKey(partnerId, RedisKeyConstant.PARTNER_PAY_OVERTIME))
                .orElseGet(() -> {
                    AssortmentOpenPlatformPartnerConfig config = new AssortmentOpenPlatformPartnerConfig();
                    config.setPartnerValue("30");
                    openPlatformPartnerConfigManager.addPartnerConfig(partnerId, RedisKeyConstant.PARTNER_PAY_OVERTIME, config);
                    return config;
                }).getPartnerValue();
    }
}
