Files
jx-callback/business/jxstore/act/act.go
gazebo 62f497fcaa - up
2019-06-20 16:08:26 +08:00

382 lines
12 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 act
import (
"fmt"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"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"
)
const (
ActionTypeNA = 0
)
type ActOrderRuleParam struct {
SalePrice int64 `orm:"" json:"salePrice"` // 满的价格
DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格
}
type ActStoreSkuParam struct {
model.ActStoreSku
Action int // -1删除1修改2新增
}
type ActDetail struct {
model.Act2
}
func ActStoreSkuParam2Map(actStoreSku []*ActStoreSkuParam) (actStoreSkuMap map[int][]*ActStoreSkuParam) {
if len(actStoreSku) > 0 {
for _, v := range actStoreSku {
actStoreSkuMap[v.StoreID] = append(actStoreSkuMap[v.StoreID], v)
}
}
return actStoreSkuMap
}
func genStoreSkuMapKey(storeID, skuID int) int64 {
return int64(storeID) + int64(skuID)*1000000
}
func ActStoreSkuParam2Model(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (actMapList []*model.ActMap, actStoreMapList []*model.ActStoreMap, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
if len(actStoreSku) > 0 {
storeIDMap := make(map[int]int)
skuIDMap := make(map[int]int)
storeSkuParamMap := make(map[int][]*ActStoreSkuParam)
for _, v := range actStoreSku {
storeIDMap[v.StoreID] = 1
skuIDMap[v.SkuID] = 1
storeSkuParamMap[v.StoreID] = append(storeSkuParamMap[v.StoreID], v)
}
db := dao.GetDB()
storeSkuList, err2 := dao.GetStoresSkusInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap))
if err = err2; err != nil {
return nil, nil, nil, nil, err
}
storeSkuMap := make(map[int64]*model.StoreSkuBind)
for _, v := range storeSkuList {
storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)] = v
}
wholeValidVendorMap := make(map[int]int)
for storeID, oneStoreSkuParam := range storeSkuParamMap {
validVendorMap := make(map[int]int)
validSkuMap := make(map[int]int)
for _, vendorID := range vendorIDs {
storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID)
if err = err2; err == nil {
for _, v := range oneStoreSkuParam {
if storeSkuInfo := storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
validVendorMap[vendorID] = 1
validSkuMap[v.SkuID] = 1
actSkuMap := &model.ActStoreSkuMap{
ActID: act.ID,
StoreID: storeID,
SkuID: v.SkuID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
if v.ActPrice != 0 {
actSkuMap.ActualActPrice = v.ActPrice
} else {
percentage := act.PricePercentage
if v.PricePercentage != 0 {
percentage = v.PricePercentage
}
percentage = percentage * int(storeDetail.PricePercentage) / 100
actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuVendorPrice(storeSkuInfo.Price, percentage, 0))
}
dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName())
actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap)
}
}
} else if !dao.IsNoRowsError(err) {
return nil, nil, nil, nil, err
} else {
err = nil
}
}
for _, v := range oneStoreSkuParam {
if validSkuMap[v.SkuID] == 1 {
if storeSkuInfo := storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
storeSku := &v.ActStoreSku
storeSku.ActID = act.ID
storeSku.OriginalPrice = int64(storeSkuInfo.Price)
dao.WrapAddIDCULDEntity(storeSku, ctx.GetUserName())
actStoreSkuList = append(actStoreSkuList, storeSku)
}
}
}
for vendorID := range validVendorMap {
wholeValidVendorMap[vendorID] = 1
actStoreMap := &model.ActStoreMap{
ActID: act.ID,
StoreID: storeID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
dao.WrapAddIDCULDEntity(actStoreMap, ctx.GetUserName())
actStoreMapList = append(actStoreMapList, actStoreMap)
}
}
for vendorID := range wholeValidVendorMap {
actMap := &model.ActMap{
ActID: act.ID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
actMapList = append(actMapList, actMap)
}
}
return actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList, err
}
func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) {
vendorIDMap := make(map[int]bool)
for _, v := range vendorIDs {
vendorIDMap[v] = true
}
db := dao.GetDB()
dao.WrapAddIDCULDEntity(act, ctx.GetUserName())
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
err = dao.CreateEntity(db, act)
if err != nil {
return 0, err
}
actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, act, vendorIDs, actStoreSku)
if err != nil {
return 0, err
}
isEmptyAct := true
for _, list := range []interface{}{
actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList,
} {
if len(utils.Interface2Slice(list)) > 0 {
err = dao.CreateMultiEntities(db, list)
if err != nil {
dao.Rollback(db)
return 0, err
}
isEmptyAct = false
}
}
if isEmptyAct {
dao.Rollback(db)
return 0, fmt.Errorf("没有门店及SKU满足需求空操作")
}
dao.Commit(db)
actID = act.ID
err = SyncAct(ctx, actID, nil, nil, nil)
return actID, err
}
func QueryActs(ctx *jxcontext.Context, actID int, keyword string, statusList []int, actTypeList []int, storeID, skuID int, beginAt, endAt time.Time) (actList []*model.Act, err error) {
return actList, err
}
func GetActDetail(ctx *jxcontext.Context, actID int) (actDetail *ActDetail, err error) {
return actDetail, err
}
// func GetAcVendorInfo(ctx *jxcontext.Context, actID int) (err error) {
// return err
// }
// func GetAcStoresVendorInfo(ctx *jxcontext.Context, actID int, storeIDs []int) (err error) {
// return err
// }
// func GetAcStoresSkusVendorInfo(ctx *jxcontext.Context, actID int, storeIDs, skuIDs []int) (err error) {
// return err
// }
func parseActStoreSkuParam(actStoreSku []*ActStoreSkuParam) {
}
func UpdateAct(ctx *jxcontext.Context, act *model.Act, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (err error) {
return err
}
func CancelAct(ctx *jxcontext.Context, actID int) (err error) {
db := dao.GetDB()
act := &model.Act{}
act.ID = actID
if err = dao.GetEntity(db, act); err != nil {
return err
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
dao.UpdateEntityLogically(db, act, map[string]interface{}{
model.FieldStatus: model.ActStatusCanceled,
}, ctx.GetUserName(), nil)
_, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, &model.ActMap{}, nil, ctx.GetUserName(), map[string]interface{}{
model.FieldActID: actID,
}, model.FieldSyncStatus, model.SyncFlagModifiedMask)
if err == nil {
dao.Commit(db)
globals.SugarLogger.Debugf("CancelAct track:%s", ctx.GetTrackInfo())
err = SyncAct(ctx, actID, nil, nil, nil)
} else {
dao.Rollback(db)
}
return err
}
func DeleteActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
storeIDMap := make(map[int]int)
skuIDMap := make(map[int]int)
actStoreSkuParamMap := make(map[int64]*ActStoreSkuParam)
for _, v := range actStoreSku {
storeIDMap[v.StoreID] = 1
skuIDMap[v.SkuID] = 1
actStoreSkuParamMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
}
db := dao.GetDB()
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap))
if err != nil {
return err
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
for _, v := range actStoreSkuMap {
for _, storeSku := range v {
storeSku.SyncStatus |= model.SyncFlagDeletedMask
if param := actStoreSkuParamMap[jxutils.Combine2Int(storeSku.StoreID, storeSku.SkuID)]; param != nil {
if _, err = dao.UpdateEntity(db, storeSku); err != nil {
return err
}
}
}
}
dao.Commit(db)
return err
}
func SyncAct(ctx *jxcontext.Context, actID int, vendorIDs, storeIDs, skuIDs []int) (err error) {
var actOrderRules []*model.ActOrderRule
db := dao.GetDB()
actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
if err != nil {
return err
}
actStoreMap, err := dao.GetActStoreVendorInfo(db, actID, vendorIDs, storeIDs)
if err != nil {
return err
}
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, vendorIDs, storeIDs, skuIDs)
if err != nil {
return err
}
var realVendorIDs []int
for vendorID := range actMap {
realVendorIDs = append(realVendorIDs, vendorID)
}
task := tasksch.NewParallelTask("SyncAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
vendorID := batchItemList[0].(int)
handler := partner.GetPurchasePlatformFromVendorID(vendorID)
if handler == nil {
err = fmt.Errorf("不被支持的vendorID:%d", vendorID)
} else {
act := actMap[vendorID]
actStore := actStoreMap[vendorID]
actStoreSku := actStoreSkuMap[vendorID]
// globals.SugarLogger.Debugf("%s", utils.Format4Output(act, false))
// globals.SugarLogger.Debugf("%s", utils.Format4Output(actStore, false))
// globals.SugarLogger.Debugf("%s", utils.Format4Output(actStoreSku, false))
if act != nil && actStore != nil && actStoreSku != nil {
if model.IsSyncStatusNeedCreate(act.SyncStatus) {
err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku)
} else if model.IsSyncStatusNeedUpdate(act.SyncStatus) {
if act.Status == model.ActStatusCanceled {
err = handler.CancelAct(ctx, task, act, actStore, actStoreSku)
} else {
// actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update := splitActStore(actStore)
// err = handler.UpdateAct(ctx, task, act, actOrderRules, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update, actStoreSku)
}
}
if err == nil {
actMap := &model.ActMap{}
actMap.ID = act.MapID
dao.UpdateEntityLogically(db, actMap, map[string]interface{}{
model.FieldSyncStatus: 0,
model.FieldVendorActID: act.VendorActID,
}, ctx.GetUserName(), nil)
for _, v := range actStore {
storeMap := model.ActStoreMap{}
storeMap.ID = v.MapID
dao.UpdateEntityLogically(db, storeMap, map[string]interface{}{
model.FieldSyncStatus: 0,
model.FieldVendorActID: v.VendorActID,
}, ctx.GetUserName(), nil)
}
for _, v := range actStoreSku {
storeSkuMap := model.ActStoreSkuMap{}
storeSkuMap.ID = v.MapID
dao.UpdateEntityLogically(db, storeSkuMap, map[string]interface{}{
model.FieldSyncStatus: 0,
model.FieldVendorActID: v.VendorActID,
}, ctx.GetUserName(), nil)
}
}
}
}
return nil, err
}, realVendorIDs)
tasksch.ManageTask(task).Run()
_, err = task.GetResult(0)
return err
}
func splitActStore(actStore []*model.ActStore2) (actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2) {
for _, v := range actStore {
if model.IsSyncStatusNeedDelete(v.SyncStatus) {
if !dao.IsVendorThingIDEmpty(v.VendorActID) {
actStoreMap2Remove = append(actStoreMap2Remove, v)
}
} else if model.IsSyncStatusNeedCreate(v.SyncStatus) {
actStoreMap2Add = append(actStoreMap2Add, v)
} else if model.IsSyncStatusNeedUpdate(v.SyncStatus) {
actStoreMap2Update = append(actStoreMap2Update, v)
}
}
return actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update
}