Files
jx-callback/business/partner/purchase/mtwm/act.go
邹宗楠 7e471da34d 1
2024-02-26 17:22:29 +08:00

368 lines
13 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 mtwm
import (
"errors"
"strings"
"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/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/putils"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
func jxActType2Mtwm(actType int) int {
if actType == model.ActSkuDirectDown {
actType = mtwmapi.RetailActTypeDirectDown
} else if actType == model.ActSkuSecKill {
actType = mtwmapi.RetailActTypeSecKill
} else {
actType = 0
}
return actType
}
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(int8) bool) (actData []*mtwmapi.RetailDiscountActData) {
orderLimit := 1
if act.LimitCount > 0 {
orderLimit = act.LimitCount
}
for _, v := range actStoreSku {
if handler == nil || handler(v.SyncStatus) {
dayLimit := -1
if v.Stock > 0 {
dayLimit = v.Stock
}
actData = append(actData, &mtwmapi.RetailDiscountActData{
AppFoodCode: utils.Int2Str(v.SkuID),
// UserType: 0,
StartTime: act.BeginAt.Unix(),
EndTime: act.EndAt.Unix(),
OrderLimit: orderLimit,
DayLimit: dayLimit,
// Period: "",
// WeeksTime: "",
SettingType: mtwmapi.SettingTypeAsPrice,
ActPrice: jxutils.IntPrice2Standard(v.ActualActPrice),
// DiscountCoefficient: 0,
// Sequence: int(v.ActPrice), // 此字段不允许重复
// ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0),
})
}
}
return actData
}
func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int8) 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 int8) bool {
return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus)
}
func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) {
actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate)
if len(actData) > 0 {
if globals.EnableMtwmStoreWrite {
actResult, faileInfoList, err2 := api.MtwmAPI.RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData)
//5873
if err2 != nil && strings.Contains(err2.Error(), "未获取有效门店id") {
temp, err := dao.GetStoreDetailForDD(dao.GetDB(), 0, model.VendorIDMTWM, vendorStoreID, "")
if err == nil {
actResult, faileInfoList, err2 = getAPI(temp.VendorOrgCode, 0, vendorStoreID).RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData)
}
}
//actResult, faileInfoList, err2 := getAPI(tempStore.VendorOrgCode, 0, vendorStoreID).RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData)
err = err2
// 忽略错误都放在failedList里
// if err != nil {
// return nil, err
// }
actStoreSkuMap := make(map[int]*model.ActStoreSku2)
for _, v := range actStoreSku {
actStoreSkuMap[v.SkuID] = v
}
for _, v := range actResult {
if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil {
v2.VendorActID = utils.Int64ToStr(v.ActID)
}
}
for _, v := range faileInfoList {
if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil {
failedList = append(failedList, &partner.StoreSkuInfoWithErr{
StoreSkuInfo: &partner.StoreSkuInfo{
SkuID: v2.SkuID,
},
VendoreID: model.VendorIDMTWM,
StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)),
ErrMsg: v.ErrorMsg,
})
}
}
} else {
for _, v := range actStoreSku {
v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID())
}
}
}
return failedList, err
}
func cancelOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if list := storeSku2ActData4Delete(actStoreSku, nil /*model.IsSyncStatusNeedDelete*/); len(list) > 0 {
if globals.EnableMtwmStoreWrite {
failedList2, err2 := api.MtwmAPI.RetailDiscountDelete2(vendorStoreID, jxActType2Mtwm(act.Type), list)
globals.SugarLogger.Debugf("==============failedList2 := %s", utils.Format4Output(failedList2, false))
globals.SugarLogger.Debugf("==============err2 := %v", err2)
globals.SugarLogger.Debugf("==============vendorStoreID := %s", utils.Format4Output(vendorStoreID, false))
globals.SugarLogger.Debugf("============== jxActType2Mtwm(act.Type) := %s", utils.Format4Output(jxActType2Mtwm(act.Type), false))
globals.SugarLogger.Debugf("==============list := %s", utils.Format4Output(list, false))
actStoreSkuMap := make(map[string]*model.ActStoreSku2)
for _, v := range actStoreSku {
actStoreSkuMap[v.VendorActID] = v
}
for _, v := range failedList2 {
if !mtwmapi.CanDeleteActErrMsgIgnore(v.ErrorMsg) {
failedList = append(failedList, &partner.StoreSkuInfoWithErr{
StoreSkuInfo: &partner.StoreSkuInfo{
SkuID: actStoreSkuMap[utils.Int64ToStr(v.ActID)].SkuID,
},
StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)),
ErrMsg: v.ErrorMsg,
VendoreID: model.VendorIDMTWM,
})
}
}
err = err2
err = nil // 强制不返回错误,使用部分错误
}
}
return failedList, err
}
func getActStoreSkuFromTaskResult(taskReslt []interface{}) (list []*model.ActStoreSku2) {
for _, v := range taskReslt {
actStoreSkuList := v.([]*model.ActStoreSku2)
list = append(list, actStoreSkuList...)
}
return list
}
func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (createdList []*model.ActStoreSku2, err error) {
actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
task := tasksch.NewParallelTask("mtwm createSkuAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
list := batchItemList[0].([]*model.ActStoreSku2)
failedList, err2 := createOneShopAct(act, list[0].VendorStoreID, list)
if err = err2; err2 == nil {
if len(failedList) > 0 {
failedMap := putils.StoreSkuInfoWithErrList2MapBySku(failedList)
list = []*model.ActStoreSku2{}
for _, v := range actStoreSku {
if failedMap[v.SkuID] == nil {
list = append(list, v)
}
}
list = []*model.ActStoreSku2{}
}
retVal = []interface{}{list}
}
return retVal, err
}, actStoreSkuListList)
tasksch.HandleTask(task, parentTask, true).Run()
result, err := task.GetResult(0)
return getActStoreSkuFromTaskResult(result), err
}
func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) {
actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
task := tasksch.NewParallelTask("mtwm cancelSkuAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2)
if _, err = cancelOneShopAct(act, actStoreSkuList[0].VendorStoreID, actStoreSkuList); err == nil {
retVal = []interface{}{actStoreSkuList}
}
return retVal, err
}, actStoreSkuListList)
tasksch.HandleTask(task, parentTask, true).Run()
result, err := task.GetResult(0)
return getActStoreSkuFromTaskResult(result), err
}
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
var actStoreSkuList4Create, actStoreSkuList4Delete []*model.ActStoreSku2
var updateItems []*dao.KVUpdateItem
actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList)
for storeID := range actStoreSkuMap {
for _, actStoreSku := range actStoreSkuMap[storeID] {
if model.IsSyncStatusDelete(actStoreSku.SyncStatus) {
actStoreSkuList4Delete = append(actStoreSkuList4Delete, actStoreSku)
} else if model.IsSyncStatusNew(actStoreSku.SyncStatus) {
actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku)
}
}
}
globals.SugarLogger.Debugf("=========actStoreSkuList4Create := %s", utils.Format4Output(actStoreSkuList4Create, false))
err = func() (err error) {
globals.SugarLogger.Debugf("=========act := %s", utils.Format4Output(act, false))
if model.IsSyncStatusDelete(act.SyncStatus) {
globals.SugarLogger.Debugf("=========act := %s", "delete")
canceledList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList)
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...)
if err = err2; err == nil {
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
}
} else if model.IsSyncStatusNew(act.SyncStatus) {
globals.SugarLogger.Debugf("=========act := %s", "create")
createdList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create)
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, createdList, model.SyncFlagNewMask)...)
if err = err2; err == nil {
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask))
}
} else if model.IsSyncStatusUpdate(act.SyncStatus) {
globals.SugarLogger.Debugf("=========act := %s", "update")
if len(actStoreSkuList4Create) > 0 {
addedList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create)
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, addedList, model.SyncFlagNewMask)...)
if err = err2; err != nil {
return err
}
}
if len(actStoreSkuList4Delete) > 0 {
deletedList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList4Delete)
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...)
if err = err2; err != nil {
return err
}
}
if err == nil {
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
}
}
return err
}()
db := dao.GetDB()
_, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems)
if err == nil {
err = err2
}
return err
}
func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) {
for _, v := range mtwmapi.ActTypeList {
//1表示进行中
if actList, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetByAppPoiCodeAndType(vendorOrgCode, 1, v); err == nil {
ample += len(actList)
}
}
return ample, err
}
const (
ActTypeBuy = 1 //买赠活动
ActTypeDeduction = 2 //商品满减
ActTypeDirectDown = 3 //折扣(爆品)
ActTypeXM = 4 //X元M件
ActTypeN = 5 //第N件优惠
ActTypeDeductionAll = 0 //全店满减
ActTypeDeductionOne = 1 //指定商品满减
)
func GetActByAppPoiCode(vendorStoreID, vendorOrgCode string, sTime, eTime int64, actType int) (map[int]interface{}, error) {
if len(vendorStoreID) == 0 || len(vendorOrgCode) == 0 || sTime == 0 || eTime == 0 {
return nil, errors.New("未选中门店或时间,请检查")
}
var (
temp []interface{}
resp = make(map[int]interface{})
a = getAPI(vendorOrgCode, 0, vendorStoreID)
)
switch actType {
case ActTypeDeduction:
actInfo, err := a.FullDiscountList(vendorStoreID, ActTypeDeductionAll)
if err != nil {
return nil, err
}
//获取活动商品
for _, v := range actInfo {
sku, err := a.FullDiscountFoodsList(vendorStoreID, v.ActInfo.ActIDs)
//actID := utils.Str2Int(v.ActInfo.ActIDs)
if err != nil || sku == nil {
temp = append(temp, actInfo)
}
if CheckActTime(sTime, eTime, v.ActInfo.StartTime, v.ActInfo.EndTime) {
temp = append(temp, sku)
//temp[actID] = sku
}
}
resp[ActTypeDeduction] = temp
return resp, nil
case ActTypeDirectDown:
killInfo, err := a.RetailDiscountList(vendorStoreID, mtwmapi.RetailActTypeSecKill)
if err != nil || killInfo == nil {
resp[mtwmapi.RetailActTypeSecKill] = ""
} else {
for _, v := range killInfo {
if CheckActTime(sTime, eTime, v.StartTime, v.EndTime) {
temp = append(temp, v)
}
}
resp[mtwmapi.RetailActTypeSecKill] = temp
}
downInfo, err1 := a.RetailDiscountList(vendorStoreID, mtwmapi.RetailActTypeDirectDown)
if err1 != nil || downInfo == nil {
resp[mtwmapi.RetailActTypeDirectDown] = ""
} else {
for _, k := range downInfo {
if CheckActTime(sTime, eTime, k.StartTime, k.EndTime) {
temp = append(temp, k)
}
}
resp[mtwmapi.RetailActTypeDirectDown] = temp
}
return resp, nil
}
return nil, nil
}
func CheckActTime(startTime, endTime, sTime, eTime int64) bool {
if sTime > endTime || eTime < startTime {
return false
}
return true
}