add user credit usage method into console service (#2240)
This commit is contained in:
parent
213bcacc83
commit
d583ab707b
@ -21,9 +21,7 @@ import (
|
|||||||
"storj.io/storj/satellite/payments"
|
"storj.io/storj/satellite/payments"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var mon = monkit.Package()
|
||||||
mon = monkit.Package()
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// maxLimit specifies the limit for all paged queries
|
// maxLimit specifies the limit for all paged queries
|
||||||
@ -457,6 +455,22 @@ func (s *Service) GetUsersProjects(ctx context.Context) (ps []Project, err error
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserCreditUsage is a method for querying users' credit information up until now
|
||||||
|
func (s *Service) GetUserCreditUsage(ctx context.Context) (usage *UserCreditUsage, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
auth, err := GetAuth(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usage, err = s.store.UserCredits().GetCreditUsage(ctx, auth.User.ID, time.Now().UTC())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return usage, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateProject is a method for creating new project
|
// CreateProject is a method for creating new project
|
||||||
func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p *Project, err error) {
|
func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p *Project, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
@ -12,8 +12,7 @@ import (
|
|||||||
|
|
||||||
// UserCredits holds information to interact with database
|
// UserCredits holds information to interact with database
|
||||||
type UserCredits interface {
|
type UserCredits interface {
|
||||||
TotalReferredCount(ctx context.Context, userID uuid.UUID) (int64, error)
|
GetCreditUsage(ctx context.Context, userID uuid.UUID, expirationEndDate time.Time) (*UserCreditUsage, error)
|
||||||
GetAvailableCredits(ctx context.Context, userID uuid.UUID, expirationEndDate time.Time) ([]UserCredit, error)
|
|
||||||
Create(ctx context.Context, userCredit UserCredit) (*UserCredit, error)
|
Create(ctx context.Context, userCredit UserCredit) (*UserCredit, error)
|
||||||
UpdateAvailableCredits(ctx context.Context, creditsToCharge int, id uuid.UUID, billingStartDate time.Time) (remainingCharge int, err error)
|
UpdateAvailableCredits(ctx context.Context, creditsToCharge int, id uuid.UUID, billingStartDate time.Time) (remainingCharge int, err error)
|
||||||
}
|
}
|
||||||
@ -29,3 +28,10 @@ type UserCredit struct {
|
|||||||
ExpiresAt time.Time
|
ExpiresAt time.Time
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserCreditUsage holds information about credit usage information
|
||||||
|
type UserCreditUsage struct {
|
||||||
|
Referred int64
|
||||||
|
AvailableCredits int64
|
||||||
|
UsedCredits int64
|
||||||
|
}
|
||||||
|
@ -503,16 +503,10 @@ func (m *lockedUserCredits) Create(ctx context.Context, userCredit console.UserC
|
|||||||
return m.db.Create(ctx, userCredit)
|
return m.db.Create(ctx, userCredit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *lockedUserCredits) GetAvailableCredits(ctx context.Context, userID uuid.UUID, expirationEndDate time.Time) ([]console.UserCredit, error) {
|
func (m *lockedUserCredits) GetCreditUsage(ctx context.Context, userID uuid.UUID, expirationEndDate time.Time) (*console.UserCreditUsage, error) {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
return m.db.GetAvailableCredits(ctx, userID, expirationEndDate)
|
return m.db.GetCreditUsage(ctx, userID, expirationEndDate)
|
||||||
}
|
|
||||||
|
|
||||||
func (m *lockedUserCredits) TotalReferredCount(ctx context.Context, userID uuid.UUID) (int64, error) {
|
|
||||||
m.Lock()
|
|
||||||
defer m.Unlock()
|
|
||||||
return m.db.TotalReferredCount(ctx, userID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *lockedUserCredits) UpdateAvailableCredits(ctx context.Context, creditsToCharge int, id uuid.UUID, billingStartDate time.Time) (remainingCharge int, err error) {
|
func (m *lockedUserCredits) UpdateAvailableCredits(ctx context.Context, creditsToCharge int, id uuid.UUID, billingStartDate time.Time) (remainingCharge int, err error) {
|
||||||
|
@ -5,6 +5,7 @@ package satellitedb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
@ -20,27 +21,36 @@ type usercredits struct {
|
|||||||
db *dbx.DB
|
db *dbx.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalReferredCount returns the total amount of referral a user has made based on user id
|
// GetCreditUsage returns the total amount of referral a user has made based on user id, total available credits, and total used credits based on user id
|
||||||
func (c *usercredits) TotalReferredCount(ctx context.Context, id uuid.UUID) (int64, error) {
|
func (c *usercredits) GetCreditUsage(ctx context.Context, userID uuid.UUID, expirationEndDate time.Time) (*console.UserCreditUsage, error) {
|
||||||
totalReferred, err := c.db.Count_UserCredit_By_ReferredBy(ctx, dbx.UserCredit_ReferredBy(id[:]))
|
usageRows, err := c.db.DB.QueryContext(ctx, c.db.Rebind(`SELECT a.used_credit, b.available_credit, c.referred
|
||||||
if err != nil {
|
FROM (SELECT SUM(credits_used_in_cents) AS used_credit FROM user_credits WHERE user_id = ?) AS a,
|
||||||
return totalReferred, errs.Wrap(err)
|
(SELECT SUM(credits_earned_in_cents - credits_used_in_cents) AS available_credit FROM user_credits WHERE expires_at > ? AND user_id = ?) AS b,
|
||||||
}
|
(SELECT count(id) AS referred FROM user_credits WHERE user_credits.referred_by = ?) AS c;`), userID[:], expirationEndDate, userID[:], userID[:])
|
||||||
|
|
||||||
return totalReferred, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAvailableCredits returns all records of user credit that are not expired or used
|
|
||||||
func (c *usercredits) GetAvailableCredits(ctx context.Context, referrerID uuid.UUID, expirationEndDate time.Time) ([]console.UserCredit, error) {
|
|
||||||
availableCredits, err := c.db.All_UserCredit_By_UserId_And_ExpiresAt_Greater_And_CreditsUsedInCents_Less_CreditsEarnedInCents_OrderBy_Asc_ExpiresAt(ctx,
|
|
||||||
dbx.UserCredit_UserId(referrerID[:]),
|
|
||||||
dbx.UserCredit_ExpiresAt(expirationEndDate),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return userCreditsFromDBX(availableCredits)
|
usage := console.UserCreditUsage{}
|
||||||
|
|
||||||
|
for usageRows.Next() {
|
||||||
|
|
||||||
|
var (
|
||||||
|
usedCredit sql.NullInt64
|
||||||
|
availableCredit sql.NullInt64
|
||||||
|
referred sql.NullInt64
|
||||||
|
)
|
||||||
|
err = usageRows.Scan(&usedCredit, &availableCredit, &referred)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.UsedCredits += usedCredit.Int64
|
||||||
|
usage.Referred += referred.Int64
|
||||||
|
usage.AvailableCredits += availableCredit.Int64
|
||||||
|
}
|
||||||
|
|
||||||
|
return &usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create insert a new record of user credit
|
// Create insert a new record of user credit
|
||||||
@ -141,23 +151,6 @@ func generateQuery(totalRows int, toInt bool) (query string) {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
func userCreditsFromDBX(userCreditsDBX []*dbx.UserCredit) ([]console.UserCredit, error) {
|
|
||||||
var userCredits []console.UserCredit
|
|
||||||
errList := new(errs.Group)
|
|
||||||
|
|
||||||
for _, credit := range userCreditsDBX {
|
|
||||||
|
|
||||||
uc, err := convertDBCredit(credit)
|
|
||||||
if err != nil {
|
|
||||||
errList.Add(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
userCredits = append(userCredits, *uc)
|
|
||||||
}
|
|
||||||
|
|
||||||
return userCredits, errList.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertDBCredit(userCreditDBX *dbx.UserCredit) (*console.UserCredit, error) {
|
func convertDBCredit(userCreditDBX *dbx.UserCredit) (*console.UserCredit, error) {
|
||||||
if userCreditDBX == nil {
|
if userCreditDBX == nil {
|
||||||
return nil, errs.New("userCreditDBX parameter is nil")
|
return nil, errs.New("userCreditDBX parameter is nil")
|
||||||
|
@ -66,9 +66,9 @@ func TestUsercredits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type result struct {
|
type result struct {
|
||||||
remainingCharge int
|
remainingCharge int
|
||||||
availableCredits int
|
usage console.UserCreditUsage
|
||||||
hasErr bool
|
hasErr bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var validUserCredits = []struct {
|
var validUserCredits = []struct {
|
||||||
@ -86,9 +86,13 @@ func TestUsercredits(t *testing.T) {
|
|||||||
},
|
},
|
||||||
chargedCredits: 120,
|
chargedCredits: 120,
|
||||||
expected: result{
|
expected: result{
|
||||||
remainingCharge: 20,
|
remainingCharge: 20,
|
||||||
availableCredits: 0,
|
usage: console.UserCreditUsage{
|
||||||
hasErr: false,
|
AvailableCredits: 0,
|
||||||
|
UsedCredits: 100,
|
||||||
|
Referred: 0,
|
||||||
|
},
|
||||||
|
hasErr: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -102,9 +106,13 @@ func TestUsercredits(t *testing.T) {
|
|||||||
},
|
},
|
||||||
chargedCredits: 60,
|
chargedCredits: 60,
|
||||||
expected: result{
|
expected: result{
|
||||||
remainingCharge: 60,
|
remainingCharge: 60,
|
||||||
availableCredits: 0,
|
usage: console.UserCreditUsage{
|
||||||
hasErr: true,
|
AvailableCredits: 0,
|
||||||
|
UsedCredits: 100,
|
||||||
|
Referred: 0,
|
||||||
|
},
|
||||||
|
hasErr: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -118,9 +126,13 @@ func TestUsercredits(t *testing.T) {
|
|||||||
},
|
},
|
||||||
chargedCredits: 80,
|
chargedCredits: 80,
|
||||||
expected: result{
|
expected: result{
|
||||||
remainingCharge: 0,
|
remainingCharge: 0,
|
||||||
availableCredits: 20,
|
usage: console.UserCreditUsage{
|
||||||
hasErr: false,
|
AvailableCredits: 20,
|
||||||
|
UsedCredits: 180,
|
||||||
|
Referred: 0,
|
||||||
|
},
|
||||||
|
hasErr: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -129,16 +141,6 @@ func TestUsercredits(t *testing.T) {
|
|||||||
_, err = consoleDB.UserCredits().Create(ctx, vc.userCredit)
|
_, err = consoleDB.UserCredits().Create(ctx, vc.userCredit)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
{
|
|
||||||
referredCount, err := consoleDB.UserCredits().TotalReferredCount(ctx, vc.userCredit.ReferredBy)
|
|
||||||
if err != nil {
|
|
||||||
require.True(t, uuid.Equal(*randomID, vc.userCredit.ReferredBy))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, int64(i+1), referredCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
remainingCharge, err := consoleDB.UserCredits().UpdateAvailableCredits(ctx, vc.chargedCredits, vc.userCredit.UserID, time.Now().UTC())
|
remainingCharge, err := consoleDB.UserCredits().UpdateAvailableCredits(ctx, vc.chargedCredits, vc.userCredit.UserID, time.Now().UTC())
|
||||||
if vc.expected.hasErr {
|
if vc.expected.hasErr {
|
||||||
@ -150,15 +152,15 @@ func TestUsercredits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
availableCredits, err := consoleDB.UserCredits().GetAvailableCredits(ctx, vc.userCredit.UserID, time.Now().UTC())
|
usage, err := consoleDB.UserCredits().GetCreditUsage(ctx, vc.userCredit.UserID, time.Now().UTC())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
var sum int
|
require.Equal(t, vc.expected.usage, *usage)
|
||||||
for i := range availableCredits {
|
}
|
||||||
sum += availableCredits[i].CreditsEarnedInCents - availableCredits[i].CreditsUsedInCents
|
|
||||||
}
|
|
||||||
|
|
||||||
|
{
|
||||||
|
referred, err := consoleDB.UserCredits().GetCreditUsage(ctx, referrer.ID, time.Now().UTC())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, vc.expected.availableCredits, sum)
|
require.Equal(t, int64(i+1), referred.Referred)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user