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) (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) } 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 }