package defsch

import (
	"fmt"
	"git.rosy.net.cn/jx-callback/business/jxstore/cms"
	"math"
	"time"

	"git.rosy.net.cn/baseapi/utils"

	"git.rosy.net.cn/jx-callback/business/model/dao"

	"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/partner"
	"git.rosy.net.cn/jx-callback/globals"
)


func (s *DefScheduler) loadSavedOrderByID(vendorOrderID string, vendorID int, isForceLoad bool) *WatchOrderInfo {
	return s.loadSavedOrderFromMap(&model.OrderStatus{
		RefVendorOrderID: vendorOrderID,
		RefVendorID:      vendorID,
	}, isForceLoad)
}

func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
	var order *model.GoodsOrder
	jxutils.CallMsgHandler(func() {
		err = func() (err error) {
			globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
			savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
			if savedOrderInfo != nil {
				order = savedOrderInfo.order
				if err = s.isPossibleSwitch2SelfDelivery(order); err == nil {
					globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus ordersavedOrderInfoID:%s", utils.Format4Output(savedOrderInfo, false))
					err = s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
					if err == nil {
						if model.IsOrderDeliveryByStore(order) {
							if order.Status < model.OrderStatusDelivering {
								storeDetail, err2 := dao.GetStoreDetail(dao.GetDB(), order.StoreID, order.VendorID, "")
								phone := userName
								if err = err2; err == nil {
									phone = storeDetail.Tel1
								}
								err = s.SelfDeliverDelivering(order, phone)
							}
						} else {
							if order.Status < model.OrderStatusDelivering {
								err = s.Swtich2SelfDeliver(order, userName)
							} else if order.VendorID == order.WaybillVendorID { // 状态为配送中，且是购物平台运单，不能转自送了
								err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
							}
						}
					}
				}
				if err == nil {
					order.Status = model.OrderStatusDelivering
					order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled | model.OrderDeliveryFlagMaskPurcahseDisabled
					if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
						s.stopTimer(savedOrderInfo)
						globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
						return err
					}
				}
			} else {
				order = &model.GoodsOrder{
					VendorOrderID: vendorOrderID,
					VendorID:      vendorID,
				}
				err = scheduler.ErrCanNotFindOrder
			}
			globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s error:%v", vendorOrderID, userName, err)
			return err
		}()
	}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
	vendorStatus := fmt.Sprintf("%s转商户自送成功", ctx.GetUserName())
	remark := ""
	if err != nil {
		vendorStatus = fmt.Sprintf("%s转商户自送失败", ctx.GetUserName())
		remark = err.Error()
	}
	partner.CurOrderManager.OnOrderMsg(order, vendorStatus, remark)
	return err
}

func (s *DefScheduler) canOrderCreateWaybillNormally(order *model.GoodsOrder, savedOrderInfo *WatchOrderInfo) (err error) {
	if !(order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) {
		err = fmt.Errorf("当前订单%s没有处于拣货完成且没有结束没有锁定的订单才能进行召唤配送操作", order.VendorOrderID)
	} else if model.IsOrderHaveWaybill(order) {
		err = fmt.Errorf("当前订单%s已经有了有效的承运人%s了", order.VendorOrderID, jxutils.GetVendorName(order.WaybillVendorID))
	}
	return err
}

func (s *DefScheduler) isPossibleSwitch2SelfDelivery(order *model.GoodsOrder) (err error) {
	if model.IsOrderDeliveryByPlatform(order) {
		if order.Status < model.OrderStatusFinishedPickup {
			err = fmt.Errorf("拣货完成后才能转自配送")
		} else if order.Status == model.OrderStatusFinishedPickup {
			if time.Now().Sub(order.StatusTime) < minMinute2Schedule3rdCarrier*time.Minute {
				err = fmt.Errorf("非自配送门店转3方配送至少要求拣货完成后%d分钟才能操作", minMinute2Schedule3rdCarrier)
			}
		} else if order.Status >= model.OrderStatusDelivering && order.Status < model.OrderStatusEndBegin {
			if model.IsOrderHaveOwnWaybill(order) {
				err = fmt.Errorf("%s物流已在配送中，不能转自配送", jxutils.GetVendorName(order.VendorID))
			}
		} else if order.Status >= model.OrderStatusEndBegin {
			err = fmt.Errorf("订单%s已经结束，请刷新状态", order.VendorOrderID)
		}
	}
	return err
}

