diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go new file mode 100644 index 000000000..11f840920 --- /dev/null +++ b/business/jxstore/act/act.go @@ -0,0 +1,319 @@ +package act + +import ( + "fmt" + "time" + + "git.rosy.net.cn/jx-callback/globals" + + "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/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" +) + +type ActOrderRuleParam struct { + SalePrice int64 `orm:"" json:"salePrice"` // 满的价格 + DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格 +} + +type ActStoreSkuParam struct { + Action int // -1删除,1修改,2新增 + + StoreID int `orm:"column(store_id)" json:"storeID"` + SkuID int `orm:"column(sku_id)" json:"skuID"` + + PricePercentage int `orm:"" json:"pricePercentage"` // 单品级活动用,SKU级的价格比例,非0覆盖Act中的PricePercentage + ActPrice int64 `orm:"" json:"actPrice"` // 单品级活动用,SKU级指定的价格,非0覆盖CustomPricePercentage与Act中的PricePercentage + + Stock int `orm:"" json:"stock"` // 订单级活动用 +} + +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 := &model.ActStoreSku{ + ActID: act.ID, + StoreID: v.StoreID, + SkuID: v.SkuID, + OriginalPrice: int64(storeSkuInfo.Price), + PricePercentage: v.PricePercentage, + ActPrice: v.ActPrice, + Stock: v.Stock, + } + 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 || err != nil { + dao.Rollback(db) + if r != nil { + 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 { + return 0, err + } + isEmptyAct = false + } + } + if isEmptyAct { + return 0, fmt.Errorf("没有门店及SKU满足需求,空操作") + } + dao.Commit(db) + 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 UpdateAct(ctx *jxcontext.Context, act *model.Act, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (err error) { + return err +} + +func DeleteAct(ctx *jxcontext.Context, actID int) (err error) { + 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.IsSyncStatusNeedDelete(act.SyncStatus) { + if !dao.IsVendorThingIDEmpty(act.VendorActID) { + } + } else if model.IsSyncStatusNeedCreate(act.SyncStatus) { + globals.SugarLogger.Debug("fuck") + err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku) + } else /*if model.IsSyncStatusNeedUpdate(act.SyncStatus)*/ { + 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 +} diff --git a/business/jxstore/act/act_test.go b/business/jxstore/act/act_test.go new file mode 100644 index 000000000..521906316 --- /dev/null +++ b/business/jxstore/act/act_test.go @@ -0,0 +1,61 @@ +package act + +import ( + "testing" + + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/globals/testinit" + + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals" + + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" +) + +func init() { + testinit.Init() +} + +func TestInitDb(t *testing.T) { + dao.ExecuteSQL(dao.GetDB(), ` + DROP TABLE IF EXISTS act,act_map, act_order_rule, act_store_map, act_store_sku, act_store_sku_map; + `) +} + +func TestCreateAct(t *testing.T) { + actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{ + Name: "测试活动2", + PricePercentage: 80, + }, []int{0, 1, 3}, nil, []*ActStoreSkuParam{ + &ActStoreSkuParam{ + StoreID: 100119, + SkuID: 30828, + }, + &ActStoreSkuParam{ + StoreID: 100119, + SkuID: 30827, + }, + &ActStoreSkuParam{ + StoreID: 100118, + SkuID: 30592, + }, + &ActStoreSkuParam{ + StoreID: 100118, + SkuID: 30565, + }, + }) + if err != nil { + t.Fatal(err) + } + globals.SugarLogger.Debug(actID) +} + +func TestSyncAct(t *testing.T) { + err := SyncAct(jxcontext.AdminCtx, 1, nil, nil, nil) + if err != nil { + t.Fatal(err) + } +} diff --git a/business/model/act.go b/business/model/act.go new file mode 100644 index 000000000..889533503 --- /dev/null +++ b/business/model/act.go @@ -0,0 +1,129 @@ +package model + +import "time" + +const ( + ActSkuDirectDown = 1 + ActSkuSecKill = 2 + + ActOrderBegin = 10 + ActOrderMoneyOff = 11 + ActOrderMoneyOffCoupon = 12 + ActOrderReduceFreight = 13 + ActOrderReduceFreightCoupon = 14 +) + +type Act struct { + ModelIDCULD + + Name string `orm:"size(64)" json:"name"` + Advertising string `orm:"size(255)" json:"advertising"` + Type int `json:"type"` + Status int `json:"status"` + LimitDevice int `json:"limitDevice"` + LimitPin int `json:"limitPin"` + LimitDaily int `json:"limitDaily"` + LimitCount int `json:"limitCount"` + Source string `orm:"size(255)" json:"source"` + CreateType int `json:"createType"` + PricePercentage int `json:"pricePercentage"` // 单品级活动才有效 + BeginAt time.Time `orm:"type(datetime);index;null" json:"beginAt"` + EndAt time.Time `orm:"type(datetime);index;null" json:"endAt"` +} + +type ActMap struct { + ModelIDCULD + + ActID int `orm:"column(act_id)" json:"actID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + SyncStatus int `orm:"default(2)" json:"syncStatus"` +} + +type Act2 struct { + MapID int `orm:"column(map_id)"` + + Act + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + SyncStatus int `orm:"default(2)" json:"syncStatus"` +} + +type ActOrderRule struct { + ModelIDCULD + + ActID int `orm:"column(act_id)" json:"actID"` + SalePrice int64 `orm:"" json:"salePrice"` // 满的价格 + DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格 +} + +// type ActStore struct { +// ModelIDCULD + +// ActID int `orm:"column(act_id)" json:"actID"` +// StoreID int `orm:"column(store_id)" json:"storeID"` +// } + +type ActStoreMap struct { + ModelIDCULD + + ActID int `orm:"column(act_id)" json:"actID"` + StoreID int `orm:"column(store_id)" json:"storeID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + SyncStatus int `orm:"default(2)" json:"syncStatus"` +} + +type ActStore2 struct { + MapID int `orm:"column(map_id)"` + + ActStoreMap + + VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"` +} + +type ActStoreSku struct { + ModelIDCULD + + ActID int `orm:"column(act_id)" json:"actID"` + StoreID int `orm:"column(store_id)" json:"storeID"` + SkuID int `orm:"column(sku_id)" json:"skuID"` + + // LocalStatus int // 这个状态是多个平台的 + // RemoteStatus int // 这个状态是多个平台的 + OriginalPrice int64 `orm:"" json:"originalPrice"` // 单品级活动用,创建活动时商品的原始京西价 + PricePercentage int `orm:"" json:"pricePercentage"` // 单品级活动用,SKU级的价格比例,非0覆盖Act中的PricePercentage + ActPrice int64 `orm:"" json:"actPrice"` // 单品级活动用,SKU级指定的价格,非0覆盖CustomPricePercentage与Act中的PricePercentage + + Stock int `orm:"" json:"stock"` // 订单级活动用 +} + +type ActStoreSkuMap struct { + ModelIDCULD + + ActID int `orm:"column(act_id)" json:"actID"` + StoreID int `orm:"column(store_id)" json:"storeID"` + SkuID int `orm:"column(sku_id)" json:"skuID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + SyncStatus int `orm:"default(2)" json:"syncStatus"` + ActualActPrice int64 `orm:"" json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格 +} + +type ActStoreSku2 struct { + MapID int `orm:"column(map_id)"` + + ActStoreSku + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + SyncStatus int `orm:"default(2)" json:"syncStatus"` + ActualActPrice int64 `orm:"" json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格 + + VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"` + VendorSkuID string `orm:"column(vendor_sku_id)" json:"vendorSkuID"` +} diff --git a/business/model/dao/act.go b/business/model/dao/act.go new file mode 100644 index 000000000..97b000667 --- /dev/null +++ b/business/model/dao/act.go @@ -0,0 +1,117 @@ +package dao + +import ( + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" +) + +func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*model.Act2, err error) { + sql := ` + SELECT t1.*, + t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status + FROM act t1 + JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ? + WHERE t1.deleted_at = ? AND t1.id = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + actID, + } + if len(vendorIDs) > 0 { + sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + var actList []*model.Act2 + if err = GetRows(db, &actList, sql, sqlParams...); err == nil { + actMap = make(map[int]*model.Act2) + for _, v := range actList { + actMap[v.VendorID] = v + } + } + return actMap, err +} + +func GetActStoreVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs []int) (actStoreMap map[int][]*model.ActStore2, err error) { + sql := ` + SELECT t1.*, + t1.id map_id, + t2.vendor_store_id + FROM act_store_map t1 + JOIN store_map t2 ON t2.store_id = t1.store_id AND t2.vendor_id = t1.vendor_id AND t2.deleted_at = ? + WHERE t1.deleted_at = ? AND t1.act_id = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + actID, + } + if len(vendorIDs) > 0 { + sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + if len(storeIDs) > 0 { + sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + var actStoreList []*model.ActStore2 + if err = GetRows(db, &actStoreList, sql, sqlParams...); err == nil { + actStoreMap = make(map[int][]*model.ActStore2) + for _, v := range actStoreList { + actStoreMap[v.VendorID] = append(actStoreMap[v.VendorID], v) + } + } + return actStoreMap, err +} + +func GetActStoreSkuVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int) (actStoreSkuMap map[int][]*model.ActStoreSku2, err error) { + sql := ` + SELECT t1.*, + t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, + t3.vendor_store_id, + CASE t2.vendor_id + WHEN 0 THEN + t4.jd_id + WHEN 1 THEN + t5.mtwm_id + WHEN 3 THEN + t5.ebai_id + ELSE + '' + END vendor_sku_id + FROM act_store_sku t1 + JOIN act_store_sku_map t2 ON t2.act_id = t1.act_id AND t2.sku_id = t1.sku_id AND t2.store_id = t1.store_id AND t2.deleted_at = ? + JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ? + JOIN sku t4 ON t4.id = t1.sku_id AND t4.deleted_at = ? + JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? + WHERE t1.deleted_at = ? AND t1.act_id = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + utils.DefaultTimeValue, + utils.DefaultTimeValue, + utils.DefaultTimeValue, + actID, + } + if len(vendorIDs) > 0 { + sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + if len(storeIDs) > 0 { + sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + if len(skuIDs) > 0 { + sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + var actStoreSkuList []*model.ActStoreSku2 + if err = GetRows(db, &actStoreSkuList, sql, sqlParams...); err == nil { + actStoreSkuMap = make(map[int][]*model.ActStoreSku2) + for _, v := range actStoreSkuList { + actStoreSkuMap[v.VendorID] = append(actStoreSkuMap[v.VendorID], v) + } + } + return actStoreSkuMap, err +} diff --git a/business/partner/partner.go b/business/partner/partner.go index 7229473a7..061193a46 100644 --- a/business/partner/partner.go +++ b/business/partner/partner.go @@ -172,6 +172,7 @@ type IStoreManager interface { // 所有非以Sync,Refresh开头的函数不用自己清理sync_status标记(VendorSync统一处理) type IPurchasePlatformHandler interface { + // IPurchasePlatformPromotionHandler GetVendorID() int GetStatusFromVendorStatus(vendorStatus string) int diff --git a/business/partner/partner_act.go b/business/partner/partner_act.go new file mode 100644 index 000000000..fa256e17d --- /dev/null +++ b/business/partner/partner_act.go @@ -0,0 +1,23 @@ +package partner + +import ( + "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" +) + +type IPurchasePlatformPromotionHandler interface { + // 如果是单品级活动,actOrderRules为空 + // 如果是订单级活动,actStoreSku可以为空(表示不限制SKU) + CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) + UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) + DeleteAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) +} + +func ActStoreSku2Map(actStoreSku []*model.ActStoreSku2) (actStoreSkuMap map[int][]*model.ActStoreSku2) { + actStoreSkuMap = make(map[int][]*model.ActStoreSku2) + for _, storeSku := range actStoreSku { + actStoreSkuMap[storeSku.StoreID] = append(actStoreSkuMap[storeSku.StoreID], storeSku) + } + return actStoreSkuMap +} diff --git a/business/partner/purchase/ebai/act.go b/business/partner/purchase/ebai/act.go new file mode 100644 index 000000000..607adc8ea --- /dev/null +++ b/business/partner/purchase/ebai/act.go @@ -0,0 +1,184 @@ +package ebai + +import ( + "git.rosy.net.cn/baseapi/platformapi/ebaiapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" + "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/partner" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +func actType2Ebai(actType int) int { + if actType < model.ActOrderBegin { + return ebaiapi.ActivityTypeDirectDown + } + return ebaiapi.ActivityTypeFullDiscount +} + +func actOrderRules2Ebai(actOrderRules []*model.ActOrderRule) (ebaiRules []*ebaiapi.ActivityRule) { + for _, v := range actOrderRules { + ebaiRules = append(ebaiRules, &ebaiapi.ActivityRule{ + Accords: int(jxutils.IntPrice2Standard(v.SalePrice)), + Sale: int(jxutils.IntPrice2Standard(v.DeductPrice)), + }) + } + return ebaiRules +} + +func actStoreSu2Ebai4Add(oneStoreActSku []*model.ActStoreSku2) (skus []*ebaiapi.ActivitySkuInfo4Add) { + for _, v := range oneStoreActSku { + if model.IsSyncStatusNeedCreate(v.SyncStatus) { + skus = append(skus, &ebaiapi.ActivitySkuInfo4Add{ + SkuID: v.VendorSkuID, + SpecialPrice: v.ActPrice, + }) + } + } + return skus +} + +func actStoreSu2Ebai4Update(oneStoreActSku []*model.ActStoreSku2) (skus []*ebaiapi.ActivitySkuInfo4Update) { + for _, v := range oneStoreActSku { + if model.IsSyncStatusNeedUpdate(v.SyncStatus) { + skus = append(skus, &ebaiapi.ActivitySkuInfo4Update{ + ShopID: utils.Int2Str(v.StoreID), + SkuID: v.VendorSkuID, + SpecialPrice: v.ActPrice, + }) + } + } + return skus +} + +func actStoreSu2Ebai4Delete(oneStoreActSku []*model.ActStoreSku2) (skus []string) { + for _, v := range oneStoreActSku { + if model.IsSyncStatusNeedDelete(v.SyncStatus) { + skus = append(skus, v.VendorSkuID) + } + } + return skus +} + +func act2EbaiActivity(act *model.Act2, actOrderRules []*model.ActOrderRule) (activity *ebaiapi.ActivityInfo) { + activity = &ebaiapi.ActivityInfo{ + ActivityName: act.Name, + ActivityType: actType2Ebai(act.Type), + StartTime: act.BeginAt.Unix(), + EndTime: act.EndAt.Unix(), + ActivityDesc: act.Advertising, + ShowCategory: act.Name, + PromotionSkuDesc: act.Name, + Rule: actOrderRules2Ebai(actOrderRules), + } + return activity +} + +func createOneShopAct(shopID string, activity *ebaiapi.ActivityInfo, oneStoreActSku []*model.ActStoreSku2) (ebaiActIDStr string, err error) { + if globals.EnableEbaiStoreWrite { + ebaiActID, err := api.EbaiAPI.ActivityCreate(shopID, 0, 0, activity) + if err == nil { + ebaiActIDStr = utils.Int64ToStr(ebaiActID) + _, err = ActivitySkuAddBatch(ebaiActID, shopID, 0, activity.ActivityType, actStoreSu2Ebai4Add(oneStoreActSku), false) + } + } else { + ebaiActIDStr = utils.Int64ToStr(jxutils.GenFakeID()) + } + return ebaiActIDStr, err +} + +func ActivitySkuAddBatch(activityID int64, shopID string, baiduShopID int64, activityType int, skuList []*ebaiapi.ActivitySkuInfo4Add, isSkuIDCustom bool) (successIDs []string, err error) { + return api.EbaiAPI.ActivitySkuAddBatch(activityID, shopID, baiduShopID, activityType, skuList, isSkuIDCustom) +} + +func ActivitySkuDeleteBatch(activityID int64, shopID string, baiduShopID int64, skuIDs []string, isSkuIDCustom bool) (successIDs []string, err error) { + return api.EbaiAPI.ActivitySkuDeleteBatch(activityID, shopID, baiduShopID, skuIDs, isSkuIDCustom) +} + +func ActivitySkuUpdateBatch(activityID int64, actSkuInfoList []*ebaiapi.ActivitySkuInfo4Update) (faildInfoList []string, err error) { + return api.EbaiAPI.ActivitySkuUpdateBatch(activityID, actSkuInfoList) +} + +func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + activity := act2EbaiActivity(act, actOrderRules) + if act.Type < model.ActOrderBegin { + actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku) + task := tasksch.NewParallelTask("ebai CreateAct", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + store := batchItemList[0].(*model.ActStore2) + store.VendorActID, err = createOneShopAct(utils.Int2Str(store.StoreID), activity, actStoreSkuMap[store.StoreID]) + return nil, err + }, actStoreMap) + tasksch.HandleTask(task, parentTask, true).Run() + _, err = task.GetResult(0) + } else { + + } + return err +} + +func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + if act.Type < model.ActOrderBegin { + actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku) + if len(actStoreMap2Remove) > 0 { + if err = c.DeleteAct(ctx, parentTask, act, actStoreMap2Remove, nil); err != nil { + return err + } + for _, v := range actStoreMap2Remove { + delete(actStoreSkuMap, v.StoreID) + } + } + if len(actStoreMap2Add) > 0 { + if err = c.CreateAct(ctx, parentTask, act, actOrderRules, actStoreMap2Add, actStoreSku); err != nil { + return err + } + for _, v := range actStoreMap2Add { + delete(actStoreSkuMap, v.StoreID) + } + } + task := tasksch.NewParallelTask("ebai UpdateAct", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + v := batchItemList[0].(*model.ActStore2) + if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil { + if list := actStoreSu2Ebai4Delete(storeSkus); len(list) > 0 { + if _, err = ActivitySkuDeleteBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, list, false); err != nil { + return nil, err + } + } + if list := actStoreSu2Ebai4Add(storeSkus); len(list) > 0 { + if _, err = ActivitySkuAddBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, actType2Ebai(act.Type), list, false); err != nil { + return nil, err + } + } + if list := actStoreSu2Ebai4Update(storeSkus); len(list) > 0 { + if _, err = ActivitySkuUpdateBatch(utils.Str2Int64(v.VendorActID), list); err != nil { + return nil, err + } + } + } + return nil, err + }, actStoreMap2Update) + tasksch.HandleTask(task, parentTask, true).Run() + _, err = task.GetResult(0) + } else { + + } + return err +} + +func (c *PurchaseHandler) DeleteAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + if act.Type < model.ActOrderBegin { + task := tasksch.NewParallelTask("ebai DeleteAct", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + v := batchItemList[0].(*model.ActStore2) + err = api.EbaiAPI.ActivityDisable(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, 0) + return nil, err + }, actStoreMap) + tasksch.HandleTask(task, parentTask, true).Run() + _, err = task.GetResult(0) + } + return err +} diff --git a/business/partner/purchase/elm/act.go b/business/partner/purchase/elm/act.go new file mode 100644 index 000000000..8a3ecbfff --- /dev/null +++ b/business/partner/purchase/elm/act.go @@ -0,0 +1,19 @@ +package elm + +import ( + "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" +) + +func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + return err +} + +func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + return err +} + +func (c *PurchaseHandler) DeleteAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + return err +} diff --git a/business/partner/purchase/jd/act.go b/business/partner/purchase/jd/act.go new file mode 100644 index 000000000..13319f837 --- /dev/null +++ b/business/partner/purchase/jd/act.go @@ -0,0 +1,183 @@ +package jd + +import ( + "time" + + "git.rosy.net.cn/jx-callback/business/jxutils" + + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" + + "git.rosy.net.cn/baseapi/platformapi/jdapi" + "git.rosy.net.cn/baseapi/utils" + "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" +) + +func CreatePromotionInfos(promotionType int, name string, beginDate, endDate time.Time, outInfoId, advertising, traceId string) (infoId int64, err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId) + } else { + return api.JdAPI.CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId) + } + } else { + infoId = jxutils.GenFakeID() + } + return infoId, err +} + +func CreatePromotionRules(promotionType int, infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int, traceId string) (err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) + } else { + return api.JdAPI.CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) + } + } + return err +} + +func CreatePromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.CreatePromotionSkuSingle(infoId, outInfoId, skus, traceId) + } else { + return api.JdAPI.CreatePromotionSkuLimitTime(infoId, outInfoId, skus, traceId) + } + } + return skusResult, err +} + +func CancelPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.CancelPromotionSkuSingle(infoId, outInfoId, skus, traceId) + } else { + return api.JdAPI.CancelPromotionSkuLimitTime(infoId, outInfoId, skus, traceId) + } + } + return err +} + +func ConfirmPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.ConfirmPromotionSingle(infoId, outInfoId, traceId) + } else { + return api.JdAPI.ConfirmPromotionLimitTime(infoId, outInfoId, traceId) + } + } + return err +} + +func CancelPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.CancelPromotionSingle(infoId, outInfoId, traceId) + } else { + return api.JdAPI.CancelPromotionLimitTime(infoId, outInfoId, traceId) + } + } + return err +} + +func AdjustPromotionTime(promotionType int, infoId int64, outInfoId string, endDate time.Time, traceId string) (err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId) + } else { + return api.JdAPI.AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId) + } + } + return err +} + +func AdjustPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { + if globals.EnableJdStoreWrite { + if promotionType == model.ActSkuDirectDown { + return api.JdAPI.AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId) + } else { + return api.JdAPI.AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId) + } + } + return skusResult, err +} + +func getTraceID(ctx *jxcontext.Context) (traceID string) { + traceID = ctx.GetUserName() + utils.GetUUID() + return traceID +} + +func storeSku2Jd(actStoreSku []*model.ActStoreSku2, handler func(syncStatus int) bool) (jdActStoreSku []*jdapi.PromotionSku) { + for _, v := range actStoreSku { + if handler(v.SyncStatus) { + jdActStoreSku = append(jdActStoreSku, &jdapi.PromotionSku{ + StationNo: utils.Str2Int64(v.VendorStoreID), + SkuID: utils.Str2Int64(v.VendorSkuID), + PromotionPrice: v.ActPrice, + // LimitSkuCount:0, + }) + } + } + return jdActStoreSku +} + +func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + traceID := getTraceID(ctx) + if act.Type < model.ActOrderBegin { + outInfoID := utils.Int2Str(act.ID) + infoID, err2 := CreatePromotionInfos(act.Type, act.Name, act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceID) + if err = err2; err == nil { + act.VendorActID = utils.Int64ToStr(infoID) + if err = CreatePromotionRules(act.Type, infoID, "", act.LimitDevice, act.LimitPin, act.LimitCount, act.LimitDaily, traceID); err == nil { + if _, err = CreatePromotionSku(act.Type, infoID, "", storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceID); err == nil { + err = ConfirmPromotion(act.Type, infoID, "", traceID) + } + } + } + } else { + + } + return err +} + +func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + traceID := getTraceID(ctx) + if act.Type < model.ActOrderBegin { + outInfoID := utils.Int2Str(act.ID) + if !utils.IsTimeZero(act.EndAt) { + if err = AdjustPromotionTime(act.Type, 0, outInfoID, act.EndAt, traceID); err != nil { + return err + } + } + if toBeDeleted := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeDeleted) > 0 { + if err = CancelPromotionSku(act.Type, 0, outInfoID, toBeDeleted, traceID); err != nil { + return err + } + } + // if toBeAdded := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeAdded) > 0 { + // if _, err = CreatePromotionSku(act.Type, 0, outInfoID, toBeAdded, traceID); err != nil { + // return err + // } + // } + // if toBeUpdated := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeUpdated) > 0 { + // if _, err = AdjustPromotionSku(act.Type, 0, outInfoID, toBeUpdated, traceID); err != nil { + // return err + // } + // } + } else { + + } + return err +} + +func (c *PurchaseHandler) DeleteAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + traceID := getTraceID(ctx) + if act.Type < model.ActOrderBegin { + outInfoID := utils.Int2Str(act.ID) + err = CancelPromotion(act.Type, 0, outInfoID, traceID) + } + return err +} diff --git a/business/partner/purchase/mtwm/act.go b/business/partner/purchase/mtwm/act.go new file mode 100644 index 000000000..7bb50c032 --- /dev/null +++ b/business/partner/purchase/mtwm/act.go @@ -0,0 +1,167 @@ +package mtwm + +import ( + "git.rosy.net.cn/baseapi/platformapi/mtwmapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" + "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/partner" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) { + for _, v := range actOrderRules { + actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{ + OriginalPrice: jxutils.IntPrice2Standard(v.SalePrice), + ActPrice: jxutils.IntPrice2Standard(v.DeductPrice), + }) + } + return actDetails +} + +func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int) bool) (actData []*mtwmapi.RetailDiscountActData) { + for _, v := range actStoreSku { + if handler == nil || handler(v.SyncStatus) { + actData = append(actData, &mtwmapi.RetailDiscountActData{ + AppFoodCode: utils.Int2Str(v.SkuID), + // UserType: 0, + StartTime: act.BeginAt.Unix(), + EndTime: act.EndAt.Unix(), + OrderLimit: act.LimitCount, + DayLimit: act.LimitDaily, + // Period: "", + // WeeksTime: "", + SettingType: mtwmapi.SettingTypeAsPrice, + ActPrice: jxutils.IntPrice2Standard(v.ActPrice), + // DiscountCoefficient: 0, + Sequence: int(v.ActPrice), + ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0), + }) + } + } + return actData +} + +func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int) bool) (actIDList []string) { + for _, v := range actStoreSku { + if handler == nil || handler(v.SyncStatus) { + if v.VendorActID != "" { + actIDList = append(actIDList, v.VendorActID) + } + } + } + return actIDList +} + +func isCreateOrUpdate(syncStatus int) bool { + return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus) +} + +func createOneShopAct(act *model.Act2, storeMap *model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate) + if len(actData) > 0 { + if globals.EnableMtwmStoreWrite { + actResult, err2 := api.MtwmAPI.RetailDiscountBatchSave(storeMap.VendorStoreID, actData) + if err = err2; err != nil { + return err + } + actResultMap := make(map[string]*mtwmapi.RetailDiscountActResult) + for _, v := range actResult { + actResultMap[v.AppFoodCode] = v + } + for _, v := range actStoreSku { + if result := actResultMap[utils.Int2Str(v.SkuID)]; result != nil { + v.VendorActID = utils.Int64ToStr(result.ActID) + } + } + } else { + for _, v := range actStoreSku { + v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID()) + } + } + } + return err +} + +func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + globals.SugarLogger.Debugf("mtwm CreateAct actID:%d", act.ID) + if act.Type < model.ActOrderBegin { + actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku) + task := tasksch.NewParallelTask("mtwm CreateAct", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + store := batchItemList[0].(*model.ActStore2) + err = createOneShopAct(act, store, actStoreSkuMap[store.StoreID]) + return nil, err + }, actStoreMap) + tasksch.HandleTask(task, parentTask, true).Run() + _, err = task.GetResult(0) + } else { + + } + return err +} + +func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + if act.Type < model.ActOrderBegin { + actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku) + if len(actStoreMap2Remove) > 0 { + if err = c.DeleteAct(ctx, parentTask, act, actStoreMap2Remove, nil); err != nil { + return err + } + for _, v := range actStoreMap2Remove { + delete(actStoreSkuMap, v.StoreID) + } + } + if len(actStoreMap2Add) > 0 { + if err = c.CreateAct(ctx, parentTask, act, actOrderRules, actStoreMap2Add, actStoreSku); err != nil { + return err + } + for _, v := range actStoreMap2Add { + delete(actStoreSkuMap, v.StoreID) + } + } + task := tasksch.NewParallelTask("mtwm UpdateAct", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + v := batchItemList[0].(*model.ActStore2) + if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil { + if list := storeSku2ActData4Delete(storeSkus, model.IsSyncStatusNeedDelete); len(list) > 0 { + if err = api.MtwmAPI.RetailDiscountDelete(v.VendorStoreID, list); err != nil { + return nil, err + } + } + if err = createOneShopAct(act, v, actStoreSkuMap[v.StoreID]); err != nil { + return nil, err + } + } + return nil, err + }, actStoreMap2Update) + tasksch.HandleTask(task, parentTask, true).Run() + _, err = task.GetResult(0) + } else { + + } + return err +} + +func (c *PurchaseHandler) DeleteAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + if act.Type < model.ActOrderBegin { + actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku) + task := tasksch.NewParallelTask("mtwm DeleteAct", nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + v := batchItemList[0].(*model.ActStore2) + actIDList := storeSku2ActData4Delete(actStoreSkuMap[v.StoreID], nil) + if len(actIDList) > 0 { + err = api.MtwmAPI.RetailDiscountDelete(v.VendorStoreID, actIDList) + } + return nil, err + }, actStoreMap) + tasksch.HandleTask(task, parentTask, true).Run() + _, err = task.GetResult(0) + } else { + + } + return err +} diff --git a/business/partner/purchase/weimob/wsc/act.go b/business/partner/purchase/weimob/wsc/act.go new file mode 100644 index 000000000..2cddfd4b9 --- /dev/null +++ b/business/partner/purchase/weimob/wsc/act.go @@ -0,0 +1,19 @@ +package wsc + +import ( + "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" +) + +func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + return err +} + +func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + return err +} + +func (c *PurchaseHandler) DeleteAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) { + return err +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 87226de45..0680b55d2 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -45,6 +45,8 @@ func Init() { // 如下语句建表时要出错(INDEX名字太长了),暂时放一下,必须放最后一句 orm.RegisterModel(&model.OrderFinancial{}, &model.AfsOrder{}, &model.OrderDiscountFinancial{}, &model.OrderSkuFinancial{}) + // orm.RegisterModel(&model.Act{}, &model.ActOrderRule{}, &model.ActStoreSku{}) + // orm.RegisterModel(&model.ActMap{}, &model.ActStoreMap{}, &model.ActStoreSkuMap{}) // create table orm.RunSyncdb("default", false, true) }