Files
jx-callback/business/partner/purchase/jd/order.go
2019-02-15 17:53:22 +08:00

267 lines
10 KiB
Go

package jd
import (
"strings"
"time"
"git.rosy.net.cn/baseapi/platformapi/autonavi"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"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/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
var (
VendorStatus2StatusMap = map[string]int{
jdapi.OrderStatusPurchased: model.OrderStatusNew,
jdapi.OrderStatusNew: model.OrderStatusNew,
jdapi.OrderStatusAdjust: model.OrderStatusNew,
jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted,
jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup,
jdapi.OrderStatusDelivering: model.OrderStatusDelivering,
jdapi.OrderStatusDelivered: model.OrderStatusDelivered,
jdapi.OrderStatusFinished: model.OrderStatusFinished,
jdapi.OrderStatusCanceled: model.OrderStatusCanceled,
jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel,
jdapi.OrderStatusLocked: model.OrderStatusLocked,
jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked,
}
)
func (c *PurchaseHandler) OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
jxutils.CallMsgHandler(func() {
retVal = c.onOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD))
return retVal
}
func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
if jdapi.OrderStatusNew == msg.StatusID {
retVal = c.onOrderNew(msg)
} else if jdapi.OrderStatusAdjust == msg.StatusID {
retVal = c.onOrderAdjust(msg)
} else {
status := c.callbackMsg2Status(msg)
if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment {
if globals.ReallyCallPlatformAPI {
c.onOrderComment(msg)
}
}
err := partner.CurOrderManager.OnOrderStatusChanged(status)
// if globals.HandleLegacyJxOrder && err == nil {
// c.legacyJdOrderStatusChanged(status)
// }
retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus)
}
return retVal
}
func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err error) {
globals.SugarLogger.Debugf("jd GetOrder orderID:%s", orderID)
var (
result map[string]interface{}
result2 string
err2 error
)
task := tasksch.NewParallelTask("jd GetOrder", nil, "admin", func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
taskIndex := batchItemList[0].(int)
switch taskIndex {
case 0:
result, err = api.JdAPI.QuerySingleOrder(orderID)
case 1:
result2, err2 = api.JdAPI.GetRealMobile4Order(orderID)
}
return nil, nil
}, []int{0, 1})
task.Run()
task.GetResult(0)
if err == nil {
order = c.Map2Order(result)
if err2 == nil {
order.ConsigneeMobile2 = result2
} else {
// globals.SugarLogger.Warnf("jd GetOrder orderID:%s, GetRealMobile4Order failed with error:%v", orderID, err2)
}
}
return order, err
}
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
result := orderData
orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"]))
order = &model.GoodsOrder{
VendorOrderID: orderID,
VendorID: model.VendorIDJD,
VendorStoreID: utils.Interface2String(result["produceStationNo"]),
StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["produceStationNoIsv"]), 0)),
StoreName: utils.Interface2String(result["produceStationName"]),
ConsigneeName: utils.Interface2String(result["buyerFullName"]),
ConsigneeMobile: utils.Interface2String(result["buyerMobile"]),
ConsigneeAddress: utils.Interface2String(result["buyerFullAddress"]),
CoordinateType: model.CoordinateTypeMars,
BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["orderBuyerRemark"])),
ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["orderPreEndDeliveryTime"]), utils.DefaultTimeValue),
PickDeadline: utils.Str2Time(result["pickDeadline"].(string)),
VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["orderStatus"])),
OrderSeq: int(utils.MustInterface2Int64(result["orderNum"])),
StatusTime: utils.Str2Time(result["orderPurchaseTime"].(string)),
OriginalData: string(utils.MustMarshal(result)),
ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]),
Skus: []*model.OrderSku{},
}
order.Status = c.GetStatusFromVendorStatus(order.VendorStatus)
businessTage := utils.Interface2String(result["businessTag"])
if strings.Index(businessTage, "dj_aging_immediately") >= 0 {
order.BusinessType = model.BusinessTypeImmediate
} else {
order.BusinessType = model.BusinessTypeDingshida
}
coordinateType := utils.Interface2Int64WithDefault(result["buyerCoordType"], 1)
originalLng := utils.MustInterface2Float64(result["buyerLng"])
originalLat := utils.MustInterface2Float64(result["buyerLat"])
if coordinateType == 1 {
lng, lat, err2 := api.AutonaviAPI.CoordinateConvert(originalLng, originalLat, autonavi.CoordSysGPS)
if err2 == nil {
originalLng = lng
originalLat = lat
} else {
// 如果没有转成功,保留原始数据
order.CoordinateType = model.CoordinateTypeGPS
}
}
order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng)
order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat)
// discounts := result["discount"].(map[string]interface{})
for _, product2 := range result["product"].([]interface{}) {
product := product2.(map[string]interface{})
sku := &model.OrderSku{
VendorOrderID: orderID,
VendorID: model.VendorIDJD,
Count: int(utils.MustInterface2Int64(product["skuCount"])),
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["skuIdIsv"]), 0)),
VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])),
SkuName: product["skuName"].(string),
Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(product["skuWeight"]))),
SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]),
PromotionType: int(utils.MustInterface2Int64(product["promotionType"])),
}
if skuCostumeProperty, ok := product["skuCostumeProperty"]; ok {
sku.SkuName += skuCostumeProperty.(string)
}
if product["isGift"].(bool) {
sku.SkuType = 1
}
order.Skus = append(order.Skus, sku)
order.SkuCount++
order.GoodsCount += sku.Count
order.SalePrice += sku.SalePrice * int64(sku.Count)
order.Weight += sku.Weight * sku.Count
}
setOrederDetailFee(result, order)
return order
}
func setOrederDetailFee(result map[string]interface{}, order *model.GoodsOrder) {
order.BoxFee = utils.MustInterface2Int64(result["packagingMoney"])
order.PlatformFeeRate = model.JdPlatformFeeRate
order.BillStoreFreightFee = utils.MustInterface2Int64(result["merchantPaymentDistanceFreightMoney"]) + utils.MustInterface2Int64(result["tips"])
}
//
func (c *PurchaseHandler) onOrderNew(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) {
order, err := c.GetOrder(msg.BillID)
if err == nil {
err = partner.CurOrderManager.OnOrderNew(order, msg.StatusID)
// if err == nil {
// c.legacyWriteJdOrder(order, false)
// }
}
return jdapi.Err2CallbackResponse(err, "jd onOrderNew")
}
func (c *PurchaseHandler) onOrderAdjust(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse {
order, err := c.GetOrder(msg.BillID)
if err == nil {
err = partner.CurOrderManager.OnOrderAdjust(order, msg.StatusID)
// if globals.HandleLegacyJxOrder && err == nil {
// c.legacyWriteJdOrder(order, true)
// }
}
return jdapi.Err2CallbackResponse(err, "jd onOrderAdjust")
}
func (c *PurchaseHandler) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.BillID,
VendorID: model.VendorIDJD,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.BillID,
RefVendorID: model.VendorIDJD,
VendorStatus: msg.StatusID,
Status: c.GetStatusFromVendorStatus(msg.StatusID),
StatusTime: utils.Str2Time(msg.Timestamp),
Remark: msg.Remark,
}
return orderStatus
}
// IPurchasePlatformHandler
func (c *PurchaseHandler) GetStatusFromVendorStatus(vendorStatus string) int {
if status, ok := VendorStatus2StatusMap[vendorStatus]; ok {
return status
}
return model.OrderStatusUnknown
}
func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
return api.JdAPI.OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName)
}
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, userName string) (err error) {
_, err = api.JdAPI.OrderJDZBDelivery(order.VendorOrderID, userName)
return err
}
func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
_, err = api.JdAPI.ModifySellerDelivery(order.VendorOrderID, userName)
if err != nil {
if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 {
globals.SugarLogger.Infof("Swtich2SelfDeliver failed with error:%v try get current status", err)
if order2, err2 := c.GetOrder(order.VendorOrderID); err2 == nil {
var mapData map[string]interface{}
if err2 = utils.UnmarshalUseNumber([]byte(order2.OriginalData), &mapData); err2 == nil {
if utils.Interface2String(mapData["deliveryCarrierNo"]) == "2938" { // 当前已经是自送状态了
err = nil
}
}
}
}
}
return err
}
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
_, err = api.JdAPI.DeliveryEndOrder(order.VendorOrderID, userName)
return err
}
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
_, err = api.JdAPI.OrderSerllerDelivery(order.VendorOrderID, userName)
return err
}
// 京东送达接口都是一样的
func (c *PurchaseHandler) SelfDeliverDelievered(order *model.GoodsOrder, userName string) (err error) {
return c.Swtich2SelfDelivered(order, userName)
}
func (c *PurchaseHandler) RefreshRealMobile(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) {
return hint, err
}