// 创建订单
func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Context, savedOrderInfo *WatchOrderInfo, courierVendorIDs, excludeCourierVendorIDs []int, forceCreate bool, maxDeliveryFee int64) (bills []*model.Waybill, err error) {
	order := savedOrderInfo.order
	// 查看订单状态是否处于可配送状态
	if !forceCreate {
		err = s.canOrderCreateWaybillNormally(order, nil)
	}
	if err == nil {
		if forceCreate {
			maxDeliveryFee = math.MaxInt64
		}
		// 生成美团订单(三方订单)
		if bills, err = s.CreateWaybillOnProviders(ctx, order, courierVendorIDs, excludeCourierVendorIDs, maxDeliveryFee, forceCreate); err == nil {
			if forceCreate {
				order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
				err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
			}
			if err == nil {
				if forceCreate {
					s.stopTimer(savedOrderInfo)
				}

				// 获取门店品牌余额
				storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order)) // 获取门店余额

				// 如果门店没钱,查看品牌，查询门店品牌id
				storeList, err := dao.GetStoreList(dao.GetDB(), []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, nil, nil, nil, "")
				if err != nil || len(storeList) != 1 {
					return nil, fmt.Errorf("门店id:[%d],所属品牌不唯一,或其他查询错误", order.JxStoreID)
				}
				result, err := dao.GetBrandBalance(dao.GetDB(), storeList[0].BrandID) // 品牌余额
				if err != nil {
					return nil, err
				}

				//门店发单开始扣钱
				if order.CreateDeliveryType == model.YES {
					deliveryFeeMap, _ := s.QueryOrderWaybillFeeInfoEx(ctx, order.VendorOrderID, order.VendorID)
					// 运费相等为0或支出大于收入不做，
					isEqual, isZero, _ := partner.CurStoreAcctManager.CheckStoreAcctExpendExist(order.VendorOrderID)
					expend, lastFee, _ := partner.CurStoreAcctManager.GetStoreAcctExpendLastCreateWayBillFee(order.VendorOrderID)
					// 收最贵的一个订单配送费(配送费发送变化,收取最贵的价格)
					if !isZero && !isEqual {
						var newPrice int64
						if len(courierVendorIDs) == 1 {
							courierVendorID := courierVendorIDs[0]
							if _, ok := deliveryFeeMap[courierVendorID]; ok {
								newPrice = deliveryFeeMap[courierVendorID].DeliveryFee
							}
						} else if len(courierVendorIDs) == 0 {
							var maxFee int64
							for _, v := range deliveryFeeMap {
								if v.DeliveryFee > maxFee {
									v.DeliveryFee = maxFee
								}
							}
							newPrice = maxFee
						}
						//  门店支出运费
						if storeList[0].BrandID != scheduler.JXC4B_SHOP && storeList[0].BrandID != scheduler.JXC4B_RAND_JXGY { // 非京西品牌,先扣门店在扣品牌
							if storeAcct.AccountBalance > int(newPrice) {
								if int(newPrice) > lastFee {
									// 门店支出费用
									partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(model.Waybill{}.DesiredFee), partner.StoreAcctTypeExpendCreateWaybill2ndMore, order.VendorOrderID, expend.ID) //int(newPrice)-lastFee
								}
							} else if result > int(newPrice) {
								// 品牌支出费用
								partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, storeList[0].BrandID, int(model.Waybill{}.DesiredFee), model.BrandBillTypeExpend, model.BrandBillFeeTypeDelivery, order.VendorOrderID)
							} else {
								return nil, fmt.Errorf("门店id:[%d],品牌id:[]%d,门店以及门店所属品牌余额不足,无法发单", order.JxStoreID, storeList[0].BrandID)
							}
						} else { // 京西品牌
							if storeAcct.AccountBalance > int(newPrice) {
								if int(newPrice) > lastFee {
									// 门店支出费用
									partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(model.Waybill{}.DesiredFee), partner.StoreAcctTypeExpendCreateWaybill2ndMore, order.VendorOrderID, expend.ID) //int(newPrice)-lastFee
								}
							} else {
								return nil, fmt.Errorf("门店id:[%d],品牌id:[]%d,门店以及门店所属品牌余额不足,无法发单", order.JxStoreID, storeList[0].BrandID)
							}
						}

					} else {
						if len(courierVendorIDs) == 1 {
							courierVendorID := courierVendorIDs[0]
							if _, ok := deliveryFeeMap[courierVendorID]; ok {
								if storeList[0].BrandID != scheduler.JXC4B_SHOP && storeList[0].BrandID != scheduler.JXC4B_RAND_JXGY { // 非京西品牌,先扣门店在扣品牌
									if storeAcct.AccountBalance > int(model.Waybill{}.DesiredFee) {
										partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(model.Waybill{}.DesiredFee), partner.StoreAcctTypeExpendCreateWaybill2ndMore, order.VendorOrderID, expend.ID) //int(newPrice)-lastFee
									} else if result > int(model.Waybill{}.DesiredFee) {
										// 品牌支出费用
										partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, storeList[0].BrandID, int(model.Waybill{}.DesiredFee), model.BrandBillTypeExpend, model.BrandBillFeeTypeDelivery, order.VendorOrderID)
									} else {
										return nil, fmt.Errorf("门店id:[%d],品牌id:[]%d,门店以及门店所属品牌余额不足,无法发单", order.JxStoreID, storeList[0].BrandID)
									}
								} else { // 京西品牌
									if storeAcct.AccountBalance > int(model.Waybill{}.DesiredFee) {
										// 门店支出费用
										partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(model.Waybill{}.DesiredFee), partner.StoreAcctTypeExpendCreateWaybill2ndMore, order.VendorOrderID, expend.ID) //int(newPrice)-lastFee
									} else {
										return nil, fmt.Errorf("门店id:[%d],品牌id:[]%d,门店以及门店所属品牌余额不足,无法发单", order.JxStoreID, storeList[0].BrandID)
									}
								}
							}
						} else if len(courierVendorIDs) == 0 {
							var maxFee int64
							for _, v := range deliveryFeeMap {
								if v.DeliveryFee > maxFee {
									v.DeliveryFee = maxFee
								}
							}
							partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(model.Waybill{}.DesiredFee), partner.StoreAcctTypeExpendCreateWaybillEx, order.VendorOrderID, 0) //int(maxFee)
						}
					}
				}
				globals.SugarLogger.Debugf("CreateWaybillOnProviders4SavedOrder orderID:%s userName:%s successfully", order.VendorOrderID, ctx.GetUserName())
				return bills, err
			}
		}
	}
	if err != nil {
		globals.SugarLogger.Debugf("CreateWaybillOnProviders4SavedOrder orderID:%s failed with error:%v", order.VendorOrderID, err)
	}
	return nil, err
}

