package endpoints import ( "encoding/json" "net/http" "time" . "github.com/imosed/signet/data" "github.com/rs/zerolog/log" "gorm.io/gorm/clause" ) type Total struct { AmountHeld float64 `json:"amountHeld"` } type GetRewardFundRequest struct { ID uint `json:"id"` ConsolidateContributions bool `json:"consolidateContributions"` } type GetRewardFundResponse struct { FundInfo FundInfo `json:"fundInfo"` Contributions Contributions `json:"contributions"` Total Total `json:"total"` } func GetRewardFund(resp http.ResponseWriter, req *http.Request) { var fund RewardFund var contribs Contributions var amountHeld Total var requestedFund GetRewardFundRequest dec := json.NewDecoder(req.Body) err := dec.Decode(&requestedFund) if err != nil { log.Error().Err(err).Msg("Could not read requested fund") } found := Db.Preload(clause.Associations).Find(&fund, requestedFund.ID).RowsAffected if found == 0 { resp.WriteHeader(404) return } Db.Table("contributions").Select("distinct on (created_at::TIMESTAMP::DATE) created_at").Where("reward_fund_id = ?", fund.ID).Scan(&contribs.Dates) baseQuery := Db.Table("contributions").Where("reward_fund_id = ?", fund.ID).Limit(30) baseCount := Db.Table("contributions").Where("reward_fund_id = ?", fund.ID) Db.Table("contributions").Select("sum(amount) amount_held").Where("reward_fund_id = ?", fund.ID).Scan(&amountHeld) if requestedFund.ConsolidateContributions { baseQuery.Select("wallet, sum(amount) amount").Group("wallet").Order("wallet").Scan(&contribs.List) baseCount.Group("wallet").Count(&contribs.Total) } else { baseQuery.Select("wallet, amount, created_at").Order("created_at desc").Scan(&contribs.List) baseCount.Count(&contribs.Total) } r := GetRewardFundResponse{ FundInfo: FundInfo{ ID: fund.ID, CreatedAt: fund.CreatedAt, Asset: fund.Asset, FundWallet: fund.FundWallet, IssuerWallet: fund.IssuerWallet, Memo: fund.Memo, Price: fund.Price, AmountAvailable: fund.AmountAvailable, MinContribution: fund.MinContribution, TelegramLink: fund.TelegramLink, Bonuses: fund.Bonuses, }, Contributions: contribs, Total: amountHeld, } err = json.NewEncoder(resp).Encode(r) if err != nil { log.Error().Err(err).Msg("Could not deliver requested fund") } } type GetContributionsRequest struct { ID uint `json:"id"` Offset int `json:"offset"` ForDate string `json:"forDate"` ConsolidateContributions bool `json:"consolidateContributions"` } type Contributions struct { List []Contribution `json:"list"` Dates []string `json:"dates"` Total int64 `json:"total"` } type GetContributionsResponse = Contributions func GetContributions(w http.ResponseWriter, r *http.Request) { var req GetContributionsRequest err := json.NewDecoder(r.Body).Decode(&req) if err != nil { log.Error().Err(err).Msg("Could not decode body in GetContributions call") return } var resp GetContributionsResponse baseQuery := Db.Table("contributions").Where("reward_fund_id = ?", req.ID).Offset(req.Offset).Limit(30) baseCount := Db.Table("contributions").Where("reward_fund_id = ?", req.ID) Db.Table("contributions").Select("distinct on (created_at::TIMESTAMP::DATE) created_at").Where("reward_fund_id = ?", req.ID).Scan(&resp.Dates) if req.ForDate == "" { if req.ConsolidateContributions { baseQuery.Select("wallet, sum(amount) amount").Group("wallet").Scan(&resp.List) baseCount.Group("wallet").Count(&resp.Total) } else { baseQuery.Select("wallet, amount, created_at").Order("created_at desc").Scan(&resp.List) baseCount.Count(&resp.Total) } } else { var t time.Time t, err = time.Parse("2006-Jan-02", req.ForDate) t = t.Add(time.Hour * 24) if err != nil { log.Error().Err(err).Msg("Could not interpret time") return } if req.ConsolidateContributions { baseQuery.Select("wallet, sum(amount) amount").Where("created_at < ?", t).Group("wallet").Scan(&resp.List) baseCount.Where("created_at < ?", t).Group("wallet").Count(&resp.Total) } else { baseQuery.Select("wallet, amount, created_at").Where("created_at < ?", t).Order("created_at desc").Scan(&resp.List) baseCount.Where("created_at < ?", t).Count(&resp.Total) } } err = json.NewEncoder(w).Encode(resp) if err != nil { log.Error().Err(err).Msg("Could not deliver response in GetContributions call") } } type FundInfo struct { ID uint `json:"id"` CreatedAt time.Time `json:"createdAt"` Asset string `json:"asset"` FundWallet string `json:"fundWallet"` IssuerWallet string `json:"issuerWallet"` Memo string `json:"memo"` Price float64 `json:"price"` AmountAvailable float64 `json:"amountAvailable"` MinContribution float64 `json:"minContribution"` TelegramLink string `json:"telegramLink"` Bonuses []Bonus `json:"bonuses"` }