Files
jx-callback/business/partner/purchase/ebai/order.go
gazebo 4fbfcdb13e - model.WaybillStatusNeverSend
- try to set ebai sku weight
2018-11-27 10:27:32 +08:00

295 lines
12 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 ebai
import (
"encoding/json"
"math"
"time"
"git.rosy.net.cn/baseapi/platformapi/autonavi"
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
"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"
"git.rosy.net.cn/jx-callback/globals/api"
)
const (
acceptOrderDelay = 270 * time.Second
fakePickedUp = "9527"
)
var (
VendorStatus2StatusMap = map[string]int{
ebaiapi.OrderStatusNew: model.OrderStatusNew,
ebaiapi.OrderStatusAccepted: model.OrderStatusAccepted,
fakePickedUp: model.OrderStatusFinishedPickup,
ebaiapi.OrderStatusCourierAccepted: model.OrderStatusDelivering,
ebaiapi.OrderStatusCourierPickedup: model.OrderStatusDelivering,
ebaiapi.OrderStatusFinished: model.OrderStatusFinished,
ebaiapi.OrderStatusCanceled: model.OrderStatusCanceled,
}
)
func (p *PurchaseHandler) GetStatusFromVendorStatus(vendorStatus string) int {
if status, ok := VendorStatus2StatusMap[vendorStatus]; ok {
return status
}
return model.OrderStatusUnknown
}
func (p *PurchaseHandler) GetOrder(vendorOrderID string) (order *model.GoodsOrder, err error) {
result, err := api.EbaiAPI.OrderGet(vendorOrderID)
// globals.SugarLogger.Info(result)
if err == nil {
shopMap := result["shop"].(map[string]interface{})
orderMap := result["order"].(map[string]interface{})
userMap := result["user"].(map[string]interface{})
order = &model.GoodsOrder{
VendorOrderID: vendorOrderID,
VendorOrderID2: orderMap["eleme_order_id"].(string),
VendorID: model.VendorIDEBAI,
VendorStoreID: shopMap["baidu_shop_id"].(string),
StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(shopMap["id"]), 0)),
StoreName: shopMap["name"].(string),
ConsigneeName: userMap["name"].(string),
ConsigneeMobile: userMap["phone"].(string),
ConsigneeAddress: userMap["address"].(string),
CoordinateType: model.CoordinateTypeBaiDu,
BuyerComment: utils.TrimBlankChar(utils.Interface2String(orderMap["remark"])),
ExpectedDeliveredTime: getTimeFromTimestampStr(utils.Interface2String(orderMap["send_time"])),
VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(orderMap["status"])),
OrderSeq: int(utils.Str2Int64(utils.Interface2String(orderMap["order_index"]))),
StatusTime: getTimeFromTimestampStr(utils.Interface2String(orderMap["create_time"])),
OriginalData: string(utils.MustMarshal(result)),
ActualPayPrice: utils.MustInterface2Int64(orderMap["user_fee"]),
Skus: []*model.OrderSku{},
}
if jxutils.IsMobileFake(order.ConsigneeMobile) {
if mobileInfo, err := api.EbaiAPI.OrderPrivateInfo(vendorOrderID); err == nil {
order.ConsigneeMobile = mobileInfo.ShortNumber
}
}
if order.StoreID > math.MaxInt32 {
order.StoreID = 0
}
order.Status = p.GetStatusFromVendorStatus(order.VendorStatus)
if utils.MustInterface2Int64(orderMap["send_immediately"]) == 1 {
order.BusinessType = model.BusinessTypeImmediate
} else {
order.BusinessType = model.BusinessTypeDingshida
}
deliveryGeo := userMap["coord"].(map[string]interface{})
originalLng := utils.MustInterface2Float64(deliveryGeo["longitude"])
originalLat := utils.MustInterface2Float64(deliveryGeo["latitude"])
lng, lat, err2 := api.AutonaviAPI.CoordinateConvert(originalLng, originalLat, autonavi.CoordSysBaidu)
if err2 == nil {
originalLng = lng
originalLat = lat
order.CoordinateType = model.CoordinateTypeMars
}
order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng)
order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat)
products := result["products"].([]interface{})[0].([]interface{})
// discounts := result["discount"].(map[string]interface{})
for _, product2 := range products {
product := product2.(map[string]interface{})
skuName := product["product_name"].(string)
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName)
sku := &model.OrderSku{
VendorOrderID: order.VendorOrderID,
VendorID: model.VendorIDEBAI,
Count: int(utils.MustInterface2Int64(product["product_amount"])),
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["custom_sku_id"]), 0)),
VendorSkuID: utils.Interface2String(product["baidu_product_id"]),
SkuName: skuName,
Weight: jxutils.FormatSkuWeight(specQuality, specUnit), // 订单信息里没有重量,只有名字里尝试找
SalePrice: utils.MustInterface2Int64(product["product_price"]),
// PromotionType: int(utils.MustInterface2Int64(product["promotionType"])),
}
if sku.Weight == 0 {
sku.Weight = 222 // 如果名字里找不到缺省给半斤左右的一个特别值
}
// 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, err
}
func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
globals.SugarLogger.Debugf("ebai AcceptOrRefuseOrder orderID:%s", order.VendorOrderID)
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
if isAcceptIt {
err = api.EbaiAPI.OrderConfirm(order.VendorOrderID)
} else {
err = api.EbaiAPI.OrderCancel(order.VendorOrderID, ebaiapi.CancelTypeCustom, "bu")
}
}
return err
}
func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, userName string) (err error) {
globals.SugarLogger.Debugf("ebai PickupGoods orderID:%s", order.VendorOrderID)
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
err = api.EbaiAPI.OrderCallDelivery(order.VendorOrderID)
}
p.postFakeFinishedPickupMsg(order.VendorOrderID) // 饿百没有拣货完成事件,模拟发送
return err
}
// 将订单从购物平台配送转为自送
func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
globals.SugarLogger.Debugf("ebai Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
err = api.EbaiAPI.OrderSwitchselfdelivery(order.VendorOrderID)
}
return err
}
// 将订单从购物平台配送转为自送后又送达
func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
globals.SugarLogger.Debugf("ebai Swtich2SelfDelivered orderID:%s", order.VendorOrderID)
// todo 饿百转商家自送后,没有确认送达的概念,空操作
return err
}
// 完全自送的门店表示开始配送
func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
globals.SugarLogger.Debugf("ebai SelfDeliverDelivering orderID:%s", order.VendorOrderID)
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
err = api.EbaiAPI.OrderSendOut(order.VendorOrderID, userName)
}
return err
}
// 完全自送的门店表示配送完成
func (p *PurchaseHandler) SelfDeliverDelievered(order *model.GoodsOrder, userName string) (err error) {
globals.SugarLogger.Debugf("ebai SelfDeliverDelievered orderID:%s", order.VendorOrderID)
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
err = api.EbaiAPI.OrderComplete(order.VendorOrderID, userName)
}
return err
}
//
func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) {
if ebaiapi.CmdOrderCreate == msg.Cmd {
retVal = c.onOrderNew(msg)
} else {
status := c.callbackMsg2Status(msg)
if status != nil {
err := partner.CurOrderManager.OnOrderStatusChanged(status)
// 如果订单所属的门店是专送模式,直接跳到拣货完成,因为饿百没有拣货完成的概念,接单就视为拣货完成
if status.Status == model.OrderStatusAccepted {
postFakeFinishedPickupMsg := true
vendorOrderID := GetOrderIDFromMsg(msg)
if order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDEBAI); err == nil {
if c.getOrderStoreDeliveryType(order) != scheduler.StoreDeliveryTypeByPlatform {
postFakeFinishedPickupMsg = false
}
}
if postFakeFinishedPickupMsg {
c.postFakeFinishedPickupMsg(vendorOrderID)
}
}
retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil)
} else {
retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, nil, nil)
}
}
return retVal
}
func (c *PurchaseHandler) onOrderNew(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) {
vendorOrderID := GetOrderIDFromMsg(msg)
order, err := c.GetOrder(vendorOrderID)
if err == nil {
err = partner.CurOrderManager.OnOrderNew(order, order.VendorStatus)
}
return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, map[string]interface{}{
"source_order_id": vendorOrderID,
})
}
func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderStatus *model.OrderStatus) {
if status, ok := msg.Body["status"]; ok {
vendorStatus := utils.Int64ToStr(utils.MustInterface2Int64(status))
orderID := GetOrderIDFromMsg(msg)
orderStatus = &model.OrderStatus{
VendorOrderID: orderID,
VendorID: model.VendorIDEBAI,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: orderID,
RefVendorID: model.VendorIDEBAI,
VendorStatus: vendorStatus,
Status: c.GetStatusFromVendorStatus(vendorStatus),
StatusTime: utils.Timestamp2Time(msg.Timestamp),
Remark: utils.Interface2String(msg.Body["reason"]),
}
} else {
globals.SugarLogger.Infof("ebai callbackMsg2Status can not find status field in msg:%s", utils.Format4Output(msg, false))
}
return orderStatus
}
func (c *PurchaseHandler) GetStatusActionTimeout(statusType, status int) time.Duration {
if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusNew {
return acceptOrderDelay // 饿百开了专送店的订单没有拣货状态,接单后就为拣货完成,所以要延迟接单,否则门店来不及备货
}
return 0
}
func (c *PurchaseHandler) getOrderStoreDeliveryType(order *model.GoodsOrder) (deliveryType int) {
sql := `
SELECT *
FROM store_map t1
WHERE t1.vendor_store_id = ?
AND t1.vendor_id = ?
AND t1.deleted_at = ?
`
db := dao.GetDB()
var storeMap *model.StoreMap
if err := dao.GetRow(db, &storeMap, sql, order.VendorStoreID, model.VendorIDEBAI, utils.DefaultTimeValue); err == nil {
return int(storeMap.DeliveryType)
} else if !dao.IsNoRowsError(err) {
globals.SugarLogger.Warnf("getOrderStoreDeliveryType orderID:%s failed with error:%v", order.VendorOrderID, err)
}
return scheduler.StoreDeliveryTypeByPlatform
}
func (c *PurchaseHandler) postFakeFinishedPickupMsg(vendorOrderID string) {
msg := &ebaiapi.CallbackMsg{
Cmd: ebaiapi.CmdOrderStatus,
Timestamp: time.Now().Unix(),
Body: map[string]interface{}{
"status": json.Number(fakePickedUp), // json.Number实际是string
"order_id": vendorOrderID,
},
}
go func() {
OnCallbackMsg(msg)
}()
}
func getTimeFromTimestampStr(sendTime string) time.Time {
timeStamp := utils.Str2Int64WithDefault(sendTime, 0)
if timeStamp < 1538103149 { // 立即达订单给的是1而不是空01538103149不是特殊值只是一个任意之前的时间这样写可以处理
return utils.DefaultTimeValue
}
return utils.Timestamp2Time(timeStamp)
}