Files
jx-callback/business/controller/order.go
gazebo 65eeef9966 - fix weixin push msg bug.
- handle jd out-of-order msg.
2018-07-20 23:22:31 +08:00

236 lines
7.7 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/jx-callback/business/scheduler"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/globals"
"github.com/astaxie/beego/orm"
)
// 所有公共接口调用前要求在order里或status中设置合适的Status
type OrderController struct {
}
func NewOrderManager() *OrderController {
return &OrderController{}
}
func (c *OrderController) OnOrderNew(order *model.GoodsOrder) (err error) {
db := orm.NewOrm()
order.StatusTime = order.OrderCreatedAt
isDuplicated, err := addOrderOrWaybillStatus(model.Order2Status(order), db)
if err == nil && !isDuplicated {
if err = c.saveOrder(order, false, db); err == nil {
err = scheduler.CurrentScheduler.OnOrderNew(order)
weixinmsg.NotifyNewOrder(order)
}
}
return err
}
func (c *OrderController) OnOrderAdjust(order *model.GoodsOrder) (err error) {
db := orm.NewOrm()
order.StatusTime = order.OrderCreatedAt
status := model.Order2Status(order)
isDuplicated, err := addOrderOrWaybillStatus(status, 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
}
if err = c.saveOrder(order, true, db); err == nil {
err = scheduler.CurrentScheduler.OnOrderStatusChanged(status)
}
}
return err
}
func (c *OrderController) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
isDuplicated, err := c.addOrderStatus(orderStatus, nil)
if err == nil && !isDuplicated {
err = scheduler.CurrentScheduler.OnOrderStatusChanged(orderStatus)
if globals.HandleLegacyJxOrder {
c.legacyJxOrderStatusChanged(orderStatus, nil)
}
}
return err
}
// private
func (c *OrderController) saveOrder(order *model.GoodsOrder, isAdjust bool, db orm.Ormer) (err error) {
// 忽略查找JX信息错误
c.updateOrderOtherInfo(order, db)
db.Begin()
// globals.SugarLogger.Debugf("new order:%v", order)
order.WaybillVendorID = model.VendorIDUnknown
order.OrderFinishedAt = utils.DefaultTimeValue
order.ID = 0
created, _, err2 := db.ReadOrCreate(order, "VendorOrderID", "VendorID")
if err = err2; err == nil {
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, sku_type, promotion_type, 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, sku.Weight, sku.SkuType, sku.PromotionType, 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, isAdjust)
}
}
} 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) updateOrderSkuOtherInfo(orderSkus []*model.OrderSku, db orm.Ormer) (err error) {
var sql string
if orderSkus[0].VendorID == model.VendorIDJD {
sql = `
SELECT t1.jdskuid, t1.skuid
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 sku map:%v", v.VendorSkuID)
}
}
} 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 t1.jxstoreid
FROM jxstoremap t1
/* JOIN jxstore t2 ON t1.jxstoreid = t2.storeid */
WHERE t1.jdstoreid = ?
`
} else if order.VendorID == model.VendorIDELM {
sql = `
SELECT t1.jx_store_id
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) 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.OrderStatusNew {
params := orm.Params{
"status": orderStatus.Status,
"vendor_status": orderStatus.VendorStatus,
}
if orderStatus.Status >= model.OrderStatusEndBegin {
params["order_finished_at"] = orderStatus.StatusTime
}
utils.CallFuncLogError(func() error {
_, err = db.QueryTable("goods_order").Filter("vendor_order_id", orderStatus.VendorOrderID).Filter("vendor_id", orderStatus.VendorID).Update(params)
return err
}, "update order")
}
return isDuplicated, err
}
func (c *OrderController) LoadOrder(vendorOrderID string, vendorID int) (order *model.GoodsOrder, err error) {
db := orm.NewOrm()
order = &model.GoodsOrder{
VendorOrderID: vendorOrderID,
VendorID: vendorID,
}
err = db.Read(order, "VendorOrderID", "VendorID")
return order, err
}
//Waybill
func (c *OrderController) UpdateWaybillVendorID(bill *model.Waybill) (err error) {
db := orm.NewOrm()
params := orm.Params{
"waybill_vendor_id": bill.WaybillVendorID,
}
// 如果运单被取消,则要保持在已拣货状态
if bill.WaybillVendorID == model.VendorIDUnknown {
params["status"] = model.OrderStatusFinishedPickup
}
utils.CallFuncLogError(func() error {
_, err = db.QueryTable("goods_order").Filter("vendor_order_id", bill.VendorOrderID).Filter("vendor_id", bill.OrderVendorID).Update(params)
return err
}, "update order")
return err
}