Merge remote-tracking branch 'origin/mark' into yonghui
This commit is contained in:
@@ -21,13 +21,6 @@ import (
|
||||
"github.com/astaxie/beego/orm"
|
||||
)
|
||||
|
||||
type tStoreSkuBindAndVendorSkuID struct {
|
||||
VendorSkuID int64 `orm:"column(vendor_sku_id)"`
|
||||
SkuID int `orm:"column(sku_id)"`
|
||||
Weight int
|
||||
Price int
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
@@ -323,49 +316,25 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
||||
}
|
||||
orderSkus := order.Skus
|
||||
|
||||
vendorSkuIDs := make([]int64, 0)
|
||||
var vendorSkuIDs []string
|
||||
for _, v := range orderSkus {
|
||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||
if intVendorSkuID != 0 {
|
||||
vendorSkuIDs = append(vendorSkuIDs, intVendorSkuID)
|
||||
if v.VendorSkuID != "" {
|
||||
vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID)
|
||||
}
|
||||
}
|
||||
if len(vendorSkuIDs) > 0 {
|
||||
tableName := "t2"
|
||||
if model.MultiStoresVendorMap[order.VendorID] == 1 {
|
||||
tableName = "t1"
|
||||
}
|
||||
fieldPrefix := dao.ConvertDBFieldPrefix(model.VendorNames[order.VendorID])
|
||||
sql := `
|
||||
SELECT %s.%s_id vendor_sku_id, t1.id sku_id, t2.price, t1.weight
|
||||
FROM sku t1
|
||||
LEFT JOIN store_sku_bind t2 ON t1.id = t2.sku_id AND t2.deleted_at = ? AND t2.store_id = ?
|
||||
WHERE t1.deleted_at = ? AND %s.%s_id IN (-1, ` + dao.GenQuestionMarks(len(vendorSkuIDs)) + ")"
|
||||
sql = fmt.Sprintf(sql, tableName, fieldPrefix, tableName, fieldPrefix)
|
||||
if order.VendorID == model.VendorIDJX {
|
||||
sql = `
|
||||
SELECT t1.id vendor_sku_id, t1.id sku_id, t2.price, t1.weight
|
||||
FROM sku t1
|
||||
LEFT JOIN store_sku_bind t2 ON t1.id = t2.sku_id AND t2.deleted_at = ? AND t2.store_id = ?
|
||||
WHERE t1.deleted_at = ? AND t1.id IN (-1, ` + dao.GenQuestionMarks(len(vendorSkuIDs)) + ")"
|
||||
}
|
||||
var skuInfos []*tStoreSkuBindAndVendorSkuID
|
||||
if err = dao.GetRows(db, &skuInfos, sql, utils.DefaultTimeValue, jxStoreID, utils.DefaultTimeValue, vendorSkuIDs); err != nil {
|
||||
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku info for orderID:%s, error:%v", order.VendorOrderID, err)
|
||||
l, err := dao.GetStoreSkuPriceAndWeight(db, order.VendorStoreID, order.VendorID, vendorSkuIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
skumapper := make(map[int64]*tStoreSkuBindAndVendorSkuID)
|
||||
for _, v := range skuInfos {
|
||||
skumapper[v.VendorSkuID] = v
|
||||
}
|
||||
|
||||
skumapper := storeSkuPriceAndWeight2Map(l)
|
||||
for _, v := range orderSkus {
|
||||
v.VendorOrderID = order.VendorOrderID
|
||||
v.VendorID = order.VendorID
|
||||
|
||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
||||
skuBindInfo := skumapper[intVendorSkuID]
|
||||
skuBindInfo := skumapper[v.VendorSkuID]
|
||||
if skuBindInfo == nil {
|
||||
globals.SugarLogger.Infof("updateOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v)
|
||||
} else {
|
||||
@@ -392,6 +361,14 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
||||
return nil
|
||||
}
|
||||
|
||||
func storeSkuPriceAndWeight2Map(l []*dao.StoreSkuPriceAndWeight) (skuMapper map[string]*dao.StoreSkuPriceAndWeight) {
|
||||
skuMapper = make(map[string]*dao.StoreSkuPriceAndWeight)
|
||||
for _, v := range l {
|
||||
skuMapper[v.VendorSkuID] = v
|
||||
}
|
||||
return skuMapper
|
||||
}
|
||||
|
||||
func updateSingleOrderEarningPrice(order *model.GoodsOrder, db *dao.DaoDB) {
|
||||
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
|
||||
skuIDMap := make(map[int]int)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package orderman
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
@@ -237,12 +236,11 @@ func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.Af
|
||||
return nil
|
||||
}
|
||||
orderSkus := order.Skus
|
||||
vendorSkuIDs := make([]int64, 0)
|
||||
var vendorSkuIDs []string
|
||||
skuIDMap := make(map[int]int)
|
||||
for _, v := range orderSkus {
|
||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||
if intVendorSkuID != 0 {
|
||||
vendorSkuIDs = append(vendorSkuIDs, intVendorSkuID)
|
||||
if v.VendorSkuID != "" {
|
||||
vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID)
|
||||
}
|
||||
|
||||
if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 {
|
||||
@@ -250,26 +248,12 @@ func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.Af
|
||||
}
|
||||
}
|
||||
if len(vendorSkuIDs) > 0 {
|
||||
tableName := "t2"
|
||||
if model.MultiStoresVendorMap[order.VendorID] == 1 {
|
||||
tableName = "t1"
|
||||
}
|
||||
fieldPrefix := dao.ConvertDBFieldPrefix(model.VendorNames[order.VendorID])
|
||||
sql := `
|
||||
SELECT %s.%s_id vendor_sku_id, t1.id sku_id, t2.price, t1.weight
|
||||
FROM sku t1
|
||||
LEFT JOIN store_sku_bind t2 ON t1.id = t2.sku_id AND t2.deleted_at = ? AND t2.store_id = ?
|
||||
WHERE t1.deleted_at = ? AND %s.%s_id IN (-1, ` + dao.GenQuestionMarks(len(vendorSkuIDs)) + ")"
|
||||
sql = fmt.Sprintf(sql, tableName, fieldPrefix, tableName, fieldPrefix)
|
||||
var skuInfos []*tStoreSkuBindAndVendorSkuID
|
||||
if err = dao.GetRows(db, &skuInfos, sql, utils.DefaultTimeValue, jxStoreID, utils.DefaultTimeValue, vendorSkuIDs); err != nil {
|
||||
globals.SugarLogger.Errorf("updateAfsOrderSkuOtherInfo can not get sku info for orderID:%s, error:%v", order.VendorOrderID, err)
|
||||
l, err := dao.GetStoreSkuPriceAndWeight(db, order.VendorStoreID, order.VendorID, vendorSkuIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
skumapper := make(map[int64]*tStoreSkuBindAndVendorSkuID)
|
||||
for _, v := range skuInfos {
|
||||
skumapper[v.VendorSkuID] = v
|
||||
}
|
||||
skumapper := storeSkuPriceAndWeight2Map(l)
|
||||
|
||||
var actStoreSkuMap *jxutils.ActStoreSkuMap
|
||||
if len(skuIDMap) > 0 {
|
||||
if order2, err2 := c.LoadOrder(order.VendorOrderID, order.VendorID); err2 == nil {
|
||||
@@ -292,7 +276,7 @@ func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.Af
|
||||
|
||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
||||
skuBindInfo := skumapper[intVendorSkuID]
|
||||
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 {
|
||||
|
||||
@@ -21,11 +21,6 @@ import (
|
||||
|
||||
const (
|
||||
DefActSkuStock = 200 // 缺省活动库存
|
||||
|
||||
maxDiscount4SkuSecKill = 80
|
||||
maxDiscount4Sku = 98
|
||||
minDiscount4SkuDirectDown = 0
|
||||
minDiscount4SkuDirectDownMTWM = 30
|
||||
)
|
||||
|
||||
type ActOrderRuleParam struct {
|
||||
@@ -64,11 +59,71 @@ type tPreCreateActInfo struct {
|
||||
ActStoreSku []*tPreCreateActStoreSku `json:"actStoreSku"`
|
||||
}
|
||||
|
||||
type tActRuleInfo struct {
|
||||
MinDiscount int
|
||||
MaxDiscount int
|
||||
}
|
||||
|
||||
type ActManager struct {
|
||||
}
|
||||
|
||||
var (
|
||||
FixedActManager *ActManager
|
||||
|
||||
actRuleMap = map[int]map[int]*tActRuleInfo{
|
||||
model.VendorIDJD: map[int]*tActRuleInfo{
|
||||
model.ActSkuFake: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 500,
|
||||
},
|
||||
model.ActSkuDirectDown: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 99,
|
||||
},
|
||||
model.ActSkuSecKill: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 80,
|
||||
},
|
||||
},
|
||||
model.VendorIDMTWM: map[int]*tActRuleInfo{
|
||||
model.ActSkuFake: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 500,
|
||||
},
|
||||
model.ActSkuDirectDown: &tActRuleInfo{
|
||||
MinDiscount: 30,
|
||||
MaxDiscount: 99,
|
||||
},
|
||||
model.ActSkuSecKill: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 30,
|
||||
},
|
||||
},
|
||||
model.VendorIDEBAI: map[int]*tActRuleInfo{
|
||||
model.ActSkuFake: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 500,
|
||||
},
|
||||
model.ActSkuDirectDown: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 99,
|
||||
},
|
||||
},
|
||||
model.VendorIDJX: map[int]*tActRuleInfo{
|
||||
model.ActSkuFake: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 500,
|
||||
},
|
||||
model.ActSkuDirectDown: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 99,
|
||||
},
|
||||
model.ActSkuSecKill: &tActRuleInfo{
|
||||
MinDiscount: 0,
|
||||
MaxDiscount: 80,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -256,11 +311,28 @@ func addActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actStoreSkuList [
|
||||
return err
|
||||
}
|
||||
|
||||
func checkActUpdate(actID int, actMap map[int]*model.Act2) (err error) {
|
||||
if len(actMap) == 0 {
|
||||
return fmt.Errorf("活动%d不存在或已被取消", actID)
|
||||
}
|
||||
errList := errlist.New()
|
||||
for vendorID, act := range actMap {
|
||||
if vendorID == model.VendorIDEBAI && act.CreateType != model.ActCreateTypeAPI {
|
||||
errList.AddErr(fmt.Errorf("饿百平台不支持修改或取消网页活动"))
|
||||
}
|
||||
}
|
||||
return errList.GetErrListAsOne()
|
||||
}
|
||||
|
||||
func AddActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
|
||||
actMap, err := dao.GetActVendorInfo(db, actID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = checkActUpdate(actID, actMap); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vendorIDs := partner.GetVendorIDsFromActMap(actMap)
|
||||
|
||||
var act *model.Act
|
||||
@@ -309,25 +381,33 @@ func AddActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actSto
|
||||
return err
|
||||
}
|
||||
|
||||
func getActRule(vendorID, actType int) (actRule *tActRuleInfo, err error) {
|
||||
if actRuleMap[vendorID] != nil {
|
||||
actRule = actRuleMap[vendorID][actType]
|
||||
}
|
||||
if actRule == nil {
|
||||
err = fmt.Errorf("%s不支持%s活动", model.VendorChineseNames[vendorID], model.ActTypeName[actType])
|
||||
}
|
||||
return actRule, err
|
||||
}
|
||||
|
||||
func checkDiscountValidation(vendorIDs []int, actType int, pricePercentage float64) (err error) {
|
||||
pricePercentageMin := int(math.Floor(pricePercentage))
|
||||
pricePercentageMax := int(math.Ceil(pricePercentage))
|
||||
if actType == model.ActSkuDirectDown && (pricePercentageMin < minDiscount4SkuDirectDown || pricePercentageMax > 99) {
|
||||
if pricePercentageMin < minDiscount4SkuDirectDown {
|
||||
err = fmt.Errorf("%s活动折扣必须大于:%d", model.ActTypeName[actType], minDiscount4SkuDirectDown)
|
||||
} else if pricePercentageMax > maxDiscount4Sku {
|
||||
err = fmt.Errorf("%s活动必须至少有%d折扣", model.ActTypeName[actType], maxDiscount4Sku)
|
||||
} else if len(vendorIDs) > 0 && vendorIDs[0] == model.VendorIDMTWM && pricePercentageMin < minDiscount4SkuDirectDownMTWM {
|
||||
err = fmt.Errorf("美团平台%s活动折扣必须大于:%d", model.ActTypeName[actType], minDiscount4SkuDirectDownMTWM)
|
||||
}
|
||||
} else if actType == model.ActSkuSecKill {
|
||||
if len(vendorIDs) > 0 && vendorIDs[0] == model.VendorIDMTWM && pricePercentageMax > minDiscount4SkuDirectDownMTWM {
|
||||
err = fmt.Errorf("美团平台%s活动折扣必须小于:%d", model.ActTypeName[actType], minDiscount4SkuDirectDownMTWM)
|
||||
} else if pricePercentageMax > maxDiscount4SkuSecKill {
|
||||
err = fmt.Errorf("%s活动折扣必须小于:%d", model.ActTypeName[actType], maxDiscount4SkuSecKill)
|
||||
errList := errlist.New()
|
||||
for _, vendorID := range vendorIDs {
|
||||
actRule, err2 := getActRule(vendorID, actType)
|
||||
if err2 == nil {
|
||||
if pricePercentageMin < actRule.MinDiscount {
|
||||
errList.AddErr(fmt.Errorf("%s%s活动折扣必须大于:%d", model.VendorChineseNames[vendorID], model.ActTypeName[actType], actRule.MinDiscount))
|
||||
} else if pricePercentageMax > actRule.MaxDiscount {
|
||||
errList.AddErr(fmt.Errorf("%s%s活动折扣必须小于:%d", model.VendorChineseNames[vendorID], model.ActTypeName[actType], actRule.MaxDiscount))
|
||||
}
|
||||
} else {
|
||||
errList.AddErr(err2)
|
||||
}
|
||||
}
|
||||
return err
|
||||
return errList.GetErrListAsOne()
|
||||
}
|
||||
|
||||
func checkActValidation(act *model.Act, vendorIDs []int) (err error) {
|
||||
@@ -644,8 +724,8 @@ func DeleteActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, act
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(actMap) == 0 {
|
||||
return 0, fmt.Errorf("找不到活动:%d,或已被取消", actID)
|
||||
if err = checkActUpdate(actID, actMap); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil)
|
||||
@@ -958,6 +1038,7 @@ func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, s
|
||||
var wrongSkuList []*ActStoreSkuParam
|
||||
var storeSkuBindList []*model.StoreSkuBind
|
||||
|
||||
actRule, _ := getActRule(vendorID, actType)
|
||||
db := dao.GetDB()
|
||||
errList := errlist.New()
|
||||
for _, v := range storeSkuList {
|
||||
@@ -978,11 +1059,7 @@ func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, s
|
||||
} else {
|
||||
vendorPrice = dao.GetStoreSkuBindVendorPrice(storeSkuBind, vendorID)
|
||||
if checkDiscountValidation([]int{vendorID}, actType, float64(v.ActPrice)*100/float64(vendorPrice)) != nil {
|
||||
if actType == model.ActSkuSecKill {
|
||||
vendorPrice = int(v.ActPrice)*100/maxDiscount4SkuSecKill + 10
|
||||
} else if actType == model.ActSkuDirectDown {
|
||||
vendorPrice = int(v.ActPrice) + 10
|
||||
}
|
||||
vendorPrice = int(v.ActPrice)*100/actRule.MaxDiscount + 10
|
||||
} else {
|
||||
storeSkuBind = nil
|
||||
}
|
||||
|
||||
@@ -208,6 +208,13 @@ type SkuNameAndPlace struct {
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
type StoreSkuPriceAndWeight struct {
|
||||
VendorSkuID string `orm:"column(vendor_sku_id)"`
|
||||
SkuID int `orm:"column(sku_id)"`
|
||||
Weight int
|
||||
Price int
|
||||
}
|
||||
|
||||
// todo 应该通过需要同步的skuid来驱动同步分类,而不是当前这种分开的逻辑
|
||||
// 单门店模式厂商适用
|
||||
// 从store_sku_bind中,得到所有依赖的商家分类信息
|
||||
@@ -632,6 +639,42 @@ func oldGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSync
|
||||
return skus, err
|
||||
}
|
||||
|
||||
func GetStoreSkuPriceAndWeight(db *DaoDB, vendorStoreID string, vendorID int, vendorSkuIDs []string) (l []*StoreSkuPriceAndWeight, err error) {
|
||||
var vendorSkuIDField, sqlThingMap string
|
||||
var thingMapParams []interface{}
|
||||
if vendorID == model.VendorIDJX {
|
||||
vendorSkuIDField = "t1.id"
|
||||
} else if model.MultiStoresVendorMap[vendorID] != 0 {
|
||||
sqlThingMap = `
|
||||
LEFT JOIN thing_map t4 ON t4.thing_type = ? AND t4.thing_id = t1.id AND t4.deleted_at = ? AND t4.vendor_id = t3.vendor_id AND t4.vendor_org_code = t3.vendor_org_code`
|
||||
thingMapParams = []interface{}{
|
||||
model.ThingTypeSku, utils.DefaultTimeValue,
|
||||
}
|
||||
vendorSkuIDField = "t4.vendor_thing_id"
|
||||
} else {
|
||||
vendorSkuIDField = fmt.Sprintf("t2.%s_id", ConvertDBFieldPrefix(model.VendorNames[vendorID]))
|
||||
}
|
||||
sql := fmt.Sprintf(`
|
||||
SELECT %s vendor_sku_id, t1.id sku_id, t2.price, t1.weight
|
||||
FROM sku t1
|
||||
LEFT JOIN store_sku_bind t2 ON t2.sku_id = t1.id AND t2.deleted_at = ?
|
||||
LEFT JOIN store_map t3 ON t3.store_id = t2.store_id AND t3.vendor_id = ? AND t3.vendor_store_id = ? AND t2.deleted_at = ?
|
||||
%s
|
||||
WHERE %s IN (`+GenQuestionMarks(len(vendorSkuIDs))+`)`, vendorSkuIDField, sqlThingMap, vendorSkuIDField)
|
||||
sqlParams := []interface{}{
|
||||
utils.DefaultTimeValue,
|
||||
vendorID, vendorStoreID, utils.DefaultTimeValue,
|
||||
}
|
||||
sqlParams = append(sqlParams, thingMapParams...)
|
||||
if vendorID == model.VendorIDJX {
|
||||
sqlParams = append(sqlParams, utils.StringSlice2Int(vendorSkuIDs))
|
||||
} else {
|
||||
sqlParams = append(sqlParams, vendorSkuIDs)
|
||||
}
|
||||
err = GetRows(db, &l, sql, sqlParams...)
|
||||
return l, err
|
||||
}
|
||||
|
||||
// 这个函数之前是要设置没有删除或同步标志不为0的,会导致将同步标志不为0且删除了的把标志去掉,现在改为只设置没有删除的
|
||||
func SetStoreSkuSyncStatus(db *DaoDB, vendorID int, storeIDs []int, skuIDs []int, syncStatus int) (num int64, err error) {
|
||||
globals.SugarLogger.Debugf("SetStoreSkuSyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID)
|
||||
|
||||
Reference in New Issue
Block a user