package service import ( "database/sql" "electricity_bill_calc/cache" "electricity_bill_calc/config" "electricity_bill_calc/exceptions" "electricity_bill_calc/global" "electricity_bill_calc/logger" "electricity_bill_calc/model" "electricity_bill_calc/tools" "fmt" "strconv" "time" "github.com/fufuok/utils" "github.com/google/uuid" "github.com/samber/lo" "github.com/shopspring/decimal" "github.com/uptrace/bun" "go.uber.org/zap" ) type _ReportService struct { l *zap.Logger } var ReportService = _ReportService{ l: logger.Named("Service", "Report"), } func (_ReportService) FetchParksWithNewestReport(uid string) ([]model.ParkNewestReport, error) { if cachedParks, _ := cache.RetreiveSearch[[]model.ParkNewestReport]("park_newest_report", uid); cachedParks != nil { return *cachedParks, nil } ctx, cancel := global.TimeoutContext() defer cancel() parks := make([]model.Park, 0) err := global.DB.NewSelect().Model(&parks).Relation("Reports"). Where("user_id = ?", uid). Where("enabled = ?", true). Order("created_at asc"). Scan(ctx) if err != nil { return make([]model.ParkNewestReport, 0), err } reducedParks := lo.Reduce( parks, func(acc map[string]model.ParkNewestReport, elem model.Park, index int) map[string]model.ParkNewestReport { if _, ok := acc[elem.Id]; !ok { newestReport := lo.MaxBy(elem.Reports, func(a, b *model.Report) bool { return a.Period.After(b.Period) }) acc[elem.Id] = model.ParkNewestReport{ Report: newestReport, Park: elem, } } return acc }, make(map[string]model.ParkNewestReport, 0), ) relations := lo.Map(parks, func(r model.Park, _ int) string { return fmt.Sprintf("park:%s", r.Id) }) relations = append(relations, "park", "report") cache.CacheSearch(reducedParks, relations, "park_newest_report", uid) return lo.Values(reducedParks), nil } func (_ReportService) IsNewPeriodValid(uid, pid string, period time.Time) (bool, error) { ctx, cancel := global.TimeoutContext() defer cancel() reports := make([]model.Report, 0) if cachedReport, _ := cache.RetreiveSearch[[]model.Report]("report", "user", uid, "park", pid); cachedReport != nil { reports = *cachedReport } else { err := global.DB.NewSelect().Model(&reports).Relation("Park"). Where("park.user_id = ?", uid). Where("r.park_id = ?", pid). Scan(ctx) if err != nil { return false, err } cache.CacheSearch(reports, []string{"report", "park"}, "park", "user", uid, "park", pid) } // 检查给定的期数在目前的记录中是否已经存在 exists := lo.Reduce( reports, func(acc bool, elem model.Report, index int) bool { if elem.Period.Equal(period) { return acc || true } else { return acc || false } }, false, ) if exists { return false, nil } // 检查给定的期数与目前已发布的最大期数的关系 maxPublished := lo.Reduce( reports, func(acc *time.Time, elem model.Report, index int) *time.Time { if elem.Published { if acc == nil || (acc != nil && elem.Period.After(*acc)) { return &elem.Period } } return acc }, nil, ) // 检查给定的期数与目前未发布的最大期数的关系 maxUnpublished := lo.Reduce( reports, func(acc *time.Time, elem model.Report, index int) *time.Time { if acc == nil || (acc != nil && elem.Period.After(*acc)) { return &elem.Period } return acc }, nil, ) if maxUnpublished == nil { return true, nil } if maxPublished != nil && maxUnpublished.Equal(*maxPublished) { // 此时不存在未发布的报表 return tools.IsNextMonth(*maxPublished, period), nil } else { // 存在未发布的报表 return false, nil } } func (_ReportService) InitializeNewReport(parkId string, period time.Time) (string, error) { ctx, cancel := global.TimeoutContext() defer cancel() periods := make([]model.Report, 0) err := global.DB.NewSelect().Model(&periods). Where("park_id = ?", parkId). Where("published = ?", true). Order("period asc"). Scan(ctx) if err != nil { return "", err } // 获取上一期的报表索引信息 maxPublishedReport := lo.Reduce( periods, func(acc *model.Report, elem model.Report, index int) *model.Report { if acc == nil || (acc != nil && elem.Period.After(acc.Period)) { return &elem } return acc }, nil, ) var indexedLastPeriodCustomers map[string]model.EndUserDetail if maxPublishedReport != nil { // 获取上一期的所有户表信息,并获取当前已启用的所有用户 lastPeriodCustomers := make([]model.EndUserDetail, 0) err = global.DB.NewSelect().Model(&lastPeriodCustomers). Where("report_id = ?", maxPublishedReport.Id). Scan(ctx) if err != nil { return "", err } indexedLastPeriodCustomers = lo.Reduce( lastPeriodCustomers, func(acc map[string]model.EndUserDetail, elem model.EndUserDetail, index int) map[string]model.EndUserDetail { acc[elem.MeterId] = elem return acc }, make(map[string]model.EndUserDetail, 0), ) } else { indexedLastPeriodCustomers = make(map[string]model.EndUserDetail, 0) } currentActivatedCustomers := make([]model.Meter04KV, 0) err = global.DB.NewSelect().Model(¤tActivatedCustomers). Where("park_id = ?", parkId). Where("enabled = ?", true). Scan(ctx) if err != nil { return "", err } var parkInfo = new(model.Park) err = global.DB.NewSelect().Model(parkInfo). Where("id = ?", parkId). Scan(ctx) if err != nil || parkInfo == nil { return "", exceptions.NewNotFoundError(fmt.Sprintf("指定园区未找到, %v", err)) } // 生成新一期的报表 tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return "", err } // 插入已经生成的报表索引信息和园区概况信息 newReport := model.Report{ Id: uuid.New().String(), ParkId: parkId, Period: period, Category: parkInfo.Category, SubmeterType: parkInfo.SubmeterType, StepState: model.NewSteps(), Published: false, Withdraw: model.REPORT_NOT_WITHDRAW, } newReportSummary := model.ReportSummary{ ReportId: newReport.Id, } _, err = tx.NewInsert().Model(&newReport).Exec(ctx) if err != nil { tx.Rollback() return "", err } _, err = tx.NewInsert().Model(&newReportSummary).Exec(ctx) if err != nil { tx.Rollback() return "", err } // 生成并插入户表信息 for _, customer := range currentActivatedCustomers { newEndUser := model.EndUserDetail{ ReportId: newReport.Id, ParkId: parkId, MeterId: customer.Code, Seq: customer.Seq, Ratio: customer.Ratio, Address: customer.Address, CustomerName: customer.CustomerName, ContactName: customer.ContactName, ContactPhone: customer.ContactPhone, IsPublicMeter: customer.IsPublicMeter, WillDilute: customer.WillDilute, LastPeriodOverall: decimal.Zero, LastPeriodCritical: decimal.Zero, LastPeriodPeak: decimal.Zero, LastPeriodFlat: decimal.Zero, LastPeriodValley: decimal.Zero, } if lastPeriod, ok := indexedLastPeriodCustomers[customer.Code]; ok { newEndUser.LastPeriodOverall = lastPeriod.CurrentPeriodOverall newEndUser.LastPeriodCritical = lastPeriod.CurrentPeriodCritical newEndUser.LastPeriodPeak = lastPeriod.CurrentPeriodPeak newEndUser.LastPeriodFlat = lastPeriod.CurrentPeriodFlat newEndUser.LastPeriodValley = lastPeriod.CurrentPeriodValley } _, err = tx.NewInsert().Model(&newEndUser).Exec(ctx) if err != nil { tx.Rollback() return "", err } } err = tx.Commit() if err != nil { tx.Rollback() return "", err } cache.AbolishRelation("report") return newReport.Id, nil } func (_ReportService) RetreiveReportIndex(rid string) (*model.Report, error) { if cachedReport, _ := cache.RetreiveEntity[model.Report]("report", rid); cachedReport != nil { return cachedReport, nil } ctx, cancel := global.TimeoutContext() defer cancel() var report = new(model.Report) err := global.DB.NewSelect().Model(report). Where("id = ?", rid). Scan(ctx) if err != nil { return nil, err } cache.CacheEntity(report, []string{fmt.Sprintf("report:%s", rid), "park"}, "report", rid) return report, nil } func (_ReportService) RetreiveReportSummary(rid string) (*model.ReportSummary, error) { if cachedSummary, _ := cache.RetreiveEntity[model.ReportSummary]("report_summary", rid); cachedSummary != nil { return cachedSummary, nil } ctx, cancel := global.TimeoutContext() defer cancel() var summary = new(model.ReportSummary) err := global.DB.NewSelect().Model(summary). Where("report_id = ?", rid). Scan(ctx) if err != nil { return nil, err } cache.CacheEntity(summary, []string{fmt.Sprintf("report:%s", rid), "park"}, "report_summary", rid) return summary, nil } func (_ReportService) UpdateReportSummary(summary *model.ReportSummary) error { ctx, cancel := global.TimeoutContext() defer cancel() _, err := global.DB.NewUpdate().Model(summary). WherePK(). Column("overall", "overall_fee", "critical", "critical_fee", "peak", "peak_fee", "valley", "valley_fee", "basic_fee", "adjust_fee"). Exec(ctx) if err == nil { cache.AbolishRelation(fmt.Sprintf("report:%s", summary.ReportId)) } return err } func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error { ctx, cancel := global.TimeoutContext() defer cancel() var report = new(model.Report) err := global.DB.NewSelect().Model(report).Relation("Summary"). Where("r.id = ?", reportId). Scan(ctx) if err != nil || report == nil { return exceptions.NewNotFoundErrorFromError("未找到指定报表", err) } tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return err } report.Summary.CalculatePrices() _, err = tx.NewUpdate().Model(report.Summary). WherePK(). Column("overall_price", "critical_price", "peak_price", "flat", "flat_fee", "flat_price", "valley_price", "consumption_fee"). Exec(ctx) if err != nil { tx.Rollback() return err } report.StepState.Summary = true _, err = tx.NewUpdate().Model(report). WherePK(). Column("step_state"). Exec(ctx) if err != nil { tx.Rollback() return err } err = tx.Commit() if err != nil { tx.Rollback() return err } cache.AbolishRelation(fmt.Sprintf("report:%s", reportId)) return nil } func (_ReportService) FetchWillDulutedMaintenanceFees(reportId string) ([]model.WillDilutedFee, error) { if cachedFees, _ := cache.RetreiveSearch[[]model.WillDilutedFee]("will_diluted_fee", "report", reportId); cachedFees != nil { return *cachedFees, nil } ctx, cancel := global.TimeoutContext() defer cancel() fees := make([]model.WillDilutedFee, 0) err := global.DB.NewSelect().Model(&fees). Where("report_id = ?", reportId). Order("created_at asc"). Scan(ctx) if err != nil { return make([]model.WillDilutedFee, 0), nil } relations := lo.Map(fees, func(f model.WillDilutedFee, _ int) string { return fmt.Sprintf("will_diluted_fee:%s", f.Id) }) relations = append(relations, fmt.Sprintf("report:will_diluted_fee:%s", reportId), fmt.Sprintf("report:%s", reportId), "park") cache.CacheSearch(fees, relations, "will_diluted_fee", "report", reportId) return fees, nil } func (_ReportService) CreateTemporaryWillDilutedMaintenanceFee(fee model.WillDilutedFee) error { ctx, cancel := global.TimeoutContext() defer cancel() fee.Id = utils.UUIDString() _, err := global.DB.NewInsert().Model(&fee).Exec(ctx) cache.AbolishRelation(fmt.Sprintf("report:will_diluted_fee:%s", fee.ReportId)) return err } func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.WillDilutedFee) error { ctx, cancel := global.TimeoutContext() defer cancel() tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return err } // 首先删除所有预定义的部分,条件是指定报表ID,SourceID不为空。 _, err = tx.NewDelete().Model((*model.WillDilutedFee)(nil)). Where("report_id = ?", reportId). Where("source_id is not null"). Exec(ctx) if err != nil { tx.Rollback() return err } // 然后插入新的记录 _, err = tx.NewInsert().Model(&fees).Exec(ctx) if err != nil { return err } err = tx.Commit() if err != nil { tx.Rollback() return err } cache.AbolishRelation(fmt.Sprintf("report:will_diluted_fee:%s", reportId)) return nil } func (_ReportService) UpdateMaintenanceFee(feeId string, updates map[string]interface{}) (err error) { ctx, cancel := global.TimeoutContext() defer cancel() updates["last_modified_at"] = lo.ToPtr(time.Now()) _, err = global.DB.NewUpdate().Model(&updates).TableExpr("will_diluted_fee"). Where("id = ?", feeId). Exec(ctx) cache.AbolishRelation(fmt.Sprintf("will_diluted_fee:%s", feeId)) return } func (_ReportService) DeleteWillDilutedFee(fee string) (err error) { ctx, cancel := global.TimeoutContext() defer cancel() _, err = global.DB.NewDelete().Model((*model.WillDilutedFee)(nil)). Where("id = ?", fee). Exec(ctx) cache.AbolishRelation(fmt.Sprintf("will_diluted_fee:%s", fee)) return } func (_ReportService) ProgressReportWillDilutedFee(report model.Report) (err error) { ctx, cancel := global.TimeoutContext() defer cancel() report.StepState.WillDiluted = true _, err = global.DB.NewUpdate().Model(&report). WherePK(). Column("step_state"). Exec(ctx) cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) ProgressReportRegisterEndUser(report model.Report) (err error) { ctx, cancel := global.TimeoutContext() defer cancel() report.StepState.Submeter = true _, err = global.DB.NewUpdate().Model(&report). WherePK(). Column("step_state"). Exec(ctx) cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) ProgressReportCalculate(report model.Report) (err error) { ctx, cancel := global.TimeoutContext() defer cancel() report.StepState.Calculate = true _, err = global.DB.NewUpdate().Model(&report). WherePK(). Column("step_state"). Exec(ctx) cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) RetreiveParkEndUserMeterType(reportId string) (int, error) { if cachedType, _ := cache.RetreiveEntity[int]("park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)); cachedType != nil { return *cachedType, nil } ctx, cancel := global.TimeoutContext() defer cancel() var mType int err := global.DB.NewSelect().Model((*model.Report)(nil)). Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery { return q.Column("meter_04kv_type") }). ExcludeColumn("*"). Where("r.id = ?", reportId). Scan(ctx, &mType) if err != nil { return -1, err } cache.CacheEntity(mType, []string{fmt.Sprintf("report:%s", reportId), "park"}, "park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)) return mType, nil } func (_ReportService) PublishReport(report model.Report) (err error) { ctx, cancel := global.TimeoutContext() defer cancel() report.Published = true report.PublishedAt = lo.ToPtr(time.Now()) report.StepState.Publish = true _, err = global.DB.NewUpdate().Model(&report). WherePK(). Column("step_state", "published", "published_at"). Exec(ctx) cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword string, requestPeriod *time.Time, requestPage int, onlyPublished bool) ([]model.JoinedReportForWithdraw, int64, error) { var ( conditions = make([]string, 0) reports = make([]model.Report, 0) cond = global.DB.NewSelect(). Model(&reports). Relation("Park").Relation("Park.Enterprise") ) conditions = append(conditions, strconv.Itoa(requestPage)) if onlyPublished { cond = cond.Where("r.published = ?", true) } conditions = append(conditions, strconv.FormatBool(onlyPublished)) if len(requestUser) > 0 { cond = cond.Where("park.user_id = ?", requestUser) conditions = append(conditions, requestUser) } if len(requestPark) > 0 { cond = cond.Where("park.id = ?", requestPark) conditions = append(conditions, requestPark) } if requestPeriod != nil { cond = cond.Where("r.period = ?", *requestPeriod) conditions = append(conditions, strconv.FormatInt(requestPeriod.Unix(), 10)) } if len(requestKeyword) > 0 { keywordCond := "%" + requestKeyword + "%" cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery { return q.Where("park.name like ?", keywordCond). WhereOr("park__enterprise.name like ?", keywordCond). WhereOr("park__enterprise.abbr like ?", keywordCond). WhereOr("park.abbr like ?", keywordCond). WhereOr("park__enterprise.address like ?", keywordCond). WhereOr("park.address like ?", keywordCond) }) conditions = append(conditions, requestKeyword) } if cachedTotal, err := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 && err == nil { if cachedRecords, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_report_for_withdraw", conditions...); cachedRecords != nil { return *cachedRecords, cachedTotal, nil } } ctx, cancel := global.TimeoutContext() defer cancel() startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize total, err := cond.Limit(config.ServiceSettings.ItemsPageSize). Offset(startItem). ScanAndCount(ctx) records := make([]model.JoinedReportForWithdraw, 0) relations := []string{"report", "park"} for _, r := range reports { records = append(records, model.JoinedReportForWithdraw{ Report: r, Park: model.FromPark(*r.Park), User: model.FromUserDetail(*r.Park.Enterprise), }) relations = append(relations, fmt.Sprintf("report:%s", r.Id)) } cache.CacheCount(relations, "join_report_for_withdraw", int64(total), conditions...) cache.CacheSearch(records, relations, "join_report_for_withdraw", conditions...) return records, int64(total), err } func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity, error) { if cachedPublicity, _ := cache.RetreiveEntity[model.Publicity]("publicity", reportId); cachedPublicity != nil { return cachedPublicity, nil } // 资料准备 ctx, cancel := global.TimeoutContext() defer cancel() var report = new(model.Report) err := global.DB.NewSelect().Model(report). Relation("Summary").Relation("WillDilutedFees").Relation("EndUsers"). Relation("Park").Relation("Park.Enterprise"). Where("r.id = ?", reportId). Scan(ctx) if err != nil { return nil, exceptions.NewNotFoundErrorFromError("未找到指定的公示报表", err) } // 组合数据 paidPart := model.PaidPart{ Overall: report.Summary.Overall, OverallPrice: report.Summary.OverallPrice.Decimal, ConsumptionFee: report.Summary.ConsumptionFee.Decimal, OverallFee: report.Summary.OverallFee, Critical: decimal.NewNullDecimal(report.Summary.Critical), CriticalPrice: report.Summary.CriticalPrice, CriticalFee: decimal.NewNullDecimal(report.Summary.CriticalFee), Peak: decimal.NewNullDecimal(report.Summary.Peak), PeakPrice: report.Summary.PeakPrice, PeakFee: decimal.NewNullDecimal(report.Summary.PeakFee), Flat: decimal.NewNullDecimal(report.Summary.Flat), FlatPrice: report.Summary.FlatPrice, FlatFee: decimal.NewNullDecimal(report.Summary.FlatFee), Valley: decimal.NewNullDecimal(report.Summary.Valley), ValleyPrice: report.Summary.ValleyPrice, ValleyFee: decimal.NewNullDecimal(report.Summary.ValleyFee), BasicFee: report.Summary.BasicFee, AdjustFee: report.Summary.AdjustFee, } endUserSummary := model.EndUserOverallPart{ Overall: report.Summary.CustomerConsumption.Decimal, OverallPrice: report.Summary.OverallPrice.Decimal, OverallFee: report.Summary.CustomerConsumptionFee.Decimal, Critical: report.Summary.CustomerConsumptionCritical, CriticalPrice: report.Summary.CriticalPrice, CriticalFee: report.Summary.CustomerConsumptionCriticalFee, Peak: report.Summary.CustomerConsumptionPeak, PeakPrice: report.Summary.PeakPrice, PeakFee: report.Summary.CustomerConsumptionPeakFee, Flat: report.Summary.CustomerConsumptionFlat, FlatPrice: report.Summary.FlatPrice, FlatFee: report.Summary.CustomerConsumptionFlatFee, Valley: report.Summary.CustomerConsumptionValley, ValleyPrice: report.Summary.ValleyPrice, ValleyFee: report.Summary.CustomerConsumptionValleyFee, } lossPart := model.LossPart{ Quantity: report.Summary.Loss.Decimal, Price: report.Summary.OverallPrice.Decimal, ConsumptionFee: report.Summary.LossFee.Decimal, Proportion: report.Summary.LossProportion.Decimal, } publicSummary := model.PublicConsumptionOverallPart{ Overall: report.Summary.PublicConsumption.Decimal, OverallPrice: report.Summary.OverallPrice.Decimal, ConsumptionFee: report.Summary.PublicConsumptionFee.Decimal, OverallFee: report.Summary.PublicConsumptionFee.Decimal, Critical: report.Summary.PublicConsumptionCritical, CriticalPrice: report.Summary.CriticalPrice, CriticalFee: report.Summary.PublicConsumptionCriticalFee, Peak: report.Summary.PublicConsumptionPeak, PeakPrice: report.Summary.PeakPrice, PeakFee: report.Summary.PublicConsumptionPeakFee, Flat: report.Summary.PublicConsumptionFlat, FlatPrice: report.Summary.FlatPrice, FlatFee: report.Summary.PublicConsumptionFlatFee, Valley: report.Summary.PublicConsumptionValley, ValleyPrice: report.Summary.ValleyPrice, ValleyFee: report.Summary.PublicConsumptionValleyFee, Proportion: report.Summary.PublicConsumptionProportion.Decimal, } otherCollection := model.OtherShouldCollectionPart{ MaintenanceFee: report.Summary.MaintenanceOverall, BasicFees: report.Summary.BasicFee.Add(report.Summary.AdjustFee), } finalMaintenance := lossPart.ConsumptionFee.Add(publicSummary.ConsumptionFee).Add(otherCollection.MaintenanceFee.Decimal).Add(otherCollection.BasicFees) var maintenancePrice = decimal.Zero if !endUserSummary.Overall.Equal(decimal.Zero) { maintenancePrice = finalMaintenance.Div(endUserSummary.Overall).RoundBank(8) } var maintenanceProportion = decimal.Zero if !paidPart.OverallFee.Equal(decimal.Zero) || !otherCollection.MaintenanceFee.Decimal.Equal(decimal.Zero) { maintenanceProportion = finalMaintenance.Div(paidPart.OverallFee.Add(otherCollection.MaintenanceFee.Decimal)).RoundBank(8) } var priceRatio = decimal.Zero if !report.Summary.OverallPrice.Decimal.Equal(decimal.Zero) { priceRatio = maintenancePrice.Div(report.Summary.OverallPrice.Decimal).RoundBank(8) } maintenanceFees := model.MaintenancePart{ BasicFees: otherCollection.BasicFees, LossFee: lossPart.ConsumptionFee, PublicConsumptionFee: publicSummary.ConsumptionFee, MaintenanceFee: otherCollection.MaintenanceFee.Decimal, FinalMaintenance: finalMaintenance, MaintenanceProportion: maintenanceProportion, MaintenancePrice: maintenancePrice, PriceRatio: priceRatio, } endUsers := lo.Map( report.EndUsers, func(elem *model.EndUserDetail, index int) model.EndUserSummary { return model.EndUserSummary{ CustomerName: elem.CustomerName, Address: elem.Address, MeterId: elem.MeterId, Overall: elem.Overall.Decimal, OverallFee: elem.OverallFee.Decimal, Critical: elem.Critical, CriticalFee: elem.CriticalFee, Peak: elem.Peak, PeakFee: elem.PeakFee, Valley: elem.Valley, ValleyFee: elem.ValleyFee, Maintenance: elem.FinalDiluted.Decimal, } }, ) publicity := &model.Publicity{ Report: *report, Park: *report.Park, User: *report.Park.Enterprise, Paid: paidPart, EndUser: endUserSummary, Loss: lossPart, PublicConsumptionOverall: publicSummary, OtherCollections: otherCollection, Maintenance: maintenanceFees, EndUserDetails: endUsers, } cache.CacheEntity(publicity, []string{fmt.Sprintf("publicity:%s", reportId), fmt.Sprintf("report:%s", reportId), "report", "park"}, "publicity", reportId) return publicity, nil }