// 创建三方运单
func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, courierVendorIDs []int, forceCreate bool, maxDeliveryFee int64) (bills []*model.Waybill, errCode string, err error) {
	savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
	if savedOrderInfo != nil {
		order := savedOrderInfo.order
		//1表示为门店发单，需要验证门店账户余额情况
		if errCode, err = s.CheckStoreBalance(ctx, order, courierVendorIDs); err != nil {
			return nil, errCode, err
		}
	}

	billFunc := func() {
		bills, err = func() (bills []*model.Waybill, err error) {
			userName := ctx.GetUserName()
			globals.SugarLogger.Debugf("CreateWaybillOnProvidersEx orderID:%s userName:%s", vendorOrderID, userName)
			if vendorID == model.VendorIDELM {
				return nil, fmt.Errorf("不要直接使用饿了么订单号，请使用相应的饿百订单号")
			}
			// 创建可调度对象,并且存储
			savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
			if savedOrderInfo != nil {
				savedOrderInfo.order.SendOrderType = 1 // 设置为手动创建订单
				order := savedOrderInfo.order
				if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
					return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID)
				}
				if !forceCreate {
					err = s.isPossibleSwitch2SelfDelivery(order)
				}
				if err == nil {
					if savedOrderInfo.order.VendorID == model.VendorIDEBAI {
						courierVendorIDs = []int{model.VendorIDMTPS, model.VendorIDDada}
					}
					order := savedOrderInfo.order
					order.DeliveryFlag = 0
					err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
					// 创建订单
					if bills, err = s.CreateWaybillOnProviders4SavedOrder(ctx, savedOrderInfo, courierVendorIDs, nil, forceCreate, maxDeliveryFee); err == nil && len(bills) > 0 {
						partner.CurOrderManager.OnOrderMsg(order, "手动创建运单成功", fmt.Sprintf("%s创建%s平台运单,强发:%t,最高限价:%d", ctx.GetUserName(), model.VendorChineseNames[bills[0].WaybillVendorID], forceCreate, maxDeliveryFee))
					}
				}
			} else {
				err = scheduler.ErrCanNotFindOrder
			}
			globals.SugarLogger.Infof("CreateWaybillOnProvidersEx orderID:%s userName:%s error:%v", vendorOrderID, userName, err)
			return bills, err
		}()
	}

	jxutils.CallMsgHandler(billFunc, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
	return bills, errCode, err
}

