From 96fb2d9535bd11f55fe855bb5353f72cd53d6174 Mon Sep 17 00:00:00 2001 From: gazebo Date: Sat, 30 Mar 2019 17:11:23 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E9=87=8D=E6=9E=84createWaybillOn3rdProvide?= =?UTF-8?q?rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxcallback/orderman/order.go | 16 ++++ .../scheduler/basesch/basesch_ext.go | 31 +++++--- .../jxcallback/scheduler/defsch/defsch.go | 77 +++---------------- .../jxcallback/scheduler/defsch/defsch_ext.go | 57 ++++++++------ business/jxutils/jxcontext/jxcontext.go | 4 + business/jxutils/jxutils_cms.go | 9 +++ business/model/const.go | 2 + business/model/dao/store.go | 20 +++++ business/model/dao/store_test.go | 9 +++ business/model/store.go | 1 + business/partner/partner.go | 1 + 11 files changed, 127 insertions(+), 100 deletions(-) diff --git a/business/jxcallback/orderman/order.go b/business/jxcallback/orderman/order.go index 53daff08a..60ba4f317 100644 --- a/business/jxcallback/orderman/order.go +++ b/business/jxcallback/orderman/order.go @@ -124,6 +124,22 @@ func (c *OrderManager) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err return err } +func (c *OrderManager) OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error) { + _, err = c.addOrderStatus(&model.OrderStatus{ + VendorOrderID: order.VendorOrderID, + VendorID: order.VendorID, + OrderType: model.OrderTypeOrder, + RefVendorOrderID: order.VendorOrderID, + RefVendorID: order.VendorID, + + VendorStatus: vendorStatus, + Status: model.OrderStatusMsg, + StatusTime: time.Now(), + Remark: remark, + }, nil) + return err +} + func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db orm.Ormer) (isDuplicated bool, err error) { globals.SugarLogger.Debugf("SaveOrder orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID) // 忽略查找JX信息错误 diff --git a/business/jxcallback/scheduler/basesch/basesch_ext.go b/business/jxcallback/scheduler/basesch/basesch_ext.go index 768bfd523..58d9ef565 100644 --- a/business/jxcallback/scheduler/basesch/basesch_ext.go +++ b/business/jxcallback/scheduler/basesch/basesch_ext.go @@ -13,23 +13,34 @@ import ( "git.rosy.net.cn/jx-callback/globals" ) -func (c *BaseScheduler) CreateWaybillOnProviders(order *model.GoodsOrder, userName string, courierVendorIDs []int, policyHandler partner.CreateWaybillPolicy) (bills []*model.Waybill, err error) { +func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, policyHandler partner.CreateWaybillPolicy) (bills []*model.Waybill, err error) { + userName := ctx.GetUserName() globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s", order.VendorOrderID, userName) + storeCourierList, err := dao.GetStoreCourierList(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusOpened) + if err != nil { + return nil, err + } + var errList []string - for _, courierVendorID := range courierVendorIDs { - bill, err2 := c.CreateWaybill(courierVendorID, order, policyHandler) - if err = err2; err == nil { - globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d bill:%v", order.VendorOrderID, userName, courierVendorID, bill) - bills = append(bills, bill) - } else { - globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err) - errList = append(errList, fmt.Sprintf("%s运单创建失败,错误:%s", model.VendorChineseNames[courierVendorID], err.Error())) + for _, storeCourier := range storeCourierList { + courierVendorID := storeCourier.VendorID + if order.VendorID != model.VendorIDWSC || courierVendorID != model.VendorIDDada { // 达达作为微商城的自有配送,不参与配送竞争 + bill, err2 := c.CreateWaybill(courierVendorID, order, policyHandler) + if err = err2; err == nil { + globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d bill:%v", order.VendorOrderID, userName, courierVendorID, bill) + bills = append(bills, bill) + } else { + globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err) + errList = append(errList, err.Error()) + } } } if len(bills) > 0 { err = nil + } else if len(errList) == 0 { + err = fmt.Errorf("orderID:%s没有绑定有效的三方配送门店", order.VendorOrderID) } else { - err = fmt.Errorf("所有运单失败:\n%s", utils.Format4Output(errList, false)) + err = fmt.Errorf("orderID:%s所有运单失败:\n%s", order.VendorOrderID, utils.Format4Output(errList, false)) } globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s error:%v", order.VendorOrderID, userName, err) return bills, err diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index 37de4c8c5..7bcd951b9 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -1,12 +1,13 @@ package defsch import ( - "errors" "fmt" "math/rand" "sync" "time" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/basesch" @@ -17,7 +18,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/model/legacymodel" "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/delivery" "git.rosy.net.cn/jx-callback/globals" "github.com/astaxie/beego/orm" ) @@ -46,10 +46,6 @@ const ( maxAddFee = 300 // 最大增加费用,单位为分,超过不发三方配送了 ) -var ( - ErrAddFeeExceeded = errors.New("配送超过基准价太多") -) - var ( FixedScheduler *DefScheduler ) @@ -57,7 +53,6 @@ var ( type WatchOrderInfo struct { autoPickupTimeoutMinute int // 0表示禁用,1表示用缺省值time2AutoPickupMin,其它表示分钟数 storeDeliveryType int - supported3rdCarriers []int order *model.GoodsOrder // order里的信息是保持更新的 waybills map[int]*model.Waybill // 这个waybills里的状态信息是不真实的,只使用id相关的信息 @@ -86,7 +81,6 @@ func NewWatchOrderInfo(order *model.GoodsOrder) (retVal *WatchOrderInfo) { autoPickupTimeoutMinute: 1, storeDeliveryType: scheduler.StoreDeliveryTypeCrowdSourcing, waybills: map[int]*model.Waybill{}, - supported3rdCarriers: []int{}, } retVal.SetOrder(order) return retVal @@ -117,25 +111,6 @@ func (s *WatchOrderInfo) updateOrderStoreFeature(order *model.GoodsOrder) (err e if s.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { order.DeliveryFlag |= model.OrderDeliveryFlagMaskPurcahseDisabled } - isNeedSchedule := s.storeDeliveryType == scheduler.StoreDeliveryTypeByStore || storeMap.DeliveryCompetition != 0 - if isNeedSchedule { - vendorList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, jxStoreID, -1) - if err = err2; err != nil { - return err - } - for _, v := range vendorList { - // 达达作为微商城的自有配送,不参与竞争配送 - if !(order.VendorID == model.VendorIDWSC && v.VendorID == model.VendorIDDada) { - s.supported3rdCarriers = append(s.supported3rdCarriers, v.VendorID) - } - } - if len(s.supported3rdCarriers) == 0 { - isNeedSchedule = false - } - } - if !isNeedSchedule { - order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled - } _, err = dao.UpdateEntity(db, order, "DeliveryFlag") globals.SugarLogger.Debugf("updateOrderStoreFeature orderID:%s, s.storeDeliveryType:%d, order.DeliveryFlag:%d", order.VendorOrderID, s.storeDeliveryType, order.DeliveryFlag) } @@ -508,47 +483,19 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf if order.VendorID == model.VendorIDELM { return nil } - if order.WaybillVendorID == model.VendorIDUnknown { - if order.LockStatus == model.OrderStatusUnknown && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin { // 订单在配送中被取消时就是配送中状态 - if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { - if savedOrderInfo.retryCount <= maxWaybillRetryCount { - successCount := 0 - for _, vendorID := range savedOrderInfo.supported3rdCarriers { - handlerInfo := partner.GetDeliveryPlatformFromVendorID(vendorID) - if handlerInfo != nil && handlerInfo.Use4CreateWaybill && savedOrderInfo.waybills[vendorID] == nil && (excludeBill == nil || vendorID != excludeBill.WaybillVendorID) { - if _, err = s.CreateWaybill(vendorID, order, delivery.DefCreateWaybillPolicy); err == nil { - successCount++ - } else { - globals.SugarLogger.Infof("CreateWaybill orderID:%s, vendor:%s failed with error:%v", order.VendorOrderID, jxutils.GetVendorName(vendorID), err) - } - } - } - if successCount != 0 { - savedOrderInfo.retryCount++ - err = nil - } else { - globals.SugarLogger.Infof("createWaybillOn3rdProviders, orderID:%s all failed", order.VendorOrderID) - err = scheduler.ErrCanNotCreateAtLeastOneWaybill - } - } else { - globals.SugarLogger.Infof("createWaybillOn3rdProviders [运营]同一订单orderID:%s尝试了%d次创建运单失败, 停止调度,如果还需要发单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount) - - tmpLog := &legacymodel.TempLog{ - VendorOrderID: order.VendorOrderID, - RefVendorOrderID: order.VendorOrderID, - Msg: fmt.Sprintf("createWaybillOn3rdProviders, orderID:%s failed %d times, stop schedule", order.VendorOrderID, savedOrderInfo.retryCount), - } - db := orm.NewOrm() - db.Insert(tmpLog) - } - } else { - globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, store:%d dont't support 3rd delivery platform", order.VendorOrderID, jxutils.GetSaleStoreIDFromOrder(order)) - } + if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { + if savedOrderInfo.retryCount <= maxWaybillRetryCount { + _, err = s.CreateWaybillOnProvider4SavedOrder(jxcontext.NewWithOnlyUserName("admin"), savedOrderInfo, false) } else { - globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, status:%d doesn't match model.OrderStatusFinishedPickup, bypass", order.VendorOrderID, order.Status) + err = fmt.Errorf("订单:%s已经自动创建过了%d次运单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount) + globals.SugarLogger.Infof("createWaybillOn3rdProviders [运营]同一订单orderID:%s尝试了%d次创建运单失败, 停止调度,如果还需要发单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount) } } else { - globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, waybillVendorID:%d, vendorWaybilID:%s is not empty, bypass", order.VendorOrderID, order.WaybillVendorID, order.VendorWaybillID) + globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, store:%d dont't support 3rd delivery platform", order.VendorOrderID, jxutils.GetSaleStoreIDFromOrder(order)) + } + + if err != nil { + partner.CurOrderManager.OnOrderMsg(order, "自动创建三方运单", jxutils.LimitStringLen(err.Error(), 255)) } return err } diff --git a/business/jxcallback/scheduler/defsch/defsch_ext.go b/business/jxcallback/scheduler/defsch/defsch_ext.go index d1ab801b6..93d4589ba 100644 --- a/business/jxcallback/scheduler/defsch/defsch_ext.go +++ b/business/jxcallback/scheduler/defsch/defsch_ext.go @@ -60,6 +60,37 @@ func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, ven return err } +func (s *DefScheduler) CreateWaybillOnProvider4SavedOrder(ctx *jxcontext.Context, savedOrderInfo *WatchOrderInfo, forceCreate bool) (bills []*model.Waybill, err error) { + order := savedOrderInfo.order + if forceCreate || (order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) { + if forceCreate || !s.IsOrderHasWaybill(order) { + feeHandler := delivery.DefCreateWaybillPolicy + if forceCreate { + feeHandler = delivery.NullCreateWaybillPolicy + } + if bills, err = s.CreateWaybillOnProviders(ctx, order, feeHandler); err == nil { + if forceCreate { + order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled + err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order) + } + if err == nil { + if forceCreate { + s.stopTimer(savedOrderInfo) + } + globals.SugarLogger.Debugf("CreateWaybillOnProvider4SavedOrder orderID:%s userName:%s successfully", order.VendorOrderID, ctx.GetUserName()) + return bills, err + } + } + } else { + err = fmt.Errorf("当前订单%s已经有了有效的承运人%s了", order.VendorOrderID, jxutils.GetVendorName(order.WaybillVendorID)) + } + } else { + globals.SugarLogger.Debugf("CreateWaybillOnProvider4SavedOrder orderID:%s orderDetails:%s", order.VendorOrderID, utils.Format4Output(order, true)) + err = fmt.Errorf("必须是处于拣货完成且没有结束没有锁定的订单才能进行召唤配送操作") + } + return nil, err +} + func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, forceCreate bool) (bills []*model.Waybill, err error) { jxutils.CallMsgHandler(func() { bills, err = func() (bills []*model.Waybill, err error) { @@ -74,31 +105,7 @@ func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendor } savedOrderInfo := s.loadSavedOrderFromMap(status, true) if savedOrderInfo != nil { - order := savedOrderInfo.order - if forceCreate || (order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) { - if forceCreate || !s.IsOrderHasWaybill(order) { - feeHandler := delivery.DefCreateWaybillPolicy - if forceCreate { - feeHandler = nil - } - if bills, err = s.CreateWaybillOnProviders(order, userName, partner.UseableDeliveryVendorIDs, feeHandler); err == nil { - if forceCreate { - order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled - err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order) - } - if err == nil { - s.stopTimer(savedOrderInfo) - globals.SugarLogger.Debugf("CreateWaybillOnProvidersEx orderID:%s userName:%s successfully", vendorOrderID, userName) - return bills, err - } - } - } else { - err = fmt.Errorf("当前订单%s已经有了有效的承运人了", order.VendorOrderID) - } - } else { - globals.SugarLogger.Debugf("CreateWaybillOnProvidersEx orderID:%s orderDetails:%s", vendorOrderID, utils.Format4Output(order, true)) - err = fmt.Errorf("必须是处于拣货完成但没有结束的订单才能进行召唤配送操作") - } + bills, err = s.CreateWaybillOnProvider4SavedOrder(ctx, savedOrderInfo, forceCreate) } else { err = scheduler.ErrCanNotFindOrder } diff --git a/business/jxutils/jxcontext/jxcontext.go b/business/jxutils/jxcontext/jxcontext.go index 7085a10d8..25daa9223 100644 --- a/business/jxutils/jxcontext/jxcontext.go +++ b/business/jxutils/jxcontext/jxcontext.go @@ -36,6 +36,10 @@ func init() { AdminCtx = NewWithUserName(nil, model.AdminName, nil, nil) } +func NewWithOnlyUserName(userName string) (ctx *Context) { + return NewWithUserName(nil, userName, nil, nil) +} + func NewWithUserName(notUsed interface{}, userName string, w http.ResponseWriter, r *http.Request) (ctx *Context) { ctx = &Context{ token: userName, diff --git a/business/jxutils/jxutils_cms.go b/business/jxutils/jxutils_cms.go index bf3595eba..d39b932d9 100644 --- a/business/jxutils/jxutils_cms.go +++ b/business/jxutils/jxutils_cms.go @@ -311,3 +311,12 @@ func AddVendorInfo2Err(inErr error, vendorID int) (outErr error) { } return outErr } + +func LimitStringLen(str string, maxLen int) (limitedStr string) { + if maxLen > 0 { + if strLen := len(str); strLen > maxLen { + str = str[:maxLen] + } + } + return str +} diff --git a/business/model/const.go b/business/model/const.go index 6616b978e..77b32f553 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -117,6 +117,8 @@ const ( ) const ( + OrderStatusMsg = -100 + OrderStatusWait4Pay = -30 // 下单待支付,微盟在这个时间发新订单事件 OrderStatusUnlocked = -25 OrderStatusLocked = -20 diff --git a/business/model/dao/store.go b/business/model/dao/store.go index b7ec25c0a..b9abf330c 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -158,3 +158,23 @@ func GetMissingDadaStores(db *DaoDB, storeID int, isMustHaveJdStore bool) (store } return nil, err } + +func GetStoreCourierList(db *DaoDB, storeID, status int) (courierStoreList []*model.StoreCourierMap, err error) { + sql := ` + SELECT t1.* + FROM store_courier_map t1 + WHERE t1.deleted_at = ? AND t1.store_id = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + storeID, + } + if status != model.StoreStatusAll { + sql += " AND t1.status = ?" + sqlParams = append(sqlParams, status) + } + if err = GetRows(db, &courierStoreList, sql, sqlParams...); err == nil { + return courierStoreList, nil + } + return nil, err +} diff --git a/business/model/dao/store_test.go b/business/model/dao/store_test.go index bbcc07547..aa805949c 100644 --- a/business/model/dao/store_test.go +++ b/business/model/dao/store_test.go @@ -4,6 +4,7 @@ import ( "testing" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/globals" ) @@ -14,3 +15,11 @@ func TestGetStoreDetail(t *testing.T) { } globals.SugarLogger.Debug(utils.Format4Output(storeDetail, false)) } + +func TestGetStoreCourierList(t *testing.T) { + storeCourierList, err := GetStoreCourierList(GetDB(), 100119, model.StoreStatusOpened) + if err != nil { + t.Fatal(err) + } + globals.SugarLogger.Debug(utils.Format4Output(storeCourierList, false)) +} diff --git a/business/model/store.go b/business/model/store.go index 22b230dd6..39d837d73 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -1,6 +1,7 @@ package model const ( + StoreStatusAll = -9 StoreStatusDisabled = -1 StoreStatusClosed = 0 StoreStatusOpened = 1 diff --git a/business/partner/partner.go b/business/partner/partner.go index 6674f9bd3..205c9f453 100644 --- a/business/partner/partner.go +++ b/business/partner/partner.go @@ -62,6 +62,7 @@ type IOrderManager interface { OnOrderNew(order *model.GoodsOrder, msgVendorStatus string) (err error) OnOrderAdjust(order *model.GoodsOrder, msgVendorStatus string) (err error) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) + OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error) OnWaybillStatusChanged(bill *model.Waybill) (err error)