The backend for the project formerly known as signet, now known as beignet.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 rivejä
5.0 KiB

  1. package endpoints
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "time"
  6. . "github.com/imosed/signet/data"
  7. "github.com/rs/zerolog/log"
  8. "gorm.io/gorm/clause"
  9. )
  10. type Total struct {
  11. AmountHeld float64 `json:"amountHeld"`
  12. }
  13. type GetRewardFundRequest struct {
  14. ID uint `json:"id"`
  15. ConsolidateContributions bool `json:"consolidateContributions"`
  16. }
  17. type GetRewardFundResponse struct {
  18. FundInfo FundInfo `json:"fundInfo"`
  19. Contributions Contributions `json:"contributions"`
  20. Total Total `json:"total"`
  21. }
  22. func GetRewardFund(resp http.ResponseWriter, req *http.Request) {
  23. var fund RewardFund
  24. var contribs Contributions
  25. var amountHeld Total
  26. var requestedFund GetRewardFundRequest
  27. dec := json.NewDecoder(req.Body)
  28. err := dec.Decode(&requestedFund)
  29. if err != nil {
  30. log.Error().Err(err).Msg("Could not read requested fund")
  31. }
  32. found := Db.Preload(clause.Associations).Find(&fund, requestedFund.ID).RowsAffected
  33. if found == 0 {
  34. resp.WriteHeader(404)
  35. return
  36. }
  37. Db.Table("contributions").Select("distinct on (created_at::TIMESTAMP::DATE) created_at").Where("reward_fund_id = ?", fund.ID).Scan(&contribs.Dates)
  38. baseQuery := Db.Table("contributions").Where("reward_fund_id = ?", fund.ID).Limit(30)
  39. baseCount := Db.Table("contributions").Where("reward_fund_id = ?", fund.ID)
  40. Db.Table("contributions").Select("sum(amount) amount_held").Where("reward_fund_id = ?", fund.ID).Scan(&amountHeld)
  41. if requestedFund.ConsolidateContributions {
  42. baseQuery.Select("wallet, sum(amount) amount").Group("wallet").Order("wallet").Scan(&contribs.List)
  43. baseCount.Group("wallet").Count(&contribs.Total)
  44. } else {
  45. baseQuery.Select("wallet, amount, created_at").Order("created_at desc").Debug().Scan(&contribs.List)
  46. baseCount.Count(&contribs.Total)
  47. }
  48. r := GetRewardFundResponse{
  49. FundInfo: FundInfo{
  50. ID: fund.ID,
  51. CreatedAt: fund.CreatedAt,
  52. Asset: fund.Asset,
  53. FundWallet: fund.FundWallet,
  54. IssuerWallet: fund.IssuerWallet,
  55. Memo: fund.Memo,
  56. Price: fund.Price,
  57. AmountAvailable: fund.AmountAvailable,
  58. MinContribution: fund.MinContribution,
  59. TelegramLink: fund.TelegramLink,
  60. Bonuses: fund.Bonuses,
  61. },
  62. Contributions: contribs,
  63. Total: amountHeld,
  64. }
  65. err = json.NewEncoder(resp).Encode(r)
  66. if err != nil {
  67. log.Error().Err(err).Msg("Could not deliver requested fund")
  68. }
  69. }
  70. type GetContributionsRequest struct {
  71. ID uint `json:"id"`
  72. Offset int `json:"offset"`
  73. ForDate string `json:"forDate"`
  74. ConsolidateContributions bool `json:"consolidateContributions"`
  75. }
  76. type Contributions struct {
  77. List []Contribution `json:"list"`
  78. Dates []string `json:"dates"`
  79. Total int64 `json:"total"`
  80. }
  81. type GetContributionsResponse = Contributions
  82. func GetContributions(w http.ResponseWriter, r *http.Request) {
  83. var req GetContributionsRequest
  84. err := json.NewDecoder(r.Body).Decode(&req)
  85. if err != nil {
  86. log.Error().Err(err).Msg("Could not decode body in GetContributions call")
  87. return
  88. }
  89. var resp GetContributionsResponse
  90. baseQuery := Db.Table("contributions").Where("reward_fund_id = ?", req.ID).Offset(req.Offset).Limit(30)
  91. baseCount := Db.Table("contributions").Where("reward_fund_id = ?", req.ID)
  92. Db.Table("contributions").Select("distinct on (created_at::TIMESTAMP::DATE) created_at").Where("reward_fund_id = ?", req.ID).Scan(&resp.Dates)
  93. if req.ForDate == "" {
  94. if req.ConsolidateContributions {
  95. baseQuery.Select("wallet, sum(amount) amount").Group("wallet").Scan(&resp.List)
  96. baseCount.Group("wallet").Count(&resp.Total)
  97. } else {
  98. baseQuery.Select("wallet, amount, created_at").Order("created_at desc").Scan(&resp.List)
  99. baseCount.Count(&resp.Total)
  100. }
  101. } else {
  102. var t time.Time
  103. t, err = time.Parse("2006-Jan-02", req.ForDate)
  104. t = t.Add(time.Hour * 24)
  105. if err != nil {
  106. log.Error().Err(err).Msg("Could not interpret time")
  107. return
  108. }
  109. if req.ConsolidateContributions {
  110. baseQuery.Select("wallet, sum(amount) amount").Where("created_at < ?", t).Group("wallet").Scan(&resp.List)
  111. baseCount.Where("created_at < ?", t).Group("wallet").Count(&resp.Total)
  112. } else {
  113. baseQuery.Select("wallet, amount, created_at").Where("created_at < ?", t).Order("created_at desc").Scan(&resp.List)
  114. baseCount.Where("created_at < ?", t).Count(&resp.Total)
  115. }
  116. }
  117. err = json.NewEncoder(w).Encode(resp)
  118. if err != nil {
  119. log.Error().Err(err).Msg("Could not deliver response in GetContributions call")
  120. }
  121. }
  122. type FundInfo struct {
  123. ID uint `json:"id"`
  124. CreatedAt time.Time `json:"createdAt"`
  125. Asset string `json:"asset"`
  126. FundWallet string `json:"fundWallet"`
  127. IssuerWallet string `json:"issuerWallet"`
  128. Memo string `json:"memo"`
  129. Price float64 `json:"price"`
  130. AmountAvailable float64 `json:"amountAvailable"`
  131. MinContribution float64 `json:"minContribution"`
  132. TelegramLink string `json:"telegramLink"`
  133. Bonuses []Bonus `json:"bonuses"`
  134. }