func (s *DefScheduler) CheckStoreBalance(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs []int) (errCode string, err error) {
	if order.CreateDeliveryType == model.YES {
		//暂时这么认为，len courierVendorIDs 为1表示是老板或者运营从小程序上点的立即发单，因为小程序上是点哪个发哪个
		//京西后台则是点一下发3个，len courierVendorIDs 是0
		//如果是小程序上点哪个扣哪个平台的钱
		//如果是后台，则选最高的那个扣
		storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order)) // 获取门店余额

		// 如果门店没钱,查看品牌，查询门店品牌id
		storeList, err := dao.GetStoreList(dao.GetDB(), []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, nil, nil, nil, "")
		if err != nil || len(storeList) != 1 {
			return "", fmt.Errorf("门店id:[%d],所属品牌不唯一,或其他查询错误", order.JxStoreID)
		}
		result, err := dao.GetBrandBalance(dao.GetDB(), storeList[0].BrandID) // 品牌余额
		if err != nil {
			return "", err
		}

		deliveryFeeMap, _ := s.QueryOrderWaybillFeeInfoEx(ctx, order.VendorOrderID, order.VendorID)
		if err != nil {
			return errCode, fmt.Errorf("获取账户余额失败！")
		}
		//1、先判断是不是第一次发：查询库里是否有这个订单的运费支出记录，再查询是否有相同金额并且类型为回退的收入记录（取消运单退回）
		//前者有，后者无， 表示已经发过了，暂未取消，若这这次的发单金额小于上次的金额则不进行判断也不多扣钱，若大于则扣除‘这次金额-上次金额’的钱，余额不足问题也根据这个判断
		//前者有，后者有，表示发过并且取消过了，是多次发，直接扣
		//前者无，表示就是第一次发，直接扣
		//2、小程序里这次金额用发单平台的金额，后台里这次金额用所有平台最高费用
		isEqual, isZero, err := partner.CurStoreAcctManager.CheckStoreAcctExpendExist(order.VendorOrderID)
		globals.SugarLogger.Debugf("CheckStoreBalance orderID :%v, isEqual : %v, isZero: %v", order.VendorOrderID, isEqual, isZero)
		//表示前者有，后者无
		if !isZero && !isEqual {
			var newPrice int64
			if len(courierVendorIDs) == 1 {
				courierVendorID := courierVendorIDs[0]
				if _, ok := deliveryFeeMap[courierVendorID]; ok {
					newPrice = deliveryFeeMap[courierVendorID].DeliveryFee
				}
			} else if len(courierVendorIDs) == 0 {
				var maxFee int64
				for _, v := range deliveryFeeMap {
					if v.DeliveryFee > maxFee {
						v.DeliveryFee = maxFee
					}
				}
				newPrice = maxFee
			}
			_, lastFee, _ := partner.CurStoreAcctManager.GetStoreAcctExpendLastCreateWayBillFee(order.VendorOrderID)
			// 如果门店属于京西菜市,京西果园则只能扣门店的金额
			if int(newPrice) > lastFee {
				if storeList[0].BrandID == scheduler.JXC4B_RAND_JXGY || storeList[0].BrandID == scheduler.JXC4B_SHOP { // 订单所属门店属于京西菜市,果园,则不扣品牌只扣门店)(1果园,菜市,7京西超市)
					if storeAcct.AccountBalance < int(newPrice)-lastFee {
						return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店/品牌账户余额小于[%v]元，不能发配送！", jxutils.IntPrice2Standard(newPrice-int64(lastFee)))
					}
				} else {
					if storeAcct.AccountBalance < int(newPrice)-lastFee && result < int(newPrice)-lastFee {
						return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店/品牌账户余额小于[%v]元，不能发配送！", jxutils.IntPrice2Standard(newPrice-int64(lastFee)))
					}
				}
			}
		} else {
			if len(courierVendorIDs) == 1 {
				courierVendorID := courierVendorIDs[0]
				if _, ok := deliveryFeeMap[courierVendorID]; ok {
					if storeList[0].BrandID == scheduler.JXC4B_RAND_JXGY || storeList[0].BrandID == scheduler.JXC4B_SHOP { // 订单所属门店属于京西菜市,果园,则不扣品牌只扣门店)(1果园,菜市,7京西超市)
						if deliveryFeeMap[courierVendorID].DeliveryFee > int64(storeAcct.AccountBalance) {
							return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店/品牌账户余额小于[%v]元，不能发配送！", jxutils.IntPrice2Standard(partner.MinCreateWaybillBalance))
						}
					} else {
						if deliveryFeeMap[courierVendorID].DeliveryFee > int64(result) && deliveryFeeMap[courierVendorID].DeliveryFee > int64(storeAcct.AccountBalance) {
							return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店/品牌 账户余额小于[%v]元，不能发配送！", jxutils.IntPrice2Standard(deliveryFeeMap[courierVendorID].DeliveryFee))
						}
					}
				}
			} else if len(courierVendorIDs) == 0 {
				var maxFee int64
				for _, v := range deliveryFeeMap {
					if v.DeliveryFee > maxFee {
						v.DeliveryFee = maxFee
					}
				}
				if storeList[0].BrandID == scheduler.JXC4B_RAND_JXGY || storeList[0].BrandID == scheduler.JXC4B_SHOP { // 订单所属门店属于京西菜市,果园,则不扣品牌只扣门店)(1果园,菜市,7京西超市)
					if maxFee > int64(storeAcct.AccountBalance) {
						return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店/品牌账户余额小于[%v]元，不能发配送！", jxutils.IntPrice2Standard(partner.MinCreateWaybillBalance))
					}
				} else {
					if maxFee > int64(result) && maxFee > int64(storeAcct.AccountBalance) {
						return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店/品牌 账户余额小于[%v]元，不能发配送！", jxutils.IntPrice2Standard(maxFee))
					}
				}
			}
		}
	}
	return errCode, err
}

