Files
jx-callback/business/controller/order.go
gazebo 805925ff58 - mtps, dada create waybill
- create legacy jxorder(not finished).
2018-07-14 14:35:51 +08:00

294 lines
9.2 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 controller
import (
"fmt"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/legacy/models"
"github.com/astaxie/beego/orm"
)
// 所有公共接口调用前要求在order里或status中设置合适的Status
type OrderController struct {
orderMap SyncMapWithTimeout
}
func NewOrderManager() *OrderController {
return &OrderController{}
}
func (c *OrderController) OnOrderNew(order *model.GoodsOrder) (err error) {
db := orm.NewOrm()
isDuplicated, err := addOrderOrWaybillStatus(c.order2Status(order), db)
if !isDuplicated {
c.handleAutoAcceptOrder(order.VendorOrderID, order.VendorID, order.ConsigneeMobile, order.StoreID, db, func(isAccept bool) {
// c.purchasePlatformHandlers[order.VendorID].AcceptOrRefuseOrder(order, isAccept)
if isAccept {
order.Status = model.OrderStatusAccepted
} else {
order.Status = model.OrderStatusFailed
}
})
// 忽略查找JX信息错误
c.updateOrderOtherInfo(order, db)
db.Begin()
// globals.SugarLogger.Debugf("new order:%v", order)
order.OrderFinishedAt = utils.DefaultTimeValue
order.ID = 0
created, _, err2 := db.ReadOrCreate(order, "VendorOrderID", "VendorID")
if err = err2; err == nil {
c.orderMap.Store(ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), order.ID)
if created {
sql := "INSERT INTO order_sku(vendor_order_id, vendor_id, count, vendor_sku_id, sku_id, jx_sku_id, sku_name, shop_price, sale_price, weight, order_created_at) VALUES"
params := []interface{}{}
for _, sku := range order.Skus {
sql += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?),"
params = append(params, sku.VendorOrderID, sku.VendorID, sku.Count, sku.VendorSkuID, sku.SkuID, sku.JxSkuID, sku.SkuName, sku.ShopPrice, sku.SalePrice, order.Weight, order.OrderCreatedAt)
}
sql = sql[:len(sql)-1] + ";"
if _, err = db.Raw(sql, params...).Exec(); err != nil {
db.Rollback()
baseapi.SugarLogger.Infof("insert order_sku error:%v", err)
} else {
db.Commit()
if globals.HandleLegacyJxOrder {
c.legacyWriteJxOrder(order, db, false)
}
}
} else {
order.DuplicatedCount++
db.Update(order, "DuplicatedCount")
db.Commit()
baseapi.SugarLogger.Infof("duplicated order:%s vendorID:%d, msg received", order.VendorOrderID, order.VendorID)
}
} else {
db.Rollback()
globals.SugarLogger.Warnf("create order:%v, error:%v", order, err)
}
}
return err
}
func (c *OrderController) OnOrderAdjust(order *model.GoodsOrder) (err error) {
db := orm.NewOrm()
isDuplicated, err := addOrderOrWaybillStatus(c.order2Status(order), db)
if err == nil && !isDuplicated {
err = utils.CallFuncLogError(func() error {
_, err = db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
return err
}, "OnAdjustOrder delete order")
if err != nil {
return err
}
err = utils.CallFuncLogError(func() error {
_, err = db.Raw("DELETE FROM goods_order WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
return err
}, "OnAdjustOrder delete order_sku")
if err != nil {
return err
}
}
err = c.OnOrderNew(order)
if globals.HandleLegacyJxOrder && err == nil {
c.legacyWriteJxOrder(order, db, true)
}
return err
}
func (c *OrderController) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
isDuplicated, err := c.addOrderStatus(orderStatus, nil)
if err == nil && !isDuplicated {
if globals.HandleLegacyJxOrder {
c.legacyJxOrderStatusChanged(orderStatus, nil)
}
}
return err
}
// private
func (c *OrderController) updateOrderSkuOtherInfo(orderSkus []*model.OrderSku, db orm.Ormer) (err error) {
var sql string
if orderSkus[0].VendorID == model.VendorIDJD {
sql = `
SELECT t1.jdskuid, t2.id
FROM skumapper t1
JOIN jx_sku t2 ON t1.skuid = t2.id
WHERE t1.jdskuid IN (
`
} else if orderSkus[0].VendorID == model.VendorIDELM {
// 饿了么当前没有存映射关系
return nil
} else {
panic(fmt.Sprintf("wrong vendorid:%d", orderSkus[0].VendorID))
}
jdskuids := []interface{}{}
for _, v := range orderSkus {
sql += "?,"
jdskuids = append(jdskuids, int(utils.Str2Int64(v.VendorSkuID)))
}
sql = sql[:len(sql)-1] + ")"
var lists []orm.ParamsList
if num, err := db.Raw(sql, jdskuids...).ValuesList(&lists); err == nil && num > 0 {
skumapper := make(map[string]string)
for _, v := range lists {
skumapper[v[0].(string)] = v[1].(string)
}
globals.SugarLogger.Debug(skumapper)
for _, v := range orderSkus {
if jxskuid, ok := skumapper[v.VendorSkuID]; ok {
v.JxSkuID = int(utils.Str2Int64(jxskuid))
} else {
globals.SugarLogger.Infof("can not find %v", jxskuid)
}
}
} else {
globals.SugarLogger.Errorf("can not get sku info for vendorID:%d, vendorOrderID:%s, num:%d, error:%v", orderSkus[0].VendorID, orderSkus[0].VendorOrderID, num, err)
}
return err
}
func (c *OrderController) updateOrderOtherInfo(order *model.GoodsOrder, db orm.Ormer) (err error) {
var sql string
if order.VendorID == model.VendorIDJD {
sql = `
SELECT t2.storeid
FROM jxstoremap t1
JOIN jxstore t2 ON t1.jxstoreid = t2.storeid
WHERE t1.jdstoreid = ?
`
} else if order.VendorID == model.VendorIDELM {
sql = `
SELECT t2.storeid
FROM jx_to_elm_store_map t1
JOIN jxstore t2 ON t1.jx_store_id = t2.storeid
WHERE t1.elm_store_id = ?
`
} else {
panic(fmt.Sprintf("wrong vendorid:%d", order.VendorID))
}
var lists []orm.ParamsList
if num, err := db.Raw(sql, utils.Str2Int64(order.VendorStoreID)).ValuesList(&lists); err == nil && num == 1 {
order.JxStoreID = int(utils.Str2Int64(lists[0][0].(string)))
} else {
globals.SugarLogger.Errorf("can not find store info for vendorID:%d, store:%s, num:%d, error:%v", order.VendorID, order.VendorStoreID, num, err)
}
err = c.updateOrderSkuOtherInfo(order.Skus, db)
return err
}
func (c *OrderController) handleAutoAcceptOrder(orderID string, vendorID int, userMobile string, jxStoreID int, db orm.Ormer, handler func(accepted bool)) int {
handleType := 0
if userMobile != "" {
if db == nil {
db = orm.NewOrm()
}
user := &models.BlackClient{
Mobile: userMobile,
}
if err := db.Read(user, "Mobile"); err != nil {
if err != orm.ErrNoRows {
globals.SugarLogger.Errorf("read data error:%v, data:%v, vendorID:%d", err, user, vendorID)
}
// 在访问数据库出错的情况下,也需要自动接单
handleType = 1
} else {
// 强制拒单
globals.SugarLogger.Infof("force reject order:%s, vendorID:%d", orderID, vendorID)
handleType = -1
}
} else {
globals.SugarLogger.Infof("order:%s, vendorID:%d, mobile is empty, should accept order", orderID, vendorID)
handleType = 1
}
if handleType == 1 {
handler(true)
} else if handleType == -1 {
handler(false)
}
return handleType
}
func (c *OrderController) addOrderStatus(orderStatus *model.OrderStatus, db orm.Ormer) (isDuplicated bool, err error) {
if db == nil {
db = orm.NewOrm()
}
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
if !isDuplicated && orderStatus.Status > model.OrderStatusUnknown {
order := &model.GoodsOrder{
VendorOrderID: orderStatus.VendorOrderID,
VendorID: orderStatus.VendorID,
}
if err = c.updateOrderPKID(order, db); err == nil {
order.Status = orderStatus.Status
order.VendorStatus = orderStatus.VendorStatus
utils.CallFuncLogError(func() error {
columns := []string{"Status", "VendorStatus"}
if orderStatus.Status >= model.OrderStatusEndBegin {
order.OrderFinishedAt = orderStatus.StatusTime
columns = append(columns, "OrderFinishedAt")
}
_, err := db.Update(order, columns...)
return err
}, "update order")
}
}
return isDuplicated, err
}
func (c *OrderController) updateOrderPKID(order *model.GoodsOrder, db orm.Ormer) (err error) {
value, ok := c.orderMap.Load(ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
if !ok {
err = db.Read(order, "VendorOrderID", "VendorID")
// todo 这里应该要报警,但测试阶段先去掉
// utils.CallFuncLogError(func() error {
// err = db.Read(order, "VendorOrderID", "VendorID")
// return err
// }, "can not get order info from db")
} else {
order.ID = value.(int64)
}
return err
}
func (c *OrderController) order2Status(order *model.GoodsOrder) (retVal *model.OrderStatus) {
retVal = &model.OrderStatus{
VendorOrderID: order.VendorOrderID,
VendorID: order.VendorID,
OrderType: model.OrderTypeOrder,
Status: order.Status,
VendorStatus: order.VendorStatus,
StatusTime: order.OrderCreatedAt,
}
return retVal
}
//Waybill
func (c *OrderController) OnWaybillStatusChanged(bill *model.Waybill, db orm.Ormer) (err error) {
return c.updateOrderByWaybill(bill, db)
}
func (c *OrderController) updateOrderByWaybill(bill *model.Waybill, db orm.Ormer) (err error) {
if db == nil {
db = orm.NewOrm()
}
order := &model.GoodsOrder{
VendorOrderID: bill.VendorOrderID,
VendorID: bill.OrderVendorID,
}
if err = db.Read(order, "VendorOrderID", "VendorID"); err == nil {
if order.Status < model.OrderStatusEndBegin {
order.WaybillStatus = bill.Status
order.WaybillVendorStatus = bill.VendorStatus
db.Update(order, "WaybillStatus", "WaybillVendorStatus")
}
}
return err
}