255 lines
8.4 KiB
Go
255 lines
8.4 KiB
Go
package controller
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"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) LoadPendingOrders() []*model.GoodsOrder {
|
||
db := orm.NewOrm()
|
||
var orders []*model.GoodsOrder
|
||
_, err := db.Raw(`
|
||
SELECT *
|
||
FROM goods_order
|
||
WHERE order_created_at >= ?
|
||
AND status < ?
|
||
ORDER by order_created_at
|
||
`, time.Now().Add(-pendingOrderGapMax), model.OrderStatusEndBegin).QueryRows(&orders)
|
||
if err != nil {
|
||
globals.SugarLogger.Warnf("LoadPendingOrders load pending orders error:%v", err)
|
||
return nil
|
||
}
|
||
return orders
|
||
}
|
||
|
||
func (c *OrderController) OnOrderNew(order *model.GoodsOrder) (err error) {
|
||
db := orm.NewOrm()
|
||
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
|
||
}
|
||
|
||
// todo 调整单的处理可能还需要再细化一点,当前只是简单的删除重建
|
||
func (c *OrderController) OnOrderAdjust(order *model.GoodsOrder) (err error) {
|
||
db := orm.NewOrm()
|
||
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, orderID:%s", order.VendorOrderID)
|
||
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, orderID:%s", order.VendorOrderID)
|
||
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.GenerateLegacyJxOrder {
|
||
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()
|
||
order.ID = 0
|
||
order.WaybillVendorID = model.VendorIDUnknown
|
||
order.OrderFinishedAt = utils.DefaultTimeValue
|
||
order.OrderCreatedAt = order.StatusTime
|
||
globals.SugarLogger.Debugf("saveOrder isAdjust:%t, order:%v", isAdjust, order)
|
||
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.StatusTime)
|
||
}
|
||
sql = sql[:len(sql)-1] + ";"
|
||
if _, err = db.Raw(sql, params...).Exec(); err != nil {
|
||
db.Rollback()
|
||
baseapi.SugarLogger.Infof("saveOrder insert order:%v, order_sku error:%v", order, err)
|
||
} else {
|
||
db.Commit()
|
||
if globals.GenerateLegacyJxOrder {
|
||
c.legacyWriteJxOrder(order, db, isAdjust)
|
||
}
|
||
}
|
||
} else {
|
||
order.DuplicatedCount++
|
||
db.Update(order, "DuplicatedCount")
|
||
db.Commit()
|
||
baseapi.SugarLogger.Infof("saveOrder duplicated orderid:%s msg received", order.VendorOrderID)
|
||
}
|
||
} else {
|
||
db.Rollback()
|
||
globals.SugarLogger.Warnf("saveOrder 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("updateOrderSkuOtherInfo can not find sku map:%v", v)
|
||
}
|
||
}
|
||
} else {
|
||
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku info for orderID:%s, num:%d, error:%v", 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("updateOrderOtherInfo can not find store info for orderID:%s, store:%s, num:%d, error:%v", order.VendorOrderID, 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 err == nil && !isDuplicated && orderStatus.Status > model.OrderStatusNew {
|
||
params := orm.Params{
|
||
"status": orderStatus.Status,
|
||
"vendor_status": orderStatus.VendorStatus,
|
||
"status_time": orderStatus.StatusTime,
|
||
}
|
||
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
|
||
}, "addOrderStatus update order, status:%v", orderStatus)
|
||
}
|
||
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
|
||
}, "UpdateWaybillVendorID update order, bill:%v", bill)
|
||
return err
|
||
}
|