package service import ( "electricity_bill_calc/cache" "electricity_bill_calc/global" "electricity_bill_calc/logger" "electricity_bill_calc/model" "github.com/samber/lo" "github.com/uptrace/bun" "go.uber.org/zap" ) type _StatisticsService struct { l *zap.Logger } var StatisticsService = _StatisticsService{ l: logger.Named("Service", "Stat"), } func (_StatisticsService) EnabledEnterprises() (int64, error) { if cachedCount, err := cache.RetreiveCount("enabled_ent"); cachedCount != -1 && err == nil { return cachedCount, nil } ctx, cancel := global.TimeoutContext() defer cancel() c, err := global.DB.NewSelect().Model((*model.User)(nil)). Where("type = ?", model.USER_TYPE_ENT). Where("enabled = ?", true). Count(ctx) if err == nil { cache.CacheCount([]string{"user"}, "enabled_ent", int64(c)) } return int64(c), err } func (_StatisticsService) EnabledParks(userIds ...string) (int64, error) { if cachedParks, err := cache.RetreiveCount("enabled_parks", userIds...); cachedParks != -1 && err == nil { return cachedParks, nil } ctx, cancel := global.TimeoutContext() defer cancel() query := global.DB.NewSelect().Model((*model.Park)(nil)). Where("enabled = ?", true) if len(userIds) > 0 { query = query.Where("user_id in (?)", bun.In(userIds)) } c, err := query.Count(ctx) if err == nil { cache.CacheCount([]string{"user", "park"}, "enabled_parks", int64(c), userIds...) } return int64(c), err } func (_StatisticsService) ParksNewestState(userIds ...string) ([]model.ParkPeriodStatistics, error) { if cachedState, _ := cache.RetreiveSearch[[]model.ParkPeriodStatistics]("park_period_stat", userIds...); cachedState != nil { return *cachedState, nil } ctx, cancel := global.TimeoutContext() defer cancel() query := global.DB.NewSelect().Model((*model.Report)(nil)). Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery { return q.Column("id", "name") }). Where("park.enabled = ?", true). Where("r.published = ?", true) if len(userIds) > 0 { query = query.Where("park.user_id in (?)", bun.In(userIds)) } parks := make([]model.ParkPeriodStatistics, 0) groupedParks := make(map[string]model.ParkPeriodStatistics, 0) err := query.Column("period").Scan(ctx, &parks) if err != nil { return make([]model.ParkPeriodStatistics, 0), err } for _, p := range parks { if c, ok := groupedParks[p.Id]; ok { if c.Period != nil && p.Period != nil && p.Period.After(*c.Period) { groupedParks[p.Id] = p } if c.Period == nil && p.Period != nil { groupedParks[p.Id] = p } } else { groupedParks[p.Id] = p } } cache.CacheSearch(lo.Values(groupedParks), []string{"user", "park"}, "park_period_stat", userIds...) return lo.Values(groupedParks), nil }