425 lines
15 KiB
Go
425 lines
15 KiB
Go
package orderman
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"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"
|
||
"github.com/astaxie/beego/adapter/orm"
|
||
)
|
||
|
||
func (c *OrderManager) LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
||
return c.loadAfsOrder(dao.GetDB(), vendorAfsOrderID, vendorID)
|
||
}
|
||
|
||
func (c *OrderManager) loadAfsOrder(db *dao.DaoDB, vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
||
afsOrder = &model.AfsOrder{
|
||
AfsOrderID: vendorAfsOrderID,
|
||
VendorID: vendorID,
|
||
}
|
||
if err = dao.GetEntity(db, afsOrder, "AfsOrderID", "VendorID"); err != nil {
|
||
afsOrder = nil
|
||
}
|
||
return afsOrder, err
|
||
}
|
||
|
||
func (c *OrderManager) OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) {
|
||
return c.onAfsOrderNew(afsOrder, orderStatus, true)
|
||
}
|
||
|
||
func (c *OrderManager) OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) {
|
||
return c.onAfsOrderNew(afsOrder, orderStatus, false)
|
||
}
|
||
|
||
func (c *OrderManager) onAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus, isAdjust bool) (err error) {
|
||
db := dao.GetDB()
|
||
globals.SugarLogger.Debugf("onAfsOrderNew1 orderID:%s", afsOrder.VendorOrderID)
|
||
c.setAfsOrderID(db, orderStatus)
|
||
if afsOrder.AfsOrderID == "" {
|
||
afsOrder.AfsOrderID = orderStatus.VendorOrderID
|
||
}
|
||
if afsOrder.VendorStatus == "" {
|
||
afsOrder.VendorStatus = orderStatus.VendorStatus
|
||
}
|
||
if afsOrder.Status == model.OrderStatusUnknown {
|
||
afsOrder.Status = orderStatus.Status
|
||
}
|
||
globals.SugarLogger.Debugf("onAfsOrderNew2 orderID:%s", afsOrder.VendorOrderID)
|
||
//
|
||
if order, _ := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); order != nil {
|
||
if order.ConsigneeMobile2 == "" {
|
||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil {
|
||
if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID, order.VendorStoreID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile {
|
||
order.ConsigneeMobile = order2.ConsigneeMobile
|
||
c.UpdateOrderFields(order, []string{"ConsigneeMobile"})
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db)
|
||
globals.SugarLogger.Debugf("onAfsOrderNew afsOrderID:%s, isDuplicated:%t", afsOrder.AfsOrderID, isDuplicated)
|
||
if err != nil || isDuplicated {
|
||
if err == nil {
|
||
dao.Commit(db)
|
||
}
|
||
return err
|
||
}
|
||
var existAfsOrder *model.AfsOrder
|
||
if existAfsOrder, err = c.loadAfsOrder(db, afsOrder.AfsOrderID, afsOrder.VendorID); err != nil {
|
||
if !dao.IsNoRowsError(err) {
|
||
return err
|
||
}
|
||
}
|
||
if existAfsOrder != nil {
|
||
// todo 可能导致状态回绕
|
||
existAfsOrder.Status = afsOrder.Status
|
||
existAfsOrder.VendorStatus = afsOrder.VendorStatus
|
||
if _, err = dao.UpdateEntity(db, existAfsOrder, "Status", "VendorStatus"); err != nil {
|
||
return err
|
||
}
|
||
afsOrder = existAfsOrder
|
||
} else {
|
||
// 全退都要先全删除再建
|
||
if afsOrder.RefundType == model.AfsTypeFullRefund {
|
||
isAdjust = true
|
||
}
|
||
if err = c.SaveAfsOrder(db, afsOrder, isAdjust); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
dao.Commit(db)
|
||
scheduler.CurrentScheduler.OnAfsOrderNew(afsOrder, false)
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) SaveAfsOrder(db *dao.DaoDB, afsOrder *model.AfsOrder, isDeleteFirst bool) (err error) {
|
||
globals.SugarLogger.Debug(afsOrder.AfsOrderID)
|
||
if db == nil {
|
||
db = dao.GetDB()
|
||
}
|
||
if err = c.updateAfsOrderOtherInfo(db, afsOrder); err != nil {
|
||
return err
|
||
}
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
if isDeleteFirst {
|
||
err = utils.CallFuncLogError(func() error {
|
||
_, err = dao.DeleteEntity(db, afsOrder, "VendorOrderID", "VendorID")
|
||
return err
|
||
}, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", afsOrder.AfsOrderID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
err = utils.CallFuncLogError(func() error {
|
||
_, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{
|
||
VendorOrderID: afsOrder.VendorOrderID,
|
||
VendorID: afsOrder.VendorID,
|
||
IsAfsOrder: 1,
|
||
}, "VendorOrderID", "VendorID", "IsAfsOrder")
|
||
return err
|
||
}, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", afsOrder.AfsOrderID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
// 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、
|
||
deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney
|
||
afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney
|
||
// order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算
|
||
if err = dao.CreateEntity(db, afsOrder); err != nil {
|
||
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v", afsOrder.AfsOrderID, err)
|
||
return err
|
||
}
|
||
|
||
// 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额)
|
||
for _, orderSku := range afsOrder.Skus[1:] {
|
||
orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney +
|
||
utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney))
|
||
afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal
|
||
if err = dao.CreateEntity(db, orderSku); err != nil {
|
||
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true))
|
||
return err
|
||
}
|
||
}
|
||
if len(afsOrder.Skus) > 0 {
|
||
orderSku := afsOrder.Skus[0]
|
||
orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal
|
||
if err = dao.CreateEntity(db, orderSku); err != nil {
|
||
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true))
|
||
return err
|
||
}
|
||
} else {
|
||
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID)
|
||
}
|
||
dao.Commit(db)
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
|
||
db := dao.GetDB()
|
||
c.setAfsOrderID(db, orderStatus)
|
||
dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db)
|
||
panic(r)
|
||
}
|
||
}()
|
||
isDuplicated, afsOrder, err := c.addAfsOrderStatus(db, orderStatus)
|
||
if err != nil || isDuplicated {
|
||
if err == nil {
|
||
dao.Commit(db)
|
||
} else {
|
||
dao.Rollback(db)
|
||
}
|
||
return err
|
||
}
|
||
dao.Commit(db)
|
||
scheduler.CurrentScheduler.OnAfsOrderStatusChanged(afsOrder, orderStatus, false)
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) addAfsOrderStatus(db *dao.DaoDB, orderStatus *model.OrderStatus) (isDuplicated bool, order *model.AfsOrder, err error) {
|
||
globals.SugarLogger.Debugf("addAfsOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID)
|
||
if db == nil {
|
||
db = dao.GetDB()
|
||
}
|
||
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
|
||
if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) {
|
||
order = &model.AfsOrder{
|
||
AfsOrderID: orderStatus.VendorOrderID,
|
||
VendorID: orderStatus.VendorID,
|
||
}
|
||
if err = db.Db.ReadForUpdate(order, "AfsOrderID", "VendorID"); err == nil {
|
||
if orderStatus.Status > model.OrderStatusUnknown { // todo 要求status不能回绕
|
||
order.VendorStatus = orderStatus.VendorStatus
|
||
order.Status = orderStatus.Status
|
||
updateFields := []string{
|
||
"VendorStatus",
|
||
"Status",
|
||
}
|
||
if model.IsAfsOrderFinalStatus(orderStatus.Status) {
|
||
order.AfsFinishedAt = orderStatus.StatusTime
|
||
updateFields = append(updateFields, "AfsFinishedAt")
|
||
}
|
||
utils.CallFuncLogError(func() error {
|
||
_, err = dao.UpdateEntity(db, order, updateFields...)
|
||
return err
|
||
}, "addAfsOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus)
|
||
} else {
|
||
isDuplicated = true
|
||
}
|
||
} else {
|
||
if dao.IsNoRowsError(err) { // todo 消息错序
|
||
err = nil
|
||
} else {
|
||
globals.SugarLogger.Warnf("addAfsOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err)
|
||
}
|
||
}
|
||
}
|
||
return isDuplicated, order, err
|
||
}
|
||
|
||
func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.AfsOrder) (err error) {
|
||
globals.SugarLogger.Debugf("updateAfsOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||
jxStoreID := jxutils.GetSaleStoreIDFromAfsOrder(order)
|
||
opNumStr := "2"
|
||
if jxStoreID == 0 {
|
||
globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]订单在京西与平台都找不到京西门店信息orderID:%s, VendorStoreID:%s", opNumStr, order.VendorOrderID, order.VendorStoreID)
|
||
return nil
|
||
}
|
||
orderSkus := order.Skus
|
||
var vendorSkuIDs []string
|
||
skuIDMap := make(map[int]int)
|
||
for _, v := range orderSkus {
|
||
if v.VendorSkuID != "" {
|
||
vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID)
|
||
}
|
||
|
||
if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 {
|
||
skuIDMap[skuID] = 1
|
||
}
|
||
}
|
||
if len(vendorSkuIDs) > 0 {
|
||
var vendorStoreID string
|
||
if order.VendorID == model.VendorIDJDShop {
|
||
vendorStoreID = model.JdShopMainVendorStoreID
|
||
} else {
|
||
vendorStoreID = order.VendorStoreID
|
||
}
|
||
l, err := dao.GetStoreSkuPriceAndWeight(db, vendorStoreID, order.VendorID, vendorSkuIDs)
|
||
if err != nil {
|
||
globals.SugarLogger.Warnf("updateAfsOrderSkuOtherInfo orderID:%s failed with err:%v", order.VendorOrderID, err)
|
||
return err
|
||
}
|
||
skumapper := storeSkuPriceAndWeight2Map(l)
|
||
|
||
var actStoreSkuMap *jxutils.ActStoreSkuMap
|
||
if len(skuIDMap) > 0 {
|
||
if order2, err2 := c.LoadOrder(order.VendorOrderID, order.VendorID); err2 == nil {
|
||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order2.OrderCreatedAt, order2.OrderCreatedAt)
|
||
if err != nil {
|
||
globals.SugarLogger.Errorf("updateAfsOrderSkuOtherInfo can not get sku promotion info for error:%v", err)
|
||
return err
|
||
}
|
||
actStoreSkuMap = jxutils.NewActStoreSkuMap(actStoreSkuList, false)
|
||
}
|
||
}
|
||
for _, v := range orderSkus {
|
||
v.AfsOrderID = order.AfsOrderID
|
||
v.VendorID = order.VendorID
|
||
v.VendorOrderID = order.VendorOrderID
|
||
v.IsAfsOrder = 1
|
||
v.VendorStoreID = order.VendorStoreID
|
||
v.StoreID = order.StoreID
|
||
v.JxStoreID = jxStoreID
|
||
|
||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
||
skuBindInfo := skumapper[v.VendorSkuID]
|
||
if skuBindInfo == nil {
|
||
globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v)
|
||
} else {
|
||
v.JxSkuID = skuBindInfo.SkuID
|
||
v.ShopPrice = int64(skuBindInfo.Price)
|
||
}
|
||
}
|
||
if actStoreSkuMap != nil {
|
||
if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 && v.StoreSubName != "" {
|
||
if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil {
|
||
v.StoreSubID = actStoreSku.ActID
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (c *OrderManager) updateAfsOrderOtherInfo(db *dao.DaoDB, afsOrder *model.AfsOrder) (err error) {
|
||
globals.SugarLogger.Debugf("updateAfsOrderOtherInfo orderID:%s, VendorStoreID:%s", afsOrder.VendorOrderID, afsOrder.VendorStoreID)
|
||
if afsOrder.VendorStoreID != "" {
|
||
if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, afsOrder.VendorStoreID, 0, ""); err == nil {
|
||
afsOrder.JxStoreID = storeDetail.Store.ID
|
||
}
|
||
}
|
||
if afsOrder.StoreID == 0 && afsOrder.JxStoreID == 0 {
|
||
if order, err2 := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); err2 == nil {
|
||
afsOrder.JxStoreID = order.JxStoreID
|
||
if afsOrder.StoreID == 0 {
|
||
afsOrder.StoreID = order.StoreID
|
||
}
|
||
if afsOrder.VendorStoreID == "" {
|
||
afsOrder.VendorStoreID = order.VendorStoreID
|
||
}
|
||
}
|
||
}
|
||
if err == nil {
|
||
if err = c.updateAfsOrderSkuOtherInfo(db, afsOrder); err == nil {
|
||
jxutils.RefreshAfsOrderSkuRelated(afsOrder)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) {
|
||
db := orm.NewOrm()
|
||
utils.CallFuncLogError(func() error {
|
||
_, err = db.Update(afsOrder, fieldList...)
|
||
return err
|
||
}, "UpdateAfsOrderFields orderID:%s failed with error:%v", afsOrder.VendorOrderID, err)
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) setAfsOrderID(db *dao.DaoDB, orderStatus *model.OrderStatus) {
|
||
// globals.SugarLogger.Debugf("setAfsOrderID1 orderStatus:%v", utils.Format4Output(orderStatus, true))
|
||
if dao.IsVendorThingIDEmpty(orderStatus.VendorOrderID) {
|
||
index := 1
|
||
if afsOrderList, err2 := dao.GetAfsOrders(db, orderStatus.RefVendorID, orderStatus.RefVendorOrderID, ""); err2 == nil {
|
||
if len(afsOrderList) > 0 {
|
||
list := strings.Split(afsOrderList[0].AfsOrderID, "-")
|
||
if len(list) > 1 {
|
||
index = int(utils.Str2Int64WithDefault(list[1], 0))
|
||
if afsOrderList[0].Status >= model.AfsOrderStatusFinished {
|
||
index++
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
globals.SugarLogger.Warnf("setAfsOrderID err2:%v", err2)
|
||
}
|
||
orderStatus.VendorOrderID = composeAfsOrderID(orderStatus.RefVendorOrderID, index)
|
||
}
|
||
// globals.SugarLogger.Debugf("setAfsOrderID2 orderStatus:%v", utils.Format4Output(orderStatus, true))
|
||
}
|
||
|
||
func composeAfsOrderID(vendorOrderID string, index int) (afsOrderID string) {
|
||
return strings.Join([]string{
|
||
vendorOrderID,
|
||
utils.Int2Str(index),
|
||
}, "-")
|
||
}
|
||
|
||
func (c *OrderManager) CreateAfsOrderFromOrder(vendorOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
||
order, err := c.LoadOrder(vendorOrderID, vendorID)
|
||
// globals.SugarLogger.Debug(utils.Format4Output(order, false))
|
||
if err == nil {
|
||
afsOrder = &model.AfsOrder{
|
||
VendorID: vendorID,
|
||
VendorOrderID: vendorOrderID,
|
||
JxStoreID: order.JxStoreID,
|
||
VendorStoreID: order.VendorStoreID,
|
||
StoreID: order.StoreID,
|
||
VendorOrgCode: order.VendorOrgCode,
|
||
}
|
||
} else {
|
||
globals.SugarLogger.Warnf("CreateAfsOrderFromOrder, orderID:%s is not found from partner.CurOrderManager.LoadOrder", vendorOrderID)
|
||
return nil, err
|
||
}
|
||
|
||
for _, sku := range order.Skus {
|
||
orderSkuFinancial := &model.OrderSkuFinancial{
|
||
VendorID: sku.VendorID,
|
||
VendorOrderID: sku.VendorOrderID,
|
||
// OrderFinancialID: sku.VendorOrderID,
|
||
// ConfirmTime: afsOrder.AfsCreateAt,
|
||
VendorStoreID: afsOrder.VendorStoreID,
|
||
StoreID: afsOrder.StoreID,
|
||
JxStoreID: afsOrder.JxStoreID,
|
||
VendorSkuID: sku.VendorSkuID,
|
||
SkuID: sku.SkuID,
|
||
PromotionType: sku.PromotionType,
|
||
Name: sku.SkuName,
|
||
ShopPrice: sku.ShopPrice,
|
||
SalePrice: sku.SalePrice,
|
||
Count: sku.Count,
|
||
// UserMoney: sku.UserMoney,
|
||
// PmSubsidyMoney: sku.PmSubsidyMoney,
|
||
IsAfsOrder: 1,
|
||
}
|
||
afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial)
|
||
}
|
||
return afsOrder, nil
|
||
}
|