shan
This commit is contained in:
@@ -1,200 +0,0 @@
|
|||||||
package basesch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
FixedBaseScheduler *BaseScheduler
|
|
||||||
)
|
|
||||||
|
|
||||||
type BaseScheduler struct {
|
|
||||||
IsReallyCallPlatformAPI bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusNew || order.Status == model.OrderStatusWaitAccepted {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AcceptOrRefuseOrder(order, isAcceptIt, userName)
|
|
||||||
}, "AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
globals.SugarLogger.Debugf("AcceptOrRefuseOrder orderID:%s, status:%d is not suitable, isAcceptIt:%t", order.VendorOrderID, order.Status, isAcceptIt)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("PickupGoods orderID:%s", order.VendorOrderID)
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusAccepted {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID)
|
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() (err error) {
|
|
||||||
if err = handler.PickupGoods(order, isSelfDelivery, userName); err != nil {
|
|
||||||
if status, err2 := handler.GetOrderStatus(order.VendorOrgCode, order.VendorOrderID); err2 == nil && status >= model.OrderStatusFinished {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}, "PickupGoods orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusAccepted {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
globals.SugarLogger.Infof("PickupGoods orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
globals.SugarLogger.Debugf("PickupGoods orderID:%s status:%d already ok", order.VendorOrderID, order.Status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status >= model.OrderStatusFinishedPickup && order.Status <= model.OrderStatusDelivering {
|
|
||||||
if order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled == 0 && c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).Swtich2SelfDeliver(order, userName)
|
|
||||||
}, "Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
if err == nil { // 因为有些平台转自送后,不会再发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
|
||||||
order.Status = model.OrderStatusDelivering
|
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskPurcahseDisabled
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusFinishedPickup || order.VendorID == order.WaybillVendorID {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
globals.SugarLogger.Infof("Swtich2SelfDeliver orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
globals.SugarLogger.Debugf("Swtich2SelfDeliver orderID:%s status:%d already ok", order.VendorOrderID, order.Status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("Swtich2SelfDelivered orderID:%s", order.VendorOrderID)
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusDelivering {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).Swtich2SelfDelivered(order, userName)
|
|
||||||
}, "Swtich2SelfDelivered orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusDelivering {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
globals.SugarLogger.Infof("Swtich2SelfDelivered orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
globals.SugarLogger.Debugf("Swtich2SelfDelivered orderID:%s status:%d already ok", order.VendorOrderID, order.Status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusFinishedPickup {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivering(order, userName)
|
|
||||||
}, "SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
|
||||||
if err == nil { // 因为有些平台设置配送中后,不会发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
|
||||||
order.Status = model.OrderStatusDelivering
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusFinishedPickup {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
globals.SugarLogger.Infof("SelfDeliverDelivering orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
globals.SugarLogger.Debugf("SelfDeliverDelivering orderID:%s, status:%d already ok", order.VendorOrderID, order.Status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("SelfDeliverDelivered orderID:%s", order.VendorOrderID)
|
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status >= model.OrderStatusFinishedPickup &&
|
|
||||||
order.Status <= model.OrderStatusDelivering {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = utils.CallFuncLogError(func() error {
|
|
||||||
return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivered(order, userName)
|
|
||||||
}, "SelfDeliverDelivered orderID:%s", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusDelivering {
|
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
|
||||||
globals.SugarLogger.Infof("SelfDeliverDelivered orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
|
||||||
globals.SugarLogger.Debugf("SelfDeliverDelivered orderID:%s, status:%d already ok", order.VendorOrderID, order.Status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CreateWaybill(platformVendorID int, order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
|
|
||||||
globals.SugarLogger.Infof("CreateWaybill orderID:%s, vendor:%s", order.VendorOrderID, jxutils.GetVendorName(platformVendorID))
|
|
||||||
if !model.IsOrderSolid(order) { // 如果订单是不完整的
|
|
||||||
globals.SugarLogger.Warnf("CreateWaybill orderID:%s, vendorID:%d is not solid!!!", order.VendorOrderID, platformVendorID)
|
|
||||||
return nil, scheduler.ErrOrderIsNotSolid
|
|
||||||
}
|
|
||||||
// if order.DeliveryFlag&model.OrderDeliveryFlagMaskScheduleDisabled != 0 {
|
|
||||||
// waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(jxcontext.AdminCtx, order.VendorOrderID, order.VendorID, true)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// if len(waybillList) > 0 {
|
|
||||||
// return nil, fmt.Errorf("转商家自送的订单只允许有一个有效运单,当前已经有%s运单", jxutils.GetVendorName(waybillList[0].WaybillVendorID))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
handlerInfo := partner.GetDeliveryPlatformFromVendorID(platformVendorID)
|
|
||||||
if handlerInfo != nil && handlerInfo.Use4CreateWaybill {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
bill, err = handlerInfo.Handler.CreateWaybill(order, maxDeliveryFee)
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Infof("CreateWaybill failed orderID:%s vendorID:%d with error:%v", order.VendorOrderID, platformVendorID, err)
|
|
||||||
} else {
|
|
||||||
order.DeliveryFlag |= model.WaybillVendorID2Mask(platformVendorID)
|
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = scheduler.ErrDeliverProviderWrong
|
|
||||||
}
|
|
||||||
return bill, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
|
||||||
globals.SugarLogger.Infof("CancelWaybill bill:%v, cancelReasonID:%d cancelReason:%s", bill, cancelReasonID, cancelReason)
|
|
||||||
// 部分快递平台在取消成功后有时会不发运单取消消息过来(比如达达,904200512000442),为避免二次取消报错,添加状态判断
|
|
||||||
if c.IsReallyCallPlatformAPI && bill.OrderVendorID != bill.WaybillVendorID && bill.Status != model.WaybillStatusCanceled {
|
|
||||||
if handlerInfo := partner.GetDeliveryPlatformFromVendorID(bill.WaybillVendorID); handlerInfo != nil {
|
|
||||||
if err = utils.CallFuncLogErrorWithInfo(func() error {
|
|
||||||
return handlerInfo.Handler.CancelWaybill(bill, cancelReasonID, cancelReason)
|
|
||||||
}, "CancelWaybill bill:%v", bill); err == nil {
|
|
||||||
bill.Status = model.WaybillStatusCanceled
|
|
||||||
bill.DeliveryFlag |= model.WaybillDeliveryFlagMaskActiveCancel
|
|
||||||
_, err = dao.UpdateEntity(nil, bill, "Status", "DeliveryFlag")
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Debugf("CancelWaybill bill:%v canceled by myself", bill)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,422 +0,0 @@
|
|||||||
package basesch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/baseapi/utils/errlist"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
autoSelfTakeCode = "135246"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs, excludeCourierVendorIDs []int, maxDeliveryFee int64, createOnlyOne bool) (bills []*model.Waybill, err error) {
|
|
||||||
userName := ctx.GetUserName()
|
|
||||||
globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s, courierVendorIDs:%v, excludeCourierVendorIDs:%v", order.VendorOrderID, userName, courierVendorIDs, excludeCourierVendorIDs)
|
|
||||||
storeCourierList, err := dao.GetStoreCourierList(dao.GetDB(), []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, model.StoreStatusOpened, model.StoreAuditStatusOnline)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
courierVendorIDMap := jxutils.IntList2Map(courierVendorIDs)
|
|
||||||
excludeCourierVendorIDMap := jxutils.IntList2Map(excludeCourierVendorIDs)
|
|
||||||
errList := errlist.New()
|
|
||||||
for _, storeCourier := range storeCourierList {
|
|
||||||
if (courierVendorIDs == nil || courierVendorIDMap[storeCourier.VendorID] == 1) &&
|
|
||||||
(excludeCourierVendorIDs == nil || excludeCourierVendorIDMap[storeCourier.VendorID] == 0) {
|
|
||||||
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil && handler.Use4CreateWaybill {
|
|
||||||
courierVendorID := storeCourier.VendorID
|
|
||||||
bill, err2 := c.CreateWaybill(courierVendorID, order, maxDeliveryFee)
|
|
||||||
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)
|
|
||||||
if createOnlyOne {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err)
|
|
||||||
errList.AddErr(fmt.Errorf("平台:%s,%s", jxutils.GetVendorName(courierVendorID), err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(bills) > 0 {
|
|
||||||
err = errList.GetErrListAsOne()
|
|
||||||
if err != nil {
|
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "创建三方运单部分失败", err.Error())
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
} else if errList.GetErrListAsOne() == nil {
|
|
||||||
err = fmt.Errorf("orderID:%s没有绑定有效的三方配送门店或没有剩下可用的三方配送", order.VendorOrderID)
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("orderID:%s所有运单失败:%s", order.VendorOrderID, errList.GetErrListAsOne().Error())
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s error:%v", order.VendorOrderID, userName, err)
|
|
||||||
return bills, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SelfDeliveredAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
err = func() (err error) {
|
|
||||||
globals.SugarLogger.Infof("SelfDeliveredAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
|
|
||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
if model.IsOrderDeliveryByStore(order) {
|
|
||||||
err = c.SelfDeliverDelivered(order, userName)
|
|
||||||
} else if model.IsOrderDeliveryByPlatform(order) {
|
|
||||||
err = c.Swtich2SelfDelivered(order, userName)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
// order.Status = model.OrderStatusFinished // todo 是否需要强制设置完成状态?
|
|
||||||
if err = dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskSetDelivered); err == nil {
|
|
||||||
globals.SugarLogger.Infof("SelfDeliveredAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Infof("SelfDeliveredAndUpdateStatus orderID:%s userName:%s error:%v", vendorOrderID, userName, err)
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) PickupGoodsAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
|
|
||||||
jxutils.CallMsgHandler(func() {
|
|
||||||
err = func() (err error) {
|
|
||||||
globals.SugarLogger.Infof("PickupGoodsAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
|
|
||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
err = c.PickupGoods(order, model.IsOrderDeliveryByStore(order), userName)
|
|
||||||
if err == nil {
|
|
||||||
order.Status = model.OrderStatusFinishedPickup
|
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
|
|
||||||
globals.SugarLogger.Infof("PickupGoodsAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Infof("PickupGoodsAndUpdateStatus orderID:%s userName:%s error:%v", vendorOrderID, userName, err)
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AdjustOrder(ctx, order, removedSkuList, reason)
|
|
||||||
if err == nil {
|
|
||||||
var skuIDs []string
|
|
||||||
for _, v := range removedSkuList {
|
|
||||||
skuIDs = append(skuIDs, utils.Int2Str(v.SkuID))
|
|
||||||
}
|
|
||||||
noticeMsg := fmt.Sprintf("商品skuID列表:%v,订单号(点击进入详情):%v", strings.Join(skuIDs, ","), globals.BackstageHost+"/#/ordermanager/"+order.VendorOrderID)
|
|
||||||
user, err := dao.GetUserByID(dao.GetDB(), "mobile", "18982250714")
|
|
||||||
if user != nil && err == nil {
|
|
||||||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "调整单调整商品", noticeMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
if globals.IsAddEvent {
|
|
||||||
err = cms.AddEventDetail(dao.GetDB(), ctx, model.OperateUpdate, order.StoreID, model.ThingTypeOrder, order.StoreID, order.VendorOrderID, order.StoreName)
|
|
||||||
}
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).CancelOrder(ctx, order, reason)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AcceptOrRefuseFailedGetOrder(ctx, order, isAcceptIt)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
flag := model.OrderFlagAgreeFailedGetGoods
|
|
||||||
if !isAcceptIt {
|
|
||||||
flag = model.OrderFlagRefuseFailedGetGoods
|
|
||||||
}
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, flag)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CallPMCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).CallCourier(ctx, order)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskCallPMCourier)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).ConfirmReceiveGoods(ctx, order)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskFailedDeliver)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).AgreeOrRefuseCancel(ctx, order, isAcceptIt, reason)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
flag := model.OrderFlagAgreeUserApplyCancel
|
|
||||||
if !isAcceptIt {
|
|
||||||
flag = model.OrderFlagRefuseUserApplyCancel
|
|
||||||
}
|
|
||||||
dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, flag)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) CancelWaybillByID(ctx *jxcontext.Context, vendorWaybillID string, waybillVendorID int, cancelReasonID int, cancelReason string) (err error) {
|
|
||||||
bill, err := partner.CurOrderManager.LoadWaybill(vendorWaybillID, waybillVendorID)
|
|
||||||
if err == nil {
|
|
||||||
err = c.CancelWaybill(bill, cancelReasonID, cancelReason)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) AgreeOrRefuseRefund(ctx *jxcontext.Context, afsOrderID string, vendorID, approveType int, reason string) (err error) {
|
|
||||||
afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(vendorID).AgreeOrRefuseRefund(ctx, afsOrder, approveType, reason)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
flag := model.AfsOrderFlagAgreeUserRefund
|
|
||||||
if approveType == partner.AfsApproveTypeRefused {
|
|
||||||
flag = model.AfsOrderFlagRefuseUserRefund
|
|
||||||
afsOrder.RefuseReason = reason
|
|
||||||
partner.CurOrderManager.UpdateAfsOrderFields(afsOrder, []string{"RefuseReason"})
|
|
||||||
} else {
|
|
||||||
if order, _ := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); order != nil {
|
|
||||||
if order.EarningType == model.EarningTypePoints {
|
|
||||||
var (
|
|
||||||
skuMap = make(map[int]*model.OrderSku)
|
|
||||||
diff int64
|
|
||||||
db = dao.GetDB()
|
|
||||||
)
|
|
||||||
for _, sku := range order.Skus {
|
|
||||||
skuMap[sku.SkuID] = sku
|
|
||||||
}
|
|
||||||
storeDetail, _ := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID)
|
|
||||||
waybills, _ := dao.GetWaybills(db, order.VendorOrderID)
|
|
||||||
//京东商城和京西要重新算totalshopmoney等
|
|
||||||
if order.VendorID == model.VendorIDJDShop || order.VendorID == model.VendorIDJX {
|
|
||||||
skus, _ := dao.GetAfsOrderSkuInfo(db, order.VendorOrderID, afsOrderID, order.VendorID, false)
|
|
||||||
for _, v := range skus {
|
|
||||||
if skuMap[v.SkuID] != nil {
|
|
||||||
diff += skuMap[v.SkuID].SalePrice * int64(v.Count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
order.TotalShopMoney = utils.Float64TwoInt64(float64(float64(order.TotalShopMoney)/jdshopapi.JdsPayPercentage-float64(diff)) * jdshopapi.JdsPayPercentage)
|
|
||||||
if len(waybills) > 0 {
|
|
||||||
jxutils.RefreshOrderEarningPrice3(order, storeDetail.PayPercentage, waybills[0])
|
|
||||||
} else {
|
|
||||||
jxutils.RefreshOrderEarningPrice2(order, storeDetail.PayPercentage)
|
|
||||||
}
|
|
||||||
dao.UpdateEntity(db, order, "TotalShopMoney", "NewEarningPrice")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dao.SetAfsOrderFlag(dao.GetDB(), ctx.GetUserName(), afsOrderID, vendorID, flag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, afsOrderID string, vendorID int) (err error) {
|
|
||||||
afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, vendorID)
|
|
||||||
if err == nil {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(vendorID).ConfirmReceivedReturnGoods(ctx, afsOrder)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
dao.SetAfsOrderFlag(dao.GetDB(), ctx.GetUserName(), afsOrderID, vendorID, model.AfsOrderFlagMaskReturnGoods)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).PartRefundOrder(ctx, order, refundSkuList, reason)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
|
||||||
if c.IsReallyCallPlatformAPI {
|
|
||||||
err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).RefundOrder(ctx, order, reason)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID string, vendorID int, selfTakeCode string) (err error) {
|
|
||||||
order, err2 := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
err = c.confirmSelfTake(ctx, order, selfTakeCode)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SetOrderWaybillTip(ctx *jxcontext.Context, vendorOrderID string, vendorID int, tipFee int64) (err error) {
|
|
||||||
order, err2 := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
err = c.SetOrderWaybillTipByOrder(ctx, order, tipFee)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWaybillCanAddTip(waybill *model.Waybill) (isCan bool) {
|
|
||||||
isCan = waybill.Status >= model.WaybillStatusNew && waybill.Status < model.WaybillStatusAccepted && partner.GetWaybillTipUpdater(waybill.WaybillVendorID) != nil
|
|
||||||
return isCan
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) SetOrderWaybillTipByOrder(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) {
|
|
||||||
roundTipFee := tipFee / 100 * 100
|
|
||||||
if roundTipFee != tipFee {
|
|
||||||
return fmt.Errorf("小费必须是1元的整数倍")
|
|
||||||
}
|
|
||||||
if order.WaybillTipMoney >= tipFee {
|
|
||||||
return fmt.Errorf("当前小费已经是%s元,想要设置%s元", jxutils.IntPrice2StandardString(order.WaybillTipMoney), jxutils.IntPrice2StandardString(tipFee))
|
|
||||||
}
|
|
||||||
|
|
||||||
db := dao.GetDB()
|
|
||||||
storeDetail, err2 := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID)
|
|
||||||
if err = err2; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果平台支持设置配送小费,必须要成功设置
|
|
||||||
if handler := partner.GetWaybillTipUpdater(order.VendorID); handler != nil {
|
|
||||||
if err = handler.UpdateWaybillTip(ctx, order.VendorOrgCode, order.VendorStoreID, order.VendorOrderID, "", "", utils.Int2Str(storeDetail.CityCode), tipFee); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
order.WaybillTipMoney = tipFee
|
|
||||||
partner.CurOrderManager.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
|
||||||
|
|
||||||
waybills, err := dao.GetWayBillByOrderID(db, 0, order.VendorID, 0, order.VendorOrderID)
|
|
||||||
if err == nil {
|
|
||||||
var waybills2 []*model.Waybill
|
|
||||||
for _, v := range waybills {
|
|
||||||
// 必须是三方配送
|
|
||||||
if !model.IsWaybillPlatformOwn(v) && isWaybillCanAddTip(v) {
|
|
||||||
waybills2 = append(waybills2, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(waybills2) > 0 {
|
|
||||||
task := tasksch.NewParallelTask("SetOrderWaybillTipByOrder", nil, ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
waybill := batchItemList[0].(*model.Waybill)
|
|
||||||
handler := partner.GetWaybillTipUpdater(waybill.WaybillVendorID)
|
|
||||||
if err == nil {
|
|
||||||
err = handler.UpdateWaybillTip(ctx, waybill.VendorOrgCode, storeDetail.VendorStoreID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2, utils.Int2Str(storeDetail.CityCode), tipFee)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}, waybills2)
|
|
||||||
tasksch.HandleTask(task, nil, false).Run()
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) confirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
|
|
||||||
globals.SugarLogger.Debugf("confirmSelfTake orderID:%s, selfTakeCode:%s", order.VendorOrderID, selfTakeCode)
|
|
||||||
vendorID := order.VendorID
|
|
||||||
if vendorID == model.VendorIDJD || vendorID == model.VendorIDJX {
|
|
||||||
if vendorID == model.VendorIDJD {
|
|
||||||
if selfTakeCode == autoSelfTakeCode {
|
|
||||||
if selfTakeCode, err = jd.CurPurchaseHandler.GetSelfTakeCode(ctx, order); err != nil {
|
|
||||||
return fmt.Errorf("获取订单:%s自提货码失败,原始错误:%s", order.VendorOrderID, err.Error())
|
|
||||||
}
|
|
||||||
if selfTakeCode == "" {
|
|
||||||
return fmt.Errorf("订单:%s看起来不是一个自提订单,如果确认是自提订单,请联系开发", order.VendorOrderID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = jd.CurPurchaseHandler.ConfirmSelfTake(ctx, order, selfTakeCode)
|
|
||||||
} else {
|
|
||||||
orderStatus := &model.OrderStatus{
|
|
||||||
VendorOrderID: order.VendorOrderID,
|
|
||||||
VendorID: model.VendorIDJX,
|
|
||||||
OrderType: model.OrderTypeOrder,
|
|
||||||
RefVendorOrderID: order.VendorOrderID,
|
|
||||||
RefVendorID: model.VendorIDJX,
|
|
||||||
VendorStatus: utils.Int2Str(model.OrderStatusFinished),
|
|
||||||
Status: model.OrderStatusFinished,
|
|
||||||
StatusTime: time.Now(),
|
|
||||||
Remark: "自提完成",
|
|
||||||
}
|
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
|
||||||
err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus)
|
|
||||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("自提核销不支持%s平台订单", model.VendorChineseNames[order.VendorID])
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *BaseScheduler) ConfirmSelfTakeOrders(ctx *jxcontext.Context, vendorIDs []int, orderCreatedAfter, orderCreatedBefore time.Time, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
orderList, err := dao.GetPendingFakeOrders(dao.GetDB(), vendorIDs, orderCreatedAfter, orderCreatedBefore)
|
|
||||||
if err == nil {
|
|
||||||
if len(orderList) > 0 {
|
|
||||||
task := tasksch.NewParallelTask(fmt.Sprintf("自动完成内部自提单%v,%s", vendorIDs, utils.Time2Str(orderCreatedAfter)), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
order := batchItemList[0].(*model.GoodsOrder)
|
|
||||||
if order.Status == model.OrderStatusAccepted {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
err = handler.AcceptOrRefuseOrder(order, true, ctx.GetUserName())
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if err = c.confirmSelfTake(ctx, order, autoSelfTakeCode); err == nil {
|
|
||||||
retVal = []int{1}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal, err
|
|
||||||
}, orderList)
|
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
if isAsync {
|
|
||||||
hint = task.GetID()
|
|
||||||
} else {
|
|
||||||
resultList, err2 := task.GetResult(0)
|
|
||||||
if err = err2; err == nil {
|
|
||||||
hint = utils.Int2Str(len(resultList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hint, err
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,59 +0,0 @@
|
|||||||
package defsch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
||||||
push "git.rosy.net.cn/jx-callback/business/jxutils/unipush"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/msghub"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
autoRejectSkuMap = map[int]int{
|
|
||||||
33996: 1,
|
|
||||||
33995: 1,
|
|
||||||
33994: 1,
|
|
||||||
33991: 1,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *DefScheduler) OnAfsOrderNew(order *model.AfsOrder, isPending bool) (err error) {
|
|
||||||
if order.Status == model.AfsOrderStatusWait4Approve {
|
|
||||||
if !isPending {
|
|
||||||
if isAutoRejectAfsOrder(order) {
|
|
||||||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
|
||||||
if err := handler.AgreeOrRefuseRefund(jxcontext.AdminCtx, order, partner.AfsApproveTypeRefused, "抱歉,蟹券不接受退货或换货"); err != nil {
|
|
||||||
globals.SugarLogger.Debugf("OnAfsOrderNew, orderID:%s, afsOrderID:%s failed with err:%v", order.VendorOrderID, order.AfsOrderID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msghub.OnNewWait4ApproveAfsOrder(order)
|
|
||||||
weixinmsg.NotifyAfsOrderStatus(order)
|
|
||||||
push.NotifyAfsOrder(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) OnAfsOrderStatusChanged(order *model.AfsOrder, status *model.OrderStatus, isPending bool) (err error) {
|
|
||||||
if status.Status == model.AfsOrderStatusWait4ReceiveGoods {
|
|
||||||
if !isPending {
|
|
||||||
msghub.OnKeyAfsOrderStatusChanged(order)
|
|
||||||
weixinmsg.NotifyAfsOrderStatus(order)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func isAutoRejectAfsOrder(order *model.AfsOrder) (isReject bool) {
|
|
||||||
for _, v := range order.Skus {
|
|
||||||
if autoRejectSkuMap[jxutils.GetSkuIDFromOrderSkuFinancial(v)] == 1 {
|
|
||||||
isReject = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isReject
|
|
||||||
}
|
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
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))
|
|
||||||
}
|
|
||||||
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)}, 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
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package scheduler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
StoreDeliveryTypeCrowdSourcing = 0 //缺省,平台众包配送,可转自送
|
|
||||||
StoreDeliveryTypeByPlatform = 1 //平台专送
|
|
||||||
StoreDeliveryTypeByStore = 2 //完全门店自送,这个表示的意思是平台的门店属性(就是购物平台不负责配送),而不是真正是否是老板自己送
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
TimerStatusTypeUnknown = -1
|
|
||||||
TimerStatusTypeOrder = 0
|
|
||||||
TimerStatusTypeWaybill = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
CurrentScheduler IScheduler
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrOrderStatusIsNotSuitable4CurOperation = errors.New("订单锁定或状态不适合当前操作")
|
|
||||||
ErrOrderStatusAlreadySatisfyCurOperation = errors.New("订单当前状态已满足当前操作")
|
|
||||||
|
|
||||||
ErrCanNotCreateAtLeastOneWaybill = errors.New("一个运单都不能创建")
|
|
||||||
ErrCanNotFindOrder = errors.New("不能找到订单(一般是由于事件错序)")
|
|
||||||
ErrCanNotFindWaybill = errors.New("不能找到运单(一般是由于事件错序)")
|
|
||||||
ErrOrderIsNotSolid = errors.New("订单是临时订单,不完整,不能用于创建运单")
|
|
||||||
ErrDeliverProviderWrong = errors.New("快递商不存在或不能用于创建运单")
|
|
||||||
)
|
|
||||||
|
|
||||||
type IScheduler interface {
|
|
||||||
// 以下是订单
|
|
||||||
OnOrderNew(order *model.GoodsOrder, isPending bool) (err error)
|
|
||||||
OnOrderStatusChanged(order *model.GoodsOrder, status *model.OrderStatus, isPending bool) (err error)
|
|
||||||
|
|
||||||
// 以下是运单
|
|
||||||
OnWaybillStatusChanged(bill *model.Waybill, isPending bool) (err error)
|
|
||||||
|
|
||||||
// 以下是售后单
|
|
||||||
OnAfsOrderNew(order *model.AfsOrder, isPending bool) (err error)
|
|
||||||
OnAfsOrderStatusChanged(order *model.AfsOrder, status *model.OrderStatus, isPending bool) (err error)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user