Files
jx-callback/business/jxcallback/scheduler/basesch/basesch.go
邹宗楠 36c35ea717 1
2023-12-15 16:33:26 +08:00

278 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 {
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
err = c.CancelWaybill(bill, partner.CancelWaybillReasonOther, 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+"抖音骑手已经接单,无法取消")
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); 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.LockStatus == model.OrderStatusUnknown && */ 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.WaybillVendorID != model.VendorJXFakeWL {
c.CancelWaybill(bill, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
}
}
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 {
// 生成三方运单
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); 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
}