282 lines
14 KiB
Go
282 lines
14 KiB
Go
package basesch
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
|
||
tiktokShop "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||
"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/jxcontext"
|
||
"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 (
|
||
ctx *jxcontext.Context
|
||
)
|
||
var (
|
||
FixedBaseScheduler *BaseScheduler
|
||
)
|
||
|
||
type BaseScheduler struct {
|
||
IsReallyCallPlatformAPI bool
|
||
}
|
||
|
||
func (c *BaseScheduler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
||
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
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *BaseScheduler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
||
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
|
||
} else {
|
||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *BaseScheduler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
||
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
|
||
} else {
|
||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *BaseScheduler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
|
||
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
|
||
} else {
|
||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *BaseScheduler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
||
if order.Status == model.OrderStatusFinishedPickup {
|
||
if c.IsReallyCallPlatformAPI {
|
||
err = utils.CallFuncLogError(func() error {
|
||
// 下面这个写法暂存,可能会有问题
|
||
if order.VendorID == model.VendorIDMTWM {
|
||
// 转自送同时取消平台订单(美团才做这个操作)
|
||
if _, err := partner.GetPurchasePlatformFromVendorID(order.VendorID).GetCancelDeliveryReason(order); err != nil {
|
||
partner.CurOrderManager.OnOrderMsg(order, "订单转自送取消美团平台发单获取理由失败", err.Error())
|
||
}
|
||
// 取消美团外卖配送,转自送
|
||
if err = partner.GetPurchasePlatformFromVendorID(order.VendorID).CancelLogisticsByWmOrderId(order, "101512", "已选择其他配送方式", order.VendorStoreID, order.VendorOrderID); err != nil {
|
||
partner.CurOrderManager.OnOrderMsg(order, "取消美团外卖,转用三方配送", err.Error())
|
||
}
|
||
// 查询订单状态,
|
||
orderStatus, _ := partner.GetPurchasePlatformFromVendorID(order.VendorID).OrderLogisticsStatus(order.VendorOrderID)
|
||
status := 0
|
||
if orderStatus != nil {
|
||
status = orderStatus.LogisticsStatus
|
||
}
|
||
if status == 100 { // 美团取消配送单
|
||
partner.CurOrderManager.OnOrderMsg(order, "美团外卖转自送成功.", "")
|
||
return nil
|
||
} else if strings.Contains(err.Error(), "包裹不存在") || strings.Contains(err.Error(), "运单不存在") || strings.Contains(err.Error(), "1071") || strings.Contains(err.Error(), "1014") || strings.Contains(err.Error(), "invalid character 'o' looking for beginning of value") {
|
||
partner.CurOrderManager.OnOrderMsg(order, "美团外卖转自送可能成功,异常:", err.Error())
|
||
err = nil
|
||
return nil
|
||
} else if strings.Contains(err.Error(), "商家没有接入众包配送,无法进行众包配送相关操作") {
|
||
partner.CurOrderManager.OnOrderMsg(order, "商家无配送设置,转配送成功", err.Error())
|
||
err = nil
|
||
} else if strings.Contains(err.Error(), "无需重复取消") {
|
||
partner.CurOrderManager.OnOrderMsg(order, "商家无配送设置,转配送成功", err.Error())
|
||
err = nil
|
||
} else {
|
||
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
||
err = c.CancelWaybill(bill, partner.CancelWaybillReasonOther, userName+":5"+partner.CancelWaybillReasonStrActive)
|
||
partner.CurOrderManager.OnOrderMsg(order, "美团外卖运单无法取消,", err.Error())
|
||
return err
|
||
}
|
||
} else if order.VendorID == model.VendorIDDD { //抖音配送
|
||
localBill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
||
// 获取抖音配送状态
|
||
tiktokWayBillStatus, err2 := partner.GetPurchasePlatformFromVendorID(order.VendorID).OrderLogisticsStatus(order.VendorOrderID)
|
||
if tiktokWayBillStatus != nil && tiktokWayBillStatus.LogisticsStatus >= tiktokShop.ShipmentStatusReceived && tiktokWayBillStatus.LogisticsStatus != tiktokShop.ShipmentStatusCanceled {
|
||
//取消抖音配送转自送
|
||
err = c.CancelWaybill(localBill, partner.CancelWaybillReasonDYPSCancel, partner.CancelWaybillReasonStrDYPSCancel+"抖音骑手已经接单,无法取消6")
|
||
partner.CurOrderManager.OnOrderMsg(order, "取消抖音配送,转用门店自配送/三方配送", "抖音骑手已经接单,无法取消")
|
||
return err
|
||
} else if tiktokWayBillStatus != nil && tiktokWayBillStatus.LogisticsStatus == -1 { // 先转自送,自送不成功取消平台配送.
|
||
if err := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivering(order, userName); err != nil {
|
||
partner.CurOrderManager.OnOrderMsg(order, "抖音转自送,平台无运力", "tiktokWayBillStatus = -1")
|
||
}
|
||
} else if (err2 != nil && strings.Contains(err2.Error(), "当前状态获取不到运力信息")) || (tiktokWayBillStatus != nil && tiktokWayBillStatus.LogisticsStatus == tiktokShop.ShipmentStatusCanceled) {
|
||
partner.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelivering(order, "")
|
||
} else if err = partner.GetPurchasePlatformFromVendorID(order.VendorID).CancelLogisticsByWmOrderId(order, "", "", order.VendorStoreID, order.VendorOrderID); err != nil {
|
||
partner.CurOrderManager.OnOrderMsg(order, "取消抖音配送异常:", err.Error())
|
||
if err = c.CancelWaybill(localBill, partner.CancelWaybillReasonDYPSCancel, partner.CancelWaybillReasonStrDYPSCancel+"7"); err != nil {
|
||
partner.CurOrderManager.OnOrderMsg(order, "取消抖音平台运单错误,无法转自送", err.Error())
|
||
return err
|
||
}
|
||
} else {
|
||
partner.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelivering(order, "")
|
||
}
|
||
} else {
|
||
if err := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivering(order, userName); err != nil && (err != scheduler.ErrOrderStatusAlreadySatisfyCurOperation) {
|
||
partner.CurOrderManager.OnOrderMsg(order, "SelfDeliverDelivering 调用[SelfDeliverDelivering]转自送", err.Error())
|
||
return err
|
||
}
|
||
}
|
||
return err
|
||
}, "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
|
||
} else {
|
||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *BaseScheduler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
||
if order.Status >= model.OrderStatusFinishedPickup && order.Status <= model.OrderStatusDelivering {
|
||
if c.IsReallyCallPlatformAPI {
|
||
err = utils.CallFuncLogError(func() error {
|
||
if err = partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivered(order, userName); err == nil {
|
||
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
||
if bill != nil && bill.WaybillVendorID != model.VendorJXFakeWL && bill.WaybillVendorID != model.VendorIDUnknown {
|
||
c.CancelWaybill(bill, partner.CancelWaybillReasonOther, userName+":"+partner.CancelWaybillReasonStrActive+"8")
|
||
}
|
||
}
|
||
return err
|
||
}, "SelfDeliverDelivered orderID:%s", order.VendorOrderID)
|
||
}
|
||
} else {
|
||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusDelivering {
|
||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
||
} else {
|
||
err = scheduler.ErrOrderStatusAlreadySatisfyCurOperation
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *BaseScheduler) CreateWaybill(platformVendorID int, order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
|
||
if !model.IsOrderSolid(order) { // 如果订单是不完整的
|
||
return nil, scheduler.ErrOrderIsNotSolid
|
||
}
|
||
|
||
storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, order.VendorOrgCode)
|
||
var balance int
|
||
|
||
// 门店发单,如果是京西门店,直接使用京西余额,非京西门店使用门店余额,余额不足使用品牌余额!
|
||
if order.CreateDeliveryType == model.YES {
|
||
storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order)) // 获取门店余额
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
balance = storeAcct.AccountBalance
|
||
} else {
|
||
balance, _ = partner.CurStoreAcctManager.GetBrandBalance(storeDetail.BrandID)
|
||
}
|
||
|
||
handlerInfo := partner.GetDeliveryPlatformFromVendorID(platformVendorID)
|
||
if handlerInfo != nil && handlerInfo.Use4CreateWaybill {
|
||
if _, ok := model.DeliveryBrandMarkMap[platformVendorID]; ok && storeDetail.BrandIsOpen != 0 && balance >= model.BrandBalanceLimit {
|
||
if c.IsReallyCallPlatformAPI {
|
||
// 如果门店是美团服务商且订单为美团订单
|
||
if storeDetail.IsService == model.YES && order.VendorID == model.VendorIDMTWM {
|
||
err = fmt.Errorf("京西ID:[%d],平台id[%s],平台[美团]:错误:[%s]", storeDetail.Store.ID, storeDetail.VendorStoreID, "此门店美团平台为服务商模式,不支持本系统提供的三方配送![仅美团,其余平台订单正常使用.]")
|
||
} else {
|
||
if order.VendorID == model.VendorIDEBAI && strings.Contains(order.ConsigneeAddress, EBaiOrderAddressHide) {
|
||
return nil, fmt.Errorf("由于饿了么用户数据隐私保护,发三方配送前请先将订单转为自配送,获取详情地址")
|
||
}
|
||
// 生成三方运单
|
||
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 = fmt.Errorf("创建运单是门店余额不足十元,无法创建运单")
|
||
}
|
||
} else {
|
||
err = scheduler.ErrDeliverProviderWrong
|
||
}
|
||
return bill, err
|
||
}
|
||
|
||
func (c *BaseScheduler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
||
// 部分快递平台在取消成功后有时会不发运单取消消息过来(比如达达,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 {
|
||
if err := handlerInfo.Handler.CancelWaybill(bill, cancelReasonID, cancelReason+"9"); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}, "CancelWaybill bill:%v", bill); err == nil {
|
||
bill.Status = model.WaybillStatusCanceled
|
||
bill.DeliveryFlag |= model.WaybillDeliveryFlagMaskActiveCancel
|
||
_, err = dao.UpdateEntity(nil, bill, "Status", "DeliveryFlag")
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
}
|