Files
jx-callback/business/jxstore/act/act.go

446 lines
14 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 (
"time"
"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/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 ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (validVendorIDs []int, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
wholeValidVendorMap := make(map[int]int)
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)
}
storeSkuList, err2 := dao.GetStoresSkusInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap))
if err = err2; err != nil {
return nil, nil, nil, err
}
storeSkuMap := make(map[int64]*model.StoreSkuBind)
for _, v := range storeSkuList {
storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
}
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[jxutils.Combine2Int(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)
}
}
wholeValidVendorMap[vendorID] = 1
} else if !dao.IsNoRowsError(err) {
return nil, nil, nil, err
} else {
err = nil
}
}
for _, v := range oneStoreSkuParam {
if validSkuMap[v.SkuID] == 1 { // todo 这里是否需要判断
if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(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)
}
}
}
}
}
return jxutils.IntMap2List(wholeValidVendorMap), actStoreSkuList, actStoreSkuMapList, err
}
func addActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap) (err error) {
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
storeSkuMap := make(map[int64]int)
for _, v := range actStoreSkuList {
err = dao.CreateEntity(db, v)
if err != nil {
dao.Rollback(db)
return err
}
storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v.ID
}
for _, v := range actStoreSkuMapList {
v.BindID = storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
}
if len(actStoreSkuMapList) > 0 {
err = dao.CreateMultiEntities(db, actStoreSkuMapList)
if err != nil {
dao.Rollback(db)
return err
}
}
dao.Commit(db)
return err
}
func AddActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
db := dao.GetDB()
var vendorIDs []int
actMap, err := dao.GetActVendorInfo(db, actID, nil)
if err != nil {
return err
}
for vendorID := range actMap {
vendorIDs = append(vendorIDs, vendorID)
}
var act *model.Act
if len(vendorIDs) > 0 {
act = &actMap[vendorIDs[0]].Act
} else {
act = &model.Act{}
act.ID = actID
if err = dao.GetEntity(db, act); err != nil {
return err
}
}
_, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku)
if err != nil {
return err
}
err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList)
return err
}
func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) {
db := dao.GetDB()
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
dao.WrapAddIDCULDEntity(act, ctx.GetUserName())
err = dao.CreateEntity(db, act)
if err != nil {
dao.Rollback(db)
return 0, err
}
validVendorIDs, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku)
if err != nil {
return 0, err
}
var actMapList []*model.ActMap
for vendorID := range validVendorIDs {
actMap := &model.ActMap{
ActID: act.ID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
actMapList = append(actMapList, actMap)
}
if len(actMapList) > 0 {
err = dao.CreateMultiEntities(db, actMapList)
if err != nil {
dao.Rollback(db)
return 0, err
}
}
if err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil {
dao.Rollback(db)
return 0, err
}
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 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()
if err = deleteActStoreBind(ctx, db, actID, nil); err != nil {
return err
}
err = SyncAct(ctx, actID, nil, nil, nil)
return err
}
func DeleteActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
return deleteActStoreBind(ctx, dao.GetDB(), actID, actStoreSku)
}
func deleteActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSkuParam []*ActStoreSkuParam) (err error) {
actMap, err := dao.GetActVendorInfo(db, actID, nil)
if err != nil {
return err
}
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil)
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)
}
}
}()
actStoreSkuParamMap := make(map[int64]*ActStoreSkuParam)
for _, v := range actStoreSkuParam {
actStoreSkuParamMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
if _, err = dao.DeleteEntityLogically(db, &model.ActStoreSku{}, nil, ctx.GetUserName(),
map[string]interface{}{
model.FieldActID: actID,
model.FieldStoreID: v.StoreID,
model.FieldSkuID: v.SkuID,
}); err != nil {
return err
}
}
isNeedCancelAct := true
for vendorID, act := range actMap {
isDeleteAll := true
isDeleteAtLeastOne := false
actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuMap[vendorID])
for storeID := range actStoreSkuMap {
for _, actStoreSku := range actStoreSkuMap[storeID] {
if actStoreSkuParam == nil || actStoreSkuParamMap[jxutils.Combine2Int(actStoreSku.StoreID, actStoreSku.SkuID)] != nil {
if _, err = dao.UpdateEntityLogically(db, partner.ActStoreSku2ActStoreSkuMap(actStoreSku),
map[string]interface{}{
model.FieldSyncStatus: actStoreSku.SyncStatus | model.SyncFlagDeletedMask,
}, ctx.GetUserName(), nil); err != nil {
return err
}
isDeleteAtLeastOne = true
} else {
isNeedCancelAct = false
isDeleteAll = false
}
}
}
if isDeleteAll || isDeleteAtLeastOne {
// globals.SugarLogger.Debugf("isDeleteAll:%t", isDeleteAll)
syncStatus := model.SyncFlagModifiedMask
if isDeleteAll {
syncStatus = model.SyncFlagDeletedMask
}
syncStatus |= act.SyncStatus
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
map[string]interface{}{
model.FieldSyncStatus: syncStatus,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
if isDeleteAll != isNeedCancelAct {
globals.SugarLogger.Warnf("deleteActStoreBind, actID:%d isDeleteAll:%t != isNeedCancelAct:%t", act.ID, isDeleteAll, isNeedCancelAct)
}
}
if isNeedCancelAct {
act := &model.Act{}
act.ID = actID
if _, err = dao.UpdateEntityLogically(db, act,
map[string]interface{}{
model.FieldStatus: model.ActStatusCanceled,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
dao.Commit(db)
return err
}
func SyncAct(ctx *jxcontext.Context, actID int, vendorIDs, storeIDs, skuIDs []int) (err error) {
db := dao.GetDB()
actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
if err != nil {
return err
}
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, storeIDs, skuIDs)
if err != nil {
return err
}
for vendorID := range actMap {
if handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformActHandler); handler != nil {
if err = handler.SyncAct(ctx, nil, actMap[vendorID], nil, actStoreSkuMap[vendorID]); err != nil {
return err
}
}
}
return err
// 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
// }