298 lines
13 KiB
Go
298 lines
13 KiB
Go
package defsch
|
||
|
||
import (
|
||
"fmt"
|
||
"math"
|
||
"time"
|
||
|
||
"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 {
|
||
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))
|
||
}
|
||
if savedOrderInfo != nil {
|
||
//TODO 2020-07-21 发单时间要在门店的营业时间内
|
||
if savedOrderInfo.storeDetail != nil {
|
||
if savedOrderInfo.storeDetail.OpenTime1 != 0 && savedOrderInfo.storeDetail.CloseTime1 != 0 {
|
||
time1 := jxutils.JxOperationTime2TimeByDate(savedOrderInfo.storeDetail.OpenTime1, time.Now())
|
||
time2 := jxutils.JxOperationTime2TimeByDate(savedOrderInfo.storeDetail.CloseTime1, time.Now())
|
||
if time.Now().Sub(time1) < 0 || time.Now().Sub(time2) > 0 {
|
||
if savedOrderInfo.storeDetail.OpenTime2 != 0 && savedOrderInfo.storeDetail.CloseTime2 != 0 {
|
||
time3 := jxutils.JxOperationTime2TimeByDate(savedOrderInfo.storeDetail.OpenTime2, time.Now())
|
||
time4 := jxutils.JxOperationTime2TimeByDate(savedOrderInfo.storeDetail.CloseTime2, time.Now())
|
||
if time.Now().Sub(time3) < 0 || time.Now().Sub(time4) > 0 {
|
||
// globals.SugarLogger.Warnf("createWaybillOn3rdProviders return orderID: %s,不在门店营业时间范围内1!", order.VendorOrderID)
|
||
err = fmt.Errorf("不在门店营业时间范围内!")
|
||
}
|
||
} else {
|
||
// globals.SugarLogger.Warnf("createWaybillOn3rdProviders return orderID: %s,不在门店营业时间范围内2!", order.VendorOrderID)
|
||
err = fmt.Errorf("不在门店营业时间范围内!")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
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)
|
||
}
|
||
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, err error) {
|
||
jxutils.CallMsgHandler(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 {
|
||
order := savedOrderInfo.order
|
||
if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
|
||
return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID)
|
||
}
|
||
if !forceCreate {
|
||
err = s.isPossibleSwitch2SelfDelivery(order)
|
||
}
|
||
if err == nil {
|
||
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.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
||
return bills, 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)}, 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
|
||
}
|