- CreatePromotion
This commit is contained in:
236
business/jxstore/promotion/jd_promotion.go
Normal file
236
business/jxstore/promotion/jd_promotion.go
Normal file
@@ -0,0 +1,236 @@
|
||||
package promotion
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
)
|
||||
|
||||
const (
|
||||
PromotionTypeNormal = 1
|
||||
PromotionTypeDirectDown = 3
|
||||
PromotionTypeLimitedTime = 4
|
||||
)
|
||||
|
||||
const (
|
||||
PriceTypePrice = 1 // 绝对价格
|
||||
PriceTypePercentage = 2 // 百分比
|
||||
)
|
||||
|
||||
const (
|
||||
PromotionLimitedTimeMinPercentage = 80
|
||||
)
|
||||
|
||||
const (
|
||||
PromotionStatusCreated = 1
|
||||
PromotionStatusEnded = 2
|
||||
)
|
||||
|
||||
type SkuPrice struct {
|
||||
SkuID int `json:"skuID"`
|
||||
PriceType int `json:"priceType"`
|
||||
Price int `json:"price"` // 分,这个不是单价
|
||||
}
|
||||
|
||||
type PromotionParams struct {
|
||||
Name string
|
||||
Advertising string
|
||||
Type int
|
||||
BeginAt time.Time
|
||||
EndAt time.Time
|
||||
StoreIDs []int
|
||||
SkuPrices []*SkuPrice
|
||||
}
|
||||
|
||||
var (
|
||||
ErrEmptySkus = errors.New("空sku")
|
||||
)
|
||||
|
||||
type JdPromotionHandler interface {
|
||||
CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error)
|
||||
CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error)
|
||||
CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error)
|
||||
ConfirmPromotion(infoId int64, outInfoId string) (err error)
|
||||
}
|
||||
|
||||
type JdDirectDownHandler struct {
|
||||
}
|
||||
|
||||
func (p *JdDirectDownHandler) CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error) {
|
||||
return api.JdAPI.CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising)
|
||||
}
|
||||
func (p *JdDirectDownHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
||||
return api.JdAPI.CreatePromotionRules(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily)
|
||||
}
|
||||
func (p *JdDirectDownHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error) {
|
||||
return api.JdAPI.CreatePromotionSkuSingle(infoId, outInfoId, skus)
|
||||
}
|
||||
func (p *JdDirectDownHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
||||
return api.JdAPI.ConfirmPromotionSingle(infoId, outInfoId)
|
||||
}
|
||||
|
||||
type JdLimitedTimeHandler struct {
|
||||
}
|
||||
|
||||
func (p *JdLimitedTimeHandler) CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error) {
|
||||
return api.JdAPI.CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising)
|
||||
}
|
||||
func (p *JdLimitedTimeHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
||||
return api.JdAPI.CreatePromotionRules(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily)
|
||||
}
|
||||
func (p *JdLimitedTimeHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error) {
|
||||
return api.JdAPI.CreatePromotionSkuLimitTime(infoId, outInfoId, skus)
|
||||
}
|
||||
func (p *JdLimitedTimeHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
||||
return api.JdAPI.ConfirmPromotionLimitTime(infoId, outInfoId)
|
||||
}
|
||||
|
||||
func init() {
|
||||
gob.Register(&PromotionParams{})
|
||||
gob.Register([]*SkuPrice{})
|
||||
}
|
||||
|
||||
func CreateJdPromotion(isAsync bool, params *PromotionParams, userName string) (hint string, err error) {
|
||||
if len(params.SkuPrices) == 0 {
|
||||
return "", ErrEmptySkus
|
||||
}
|
||||
db := dao.GetDB()
|
||||
skuIDs := make([]int, len(params.SkuPrices))
|
||||
skuPriceMap := make(map[int]*SkuPrice)
|
||||
for k, v := range params.SkuPrices {
|
||||
skuIDs[k] = v.SkuID
|
||||
skuPriceMap[v.SkuID] = v
|
||||
}
|
||||
sql := `
|
||||
SELECT t1.*
|
||||
FROM store_sku_bind t1
|
||||
WHERE t1.jd_sync_status = 0 AND t1.deleted_at = ? AND t1.store_id = ? AND t1.sku_id IN (
|
||||
` + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
||||
|
||||
errMsg := ""
|
||||
modifyPricesList := make(map[int][]*jdapi.SkuPriceInfo)
|
||||
promotionPrices := make([]map[string]interface{}, len(params.StoreIDs)*len(params.SkuPrices))
|
||||
index := 0
|
||||
for _, storeID := range params.StoreIDs {
|
||||
var skuBinds []*model.StoreSkuBind
|
||||
if err = dao.GetRows(db, &skuBinds, sql, utils.DefaultTimeValue, storeID, skuIDs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, skuBind := range skuBinds {
|
||||
promotionSkuPrice := skuPriceMap[skuBind.SkuID]
|
||||
if promotionSkuPrice.PriceType == PriceTypePercentage {
|
||||
promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100
|
||||
}
|
||||
if promotionSkuPrice.Price >= skuBind.Price {
|
||||
errMsg += fmt.Sprintf("促销价大于等于原价,storeID:%d, skuID:%d\n", storeID, skuBind.SkuID)
|
||||
}
|
||||
if errMsg == "" {
|
||||
if params.Type == PromotionTypeLimitedTime {
|
||||
if skuBind.Price*PromotionLimitedTimeMinPercentage/100 < promotionSkuPrice.Price {
|
||||
modifyPricesList[storeID] = append(modifyPricesList[storeID], &jdapi.SkuPriceInfo{
|
||||
OutSkuId: utils.Int2Str(skuBind.SkuID),
|
||||
Price: promotionSkuPrice.Price*100/PromotionLimitedTimeMinPercentage + 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
promotionPrices[index] = map[string]interface{}{
|
||||
jdapi.KeyOutStationNo: utils.Int2Str(storeID),
|
||||
jdapi.KeyOutSkuId: utils.Int2Str(skuBind.SkuID),
|
||||
jdapi.KeyPromotionPrice: promotionSkuPrice.Price,
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
promotionPrices = promotionPrices[:index]
|
||||
if len(promotionPrices) == 0 {
|
||||
return "", ErrEmptySkus
|
||||
}
|
||||
if errMsg != "" {
|
||||
return "", errors.New(errMsg)
|
||||
}
|
||||
|
||||
promotion := &model.Promotion{
|
||||
Name: params.Name,
|
||||
VendorID: model.VendorIDJD,
|
||||
Type: params.Type,
|
||||
Status: PromotionStatusCreated,
|
||||
SyncStatus: model.SyncFlagNewMask,
|
||||
BeginAt: params.BeginAt,
|
||||
EndAt: params.EndAt,
|
||||
}
|
||||
dao.WrapAddIDCULDEntity(promotion, userName)
|
||||
if promotion.Params, err = jxutils.SerializeData(params); err != nil {
|
||||
return "", err
|
||||
}
|
||||
dao.Begin(db)
|
||||
defer func() {
|
||||
dao.Rollback(db)
|
||||
}()
|
||||
|
||||
if err = dao.CreateEntity(db, promotion); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var promotionHandler JdPromotionHandler
|
||||
if params.Type == PromotionTypeDirectDown {
|
||||
promotionHandler = &JdDirectDownHandler{}
|
||||
} else if params.Type == PromotionTypeLimitedTime {
|
||||
promotionHandler = &JdLimitedTimeHandler{}
|
||||
} else {
|
||||
panic(fmt.Sprintf("unknown promotion type:%d", params.Type))
|
||||
}
|
||||
infoId, err2 := promotionHandler.CreatePromotionInfos(params.Name, params.BeginAt, params.EndAt, utils.Int2Str(promotion.ID), params.Advertising)
|
||||
if err = err2; err != nil {
|
||||
return "", err
|
||||
}
|
||||
promotion.VendorPromotionID = utils.Int64ToStr(infoId)
|
||||
if _, err = dao.UpdateEntity(db, promotion); err != nil {
|
||||
return "", err
|
||||
}
|
||||
dao.Commit(db)
|
||||
|
||||
task := tasksch.RunTask("CreateJdPromotion update sku price", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
storeID := batchItemList[0].(int)
|
||||
modifyPricesList := jxutils.SplitSlice(modifyPricesList[storeID], jdapi.MaxStoreSkuBatchSize)
|
||||
for _, modifyPrices := range modifyPricesList {
|
||||
modifyPrices2 := make([]*jdapi.SkuPriceInfo, len(modifyPrices))
|
||||
for k, v := range modifyPrices {
|
||||
modifyPrices2[k] = v.(*jdapi.SkuPriceInfo)
|
||||
}
|
||||
if _, err = api.JdAPI.UpdateVendorStationPrice(utils.Int2Str(storeID), "", modifyPrices2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}, params.StoreIDs)
|
||||
if _, err = task.GetResult(0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err = promotionHandler.CreatePromotionRules(infoId, "", 1, 1, 1, 1); err != nil {
|
||||
return "", err
|
||||
}
|
||||
task = tasksch.RunManagedTask("CreateJdPromotion CreatePromotionSku", false, nil, 0, jdapi.MaxPromotionSkuCount, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
skus := make([]map[string]interface{}, len(batchItemList))
|
||||
for k, v := range batchItemList {
|
||||
skus[k] = v.(map[string]interface{})
|
||||
}
|
||||
_, err = promotionHandler.CreatePromotionSku(infoId, "", skus)
|
||||
return nil, err
|
||||
}, promotionPrices)
|
||||
if _, err = task.GetResult(0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = promotionHandler.ConfirmPromotion(infoId, "")
|
||||
|
||||
return "", err
|
||||
}
|
||||
Reference in New Issue
Block a user