Files
jx-callback/business/controller/order.go
2018-07-12 20:57:34 +08:00

220 lines
7.1 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 (
"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, orderSkus []*model.OrderSku) (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
}
})
if err = c.updateOrderOtherInfo(order, db); err == nil {
if err = c.updateOrderSkuOtherInfo(orderSkus, db); err == nil {
db.Begin()
// globals.SugarLogger.Debugf("new order:%v", order)
order.OrderFinishedAt = 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, sku_id, vendor_sku_id, sku_name, shop_price, sale_price, weight, order_created_at) VALUES"
params := []interface{}{}
for _, sku := range orderSkus {
sql += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?),"
params = append(params, sku.VendorOrderID, sku.VendorID, sku.Count, sku.SkuID, sku.VendorSkuID, 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()
}
} 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, orderSkus []*model.OrderSku) (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
}
}
return c.OnOrderNew(order, orderSkus)
}
func (c *OrderController) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
isDuplicated, err := c.addOrderStatus(orderStatus, nil)
if err == nil && !isDuplicated {
}
return err
}
// private
func (c *OrderController) updateOrderSkuOtherInfo(orderSkus []*model.OrderSku, db orm.Ormer) (err error) {
return nil
}
func (c *OrderController) updateOrderOtherInfo(order *model.GoodsOrder, db orm.Ormer) (err error) {
return nil
}
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 it", 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
}