// todo 这个函数可以和SelfDeliveringAndUpdateStatus合并
func (s *DefScheduler) CancelAll3rdWaybills(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isStopSchedule bool) (err error) {
	jxutils.CallMsgHandler(func() {
		err = func() (err error) {
			// 取消三方运单,取消各平台单号信息,间隔一段时间后定时任务重新调度
			globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s", vendorOrderID, ctx.GetUserName())
			savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
			if savedOrderInfo != nil {
				err = s.cancelOtherWaybills(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
			} else {
				err = scheduler.ErrCanNotFindOrder
			}
			globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s error:%v", vendorOrderID, ctx.GetUserName(), err)
			// 停止调度,同事停止订单调度,不在通知第三方
			if err == nil && isStopSchedule {
				order := savedOrderInfo.order
				order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
				if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
					s.stopTimer(savedOrderInfo)
					globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s successfully", vendorOrderID, ctx.GetUserName())
				}
			}
			return err
		}()
	}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
	return err
}

// 查询三方运单费用
func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (deliveryFeeMap map[int]*partner.WaybillFeeInfo, err error) {
	jxutils.CallMsgHandler(func() {
		deliveryFeeMap, err = func() (deliveryFeeMap map[int]*partner.WaybillFeeInfo, err error) {
			userName := ctx.GetUserName()
			globals.SugarLogger.Infof("GetWaybillsInfoEx orderID:%s userName:%s", vendorOrderID, userName)

			db := dao.GetDB()
			order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
			if err != nil {
				return nil, err
			}
			if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
				return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID)
			}

			// 获取用户送货地址
			storeCourierList, err := dao.GetStoreCourierList(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, model.StoreStatusAll, model.StoreAuditStatusOnline)
			if err != nil {
				return nil, err
			}
			// 美团配送订单兑现
			waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(ctx, vendorOrderID, vendorID, true, false)
			if err != nil {
				return nil, err
			}
			waybillMap := make(map[int]*model.Waybill)
			for _, bill := range waybillList {
				waybillMap[bill.WaybillVendorID] = &bill.Waybill
			}
			deliveryFeeMap = make(map[int]*partner.WaybillFeeInfo)

			var timeoutSecond int
			if savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, false); savedOrderInfo != nil {
				timeoutSecond = savedOrderInfo.GetCreateWaybillTimeout()
			}
			for _, storeCourier := range storeCourierList {
				var feeInfo *partner.WaybillFeeInfo
				if waybillMap[storeCourier.VendorID] != nil {
					feeInfo = &partner.WaybillFeeInfo{
						Waybill: waybillMap[storeCourier.VendorID],
					}
				} else {
					if storeCourier.Status != model.StoreStatusOpened {
						feeInfo = &partner.WaybillFeeInfo{
							ErrCode: partner.WaybillFeeErrCodeCourierNotOpen,
							ErrStr:  fmt.Sprintf("暂未开通，联系运营"),
						}
					} else {
						if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil {
							if handler.Use4CreateWaybill {
								// 获取订单配送费用
								if feeInfo, err = handler.Handler.GetWaybillFee(order); err != nil {
									feeInfo = &partner.WaybillFeeInfo{
										ErrCode: partner.WaybillFeeErrCodeCourierOthers,
										ErrStr:  err.Error(),
									}
								} else {
									feeInfo.TimeoutSecond = timeoutSecond
								}
							} else {
								feeInfo = &partner.WaybillFeeInfo{
									ErrCode: partner.WaybillFeeErrCodeCourierForbidden,
									ErrStr:  fmt.Sprintf("内部错误，%d不能用于创建运单", storeCourier.VendorID),
								}
							}
						} else {
							feeInfo = &partner.WaybillFeeInfo{
								ErrCode: partner.WaybillFeeErrCodeCourierNotSupported,
								ErrStr:  fmt.Sprintf("内部错误，%d不被支持", storeCourier.VendorID),
							}
						}
					}
				}
				deliveryFeeMap[storeCourier.VendorID] = feeInfo
			}
			err = nil
			return deliveryFeeMap, err
		}()
	}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
	return deliveryFeeMap, err
}
