Files
jx-callback/business/jxstore/report/report.go
2020-04-22 09:09:06 +08:00

286 lines
9.8 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 report
import (
"errors"
"fmt"
"math"
"sort"
"time"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/baseapi/utils"
"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"
)
type tStoreSkuBindAndSkuName struct {
CityCode int
StoreID int `orm:"column(store_id)"`
NameID int `orm:"column(name_id)"`
UnitPrice int
UnitPriceList []int
}
func GetStatisticsReportForOrders(ctx *jxcontext.Context, storeIDs []int, fromDate string, toDate string) (statisticsReportForOrdersList []*dao.StatisticsReportForOrdersList, err error) {
db := dao.GetDB()
fromDateParm := utils.Str2Time(fromDate)
toDateParm := utils.Str2Time(toDate)
//若时间间隔大于3个月则不允许查询
if math.Ceil(toDateParm.Sub(fromDateParm).Hours()/24) > 92 {
return nil, errors.New(fmt.Sprintf("查询间隔时间不允许大于3个月: 时间范围:[%v] 至 [%v]", fromDate, toDate))
}
statisticsReportForOrdersList, err = dao.GetStatisticsReportForOrders(db, storeIDs, fromDateParm, toDateParm)
return statisticsReportForOrdersList, err
}
func GetStatisticsReportForAfsOrders(ctx *jxcontext.Context, storeIDs []int, fromDate string, toDate string) (statisticsReportForOrdersList []*dao.StatisticsReportForOrdersList, err error) {
db := dao.GetDB()
fromDateParm := utils.Str2Time(fromDate)
toDateParm := utils.Str2Time(toDate)
//若时间间隔大于3个月则不允许查询
if math.Ceil(toDateParm.Sub(fromDateParm).Hours()/24) > 92 {
return nil, errors.New(fmt.Sprintf("查询间隔时间不允许大于3个月: 时间范围:[%v] 至 [%v]", fromDate, toDate))
}
statisticsReportForOrdersList, err = dao.GetGetStatisticsReportForAfsOrders(db, storeIDs, fromDateParm, toDateParm)
return statisticsReportForOrdersList, err
}
func StatisticsReportForStoreSkusPrice(ctx *jxcontext.Context, cityCodes, skuIDs []int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
var snapDateParam time.Time
db := dao.GetDB()
if snapDate != "" {
snapDateParam = utils.Str2Time(snapDate)
}
priceReferSnapshot, totalCount, err := dao.GetPriceReferSnapshot(db, cityCodes, skuIDs, 0, snapDateParam, offset, pageSize)
pagedInfo = &model.PagedInfo{
Data: priceReferSnapshot,
TotalCount: totalCount,
}
return
}
func BeginSavePriceRefer(ctx *jxcontext.Context, cityCodes, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
var priceReferSnapshotList []*model.PriceReferSnapshot
db := dao.GetDB()
snapshotAt := utils.Time2Date(time.Now().AddDate(0, 0, -1))
dao.DeletePriceReferHistory(db, utils.Time2Date(snapshotAt.AddDate(0, 0, -7)))
priceReferSnapshotDelete := &model.PriceReferSnapshot{SnapshotAt: snapshotAt}
dao.DeleteEntity(db, priceReferSnapshotDelete, "SnapshotAt")
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step {
case 0:
priceReferSnapshot, err := dao.GetStatisticsReportForStoreSkusPrice(db, cityCodes, skuIDs)
if len(priceReferSnapshot) > 0 {
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
for _, v := range priceReferSnapshot {
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
v.SnapshotAt = snapshotAt
}
dao.CreateMultiEntities(db, priceReferSnapshot)
dao.Commit(db)
}
case 1:
priceReferSnapshotList, err = dao.GetPriceReferSnapshotNoPage(db, nil, nil, nil, snapshotAt)
var (
citySkuMap = make(map[int]map[int][]int)
countryMap = make(map[int][]int)
resultMap = make(map[int]map[int]*model.PriceReferSnapshot)
resultCountryMap = make(map[int]*model.PriceReferSnapshot)
)
storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "")
if err != nil {
return result, err
}
for _, v := range storeList {
if v.PayPercentage < 50 {
continue
}
var tList []*tStoreSkuBindAndSkuName
sql := `
SELECT DISTINCT b.city_code, a.store_id, Round(a.unit_price * IF(b.pay_percentage < 50 , 70, b.pay_percentage) / 100) AS unit_price, c.name_id
FROM store_sku_bind a
JOIN store b ON b.id = a.store_id AND b.deleted_at = ? AND b.status != ?
JOIN sku c ON c.id = a.sku_id
WHERE a.store_id = ?
AND c.name_id NOT IN(
SELECT b.name_id
FROM store_sku_bind a
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
WHERE a.deleted_at = ?
AND a.store_id = ?
AND b.name_id NOT IN(SELECT DISTINCT b.name_id
FROM store_sku_bind a
JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ?
WHERE a.deleted_at = ?
AND a.store_id = ?
AND a.status = ?)
)
AND a.deleted_at = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
model.StoreStatusDisabled,
v.ID,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
v.ID,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
v.ID,
model.StoreSkuBindStatusNormal,
utils.DefaultTimeValue,
}
dao.GetRows(db, &tList, sql, sqlParams...)
skuNameMap := make(map[int][]int)
if len(tList) > 0 {
for _, vv := range tList {
skuNameMap[vv.NameID] = append(skuNameMap[vv.NameID], vv.UnitPrice)
countryMap[vv.NameID] = append(countryMap[vv.NameID], vv.UnitPrice)
}
if citySkuMap[v.CityCode] != nil {
for nameID, unitPriceList := range skuNameMap {
if citySkuMap[v.CityCode][nameID] != nil {
citySkuMap[v.CityCode][nameID] = append(citySkuMap[v.CityCode][nameID], unitPriceList...)
} else {
citySkuMap[v.CityCode][nameID] = unitPriceList
}
}
} else {
citySkuMap[v.CityCode] = skuNameMap
}
}
}
for k, v := range countryMap {
var midUnitPrice int
var avgUnitPrice int
sort.Ints(v)
if len(v)%2 == 0 {
midUnitPrice = v[len(v)/2-1]
} else {
midUnitPrice = v[len(v)/2]
}
for _, vv := range v {
avgUnitPrice += vv
}
priceRefer := &model.PriceReferSnapshot{
MidUnitPrice: midUnitPrice,
MaxUnitPrice: v[len(v)-1],
MinUnitPrice: v[0],
AvgUnitPrice: avgUnitPrice / len(v),
}
resultCountryMap[k] = priceRefer
}
for k1, v := range citySkuMap {
skuNameMap := make(map[int]*model.PriceReferSnapshot)
for k2, _ := range v {
var midUnitPrice int
var avgUnitPrice int
sort.Ints(v[k2])
if len(v[k2])%2 == 0 {
midUnitPrice = v[k2][len(v[k2])/2-1]
} else {
midUnitPrice = v[k2][len(v[k2])/2]
}
for _, vv := range v[k2] {
avgUnitPrice += vv
}
skuNameMap[k2] = &model.PriceReferSnapshot{
MidUnitPrice: midUnitPrice,
MaxUnitPrice: v[k2][len(v[k2])-1],
MinUnitPrice: v[k2][0],
AvgUnitPrice: avgUnitPrice / len(v[k2]),
}
}
resultMap[k1] = skuNameMap
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
if len(priceReferSnapshotList) > 0 {
for _, v := range priceReferSnapshotList {
if v.CityCode == 0 {
if resultCountryMap[v.NameID] != nil {
v.MidUnitPrice = resultCountryMap[v.NameID].MidUnitPrice
v.MaxUnitPrice = resultCountryMap[v.NameID].MaxUnitPrice
v.AvgUnitPrice = resultCountryMap[v.NameID].AvgUnitPrice
v.MinUnitPrice = resultCountryMap[v.NameID].MinUnitPrice
dao.UpdateEntity(db, v, "MidUnitPrice", "MaxUnitPrice", "MinUnitPrice", "AvgUnitPrice")
}
continue
}
if resultMap[v.CityCode][v.NameID] != nil {
v.MidUnitPrice = resultMap[v.CityCode][v.NameID].MidUnitPrice
v.MaxUnitPrice = resultMap[v.CityCode][v.NameID].MaxUnitPrice
v.AvgUnitPrice = resultMap[v.CityCode][v.NameID].AvgUnitPrice
v.MinUnitPrice = resultMap[v.CityCode][v.NameID].MinUnitPrice
dao.UpdateEntity(db, v, "MidUnitPrice", "MaxUnitPrice", "MinUnitPrice", "AvgUnitPrice")
}
}
}
dao.Commit(db)
case 2:
dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
if r != nil {
panic(r)
}
}
}()
if len(priceReferSnapshotList) > 0 {
for _, v := range priceReferSnapshotList {
result, _ := dao.GetPriceReferPrice(db, v.CityCode, v.SkuID, snapshotAt)
v.MaxPrice = result.MaxPrice
v.MinPrice = result.MinPrice
v.AvgPrice = result.AvgPrice
v.MidPrice = result.MidPrice
dao.UpdateEntity(db, v, "MidPrice", "MaxPrice", "MinPrice", "AvgPrice")
}
}
dao.Commit(db)
//TODO 京东查询接口报错,暂时屏蔽了
// case 3:
// priceReferSnapshotList, err = dao.GetPriceReferSnapshotNoPage(db, []int{0}, nil, nil, snapshotAt)
// taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
// v := batchItemList[0].(*model.PriceReferSnapshot)
// for _, appOrg := range apimanager.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) {
// directPrice, _ := jd.GetAPI(appOrg).GetJdSkuDirectPrice(v.SkuID)
// v.JdDirectPrice = int(directPrice)
// dao.UpdateEntity(db, v, "JdDirectPrice")
// }
// return retVal, err
// }
// taskParallel := tasksch.NewParallelTask("获取并更新京东指导价格", tasksch.NewParallelConfig(), ctx, taskFunc, priceReferSnapshotList)
// tasksch.HandleTask(taskParallel, task, true).Run()
// _, err = taskParallel.GetResult(0)
}
return result, err
}
taskSeq := tasksch.NewSeqTask2("生成每日价格统计", ctx, isContinueWhenError, taskSeqFunc, 3)
tasksch.HandleTask(taskSeq, nil, true).Run()
if !isAsync {
_, err = taskSeq.GetResult(0)
hint = "1"
} else {
hint = taskSeq.GetID()
}
return hint, err
}