Files
jx-callback/business/jxcallback/scheduler/defsch/defsch_ext.go
2019-05-08 17:17:45 +08:00

242 lines
10 KiB
Go

package defsch
import (
"fmt"
"time"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner/delivery"
"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) {
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
err = s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
if err == nil {
// todo
if true { //order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled == 0 {
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
if order.Status <= model.OrderStatusFinishedPickup {
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.OrderStatusFinishedPickup {
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.UpdateOrderStatusAndFlag(order); err == nil {
s.stopTimer(savedOrderInfo)
globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
return err
}
}
} else {
err = scheduler.ErrCanNotFindOrder
}
globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s error:%v", vendorOrderID, userName, err)
return err
}()
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
return err
}
func (s *DefScheduler) canOrderCreateWaybillNormally(order *model.GoodsOrder) (err error) {
if !(order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) {
err = fmt.Errorf("当前订单%s没有处于拣货完成且没有结束没有锁定的订单才能进行召唤配送操作", order.VendorOrderID)
} else if s.IsOrderHasWaybill(order) {
err = fmt.Errorf("当前订单%s已经有了有效的承运人%s了", order.VendorOrderID, jxutils.GetVendorName(order.WaybillVendorID))
}
return err
}
func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Context, savedOrderInfo *WatchOrderInfo, courierVendorIDs []int, forceCreate bool, maxAddFee, maxDiffFee2Mtps int64) (bills []*model.Waybill, err error) {
order := savedOrderInfo.order
err = s.canOrderCreateWaybillNormally(order)
if forceCreate || err == nil {
err = nil
feeHandler := delivery.DefCreateWaybillPolicy
if forceCreate {
feeHandler = delivery.NullCreateWaybillPolicy
} else if maxAddFee != 0 {
feeHandler = delivery.CreateWaybillPolicy(maxDiffFee2Mtps, maxAddFee)
}
if bills, err = s.CreateWaybillOnProviders(ctx, order, courierVendorIDs, feeHandler, forceCreate); err == nil {
if forceCreate {
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
err = partner.CurOrderManager.UpdateOrderStatusAndFlag(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, maxAddFee, maxDiffFee2Mtps 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 scheduler.StoreDeliveryTypeByStore != s.GetStoreDeliveryType(order, nil) &&
order.Status == model.OrderStatusFinishedPickup &&
time.Now().Sub(order.StatusTime) < minMinute2Schedule3rdCarrier*time.Minute {
return nil, fmt.Errorf("非自配送门店转3方配送至少要求拣货完成后%d分钟才能操作", minMinute2Schedule3rdCarrier)
}
bills, err = s.CreateWaybillOnProviders4SavedOrder(ctx, savedOrderInfo, courierVendorIDs, forceCreate, maxAddFee, maxDiffFee2Mtps)
} 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.UpdateOrderStatusAndFlag(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
}
storeCourierList, err := dao.GetStoreCourierList(db, jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusAll)
if err != nil {
return nil, err
}
waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(ctx, vendorOrderID, vendorID, true)
if err != nil {
return nil, err
}
waybillMap := make(map[int]*model.Waybill)
for _, bill := range waybillList {
waybillMap[bill.WaybillVendorID] = bill
}
deliveryFeeMap = make(map[int]*partner.WaybillFeeInfo)
var timeoutSecond int
if savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, false); savedOrderInfo != nil {
if savedOrderInfo.timerStatusType == scheduler.TimerStatusTypeWaybill && savedOrderInfo.timerStatus == model.WaybillStatusNew {
timeoutSecond = int(savedOrderInfo.timerTime.Sub(time.Now()) / time.Second)
}
}
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("%d配送门店没有启用", storeCourier.VendorID),
}
} 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
}