123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package storagebonus
- import (
- "database/sql"
- "errors"
- "github.com/ente-io/museum/pkg/utils/random"
- "github.com/ente-io/museum/ente"
- entity "github.com/ente-io/museum/ente/storagebonus"
- "github.com/ente-io/museum/pkg/controller/email"
- "github.com/ente-io/museum/pkg/controller/lock"
- "github.com/ente-io/museum/pkg/repo"
- "github.com/ente-io/museum/pkg/repo/storagebonus"
- "github.com/ente-io/museum/pkg/utils/auth"
- enteTime "github.com/ente-io/museum/pkg/utils/time"
- "github.com/ente-io/stacktrace"
- "github.com/gin-gonic/gin"
- )
- const (
- codeLength = 6
- referralAmountInGb = 10
- maxClaimableReferralAmount = 2000
- numOfDaysToClaimReferral = 32
- defaultPlanType = entity.TenGbOnUpgrade
- )
- // Controller exposes functions to interact with family module
- type Controller struct {
- UserRepo *repo.UserRepository
- StorageBonus *storagebonus.Repository
- LockController *lock.LockController
- CronRunning bool
- EmailNotificationController *email.EmailNotificationController
- }
- func (c *Controller) GetUserReferralView(ctx *gin.Context) (*entity.GetUserReferralView, error) {
- // Get the user id from the context
- userID := auth.GetUserID(ctx.Request.Header)
- // Use goroutines to fetch UserRepo.Get, HasAppliedReferral
- user, err := c.UserRepo.Get(userID)
- if err != nil {
- return nil, stacktrace.Propagate(err, "failed to get user")
- }
- appliedReferral, err := c.StorageBonus.HasAppliedReferral(ctx, userID)
- if err != nil {
- return nil, stacktrace.Propagate(err, "")
- }
- isFamilyMember := user.FamilyAdminID != nil && *user.FamilyAdminID != userID
- enableApplyCode := !appliedReferral && user.CreationTime > enteTime.MicrosecondBeforeDays(numOfDaysToClaimReferral) && !isFamilyMember
- // Get the referral code for the user or family admin
- codeUser := userID
- if isFamilyMember {
- codeUser = *user.FamilyAdminID
- }
- referralCode, err2 := c.GetOrCreateReferralCode(ctx, codeUser)
- if err2 != nil {
- return nil, stacktrace.Propagate(err2, "failed to get or create referral code")
- }
- storageClaimed, err2 := c.GetActiveReferralBonusValue(ctx, codeUser)
- if err2 != nil {
- return nil, stacktrace.Propagate(err2, "failed to get storage claimed")
- }
- return &entity.GetUserReferralView{
- PlanInfo: entity.PlanInfo{
- IsEnabled: true,
- PlanType: defaultPlanType,
- StorageInGB: referralAmountInGb,
- MaxClaimableStorageInGB: maxClaimableReferralAmount,
- },
- Code: referralCode,
- EnableApplyCode: enableApplyCode,
- IsFamilyMember: isFamilyMember,
- HasAppliedCode: appliedReferral,
- ClaimedStorage: *storageClaimed,
- }, nil
- }
- func (c *Controller) ApplyReferralCode(ctx *gin.Context, code string) error {
- // Get user id from the context
- userID := auth.GetUserID(ctx.Request.Header)
- user, err := c.UserRepo.Get(userID)
- if err != nil {
- return stacktrace.Propagate(err, "failed to get user")
- }
- codeOwnerID, err := c.StorageBonus.GetUserIDByCode(ctx, code)
- if err != nil {
- return stacktrace.Propagate(err, "failed to get user id by code")
- }
- // Verify that the codeOwnerID is not deleted yet
- _, err = c.UserRepo.Get(*codeOwnerID)
- if err != nil {
- if errors.Is(err, ente.ErrUserDeleted) {
- return stacktrace.Propagate(entity.InvalidCodeErr, "code belongs to deleted user")
- }
- return stacktrace.Propagate(err, "failed to get user")
- }
- if user.CreationTime < enteTime.MicrosecondBeforeDays(numOfDaysToClaimReferral) {
- return stacktrace.Propagate(entity.CanNotApplyCodeErr, "account is too old to apply code")
- } else if user.FamilyAdminID != nil && userID != *user.FamilyAdminID {
- return stacktrace.Propagate(entity.CanNotApplyCodeErr, "user is member of a family plan")
- }
- err = c.StorageBonus.TrackReferralAndInviteeBonus(ctx, userID, *codeOwnerID, defaultPlanType)
- if err != nil {
- return stacktrace.Propagate(err, "failed to apply code")
- }
- return nil
- }
- func (c *Controller) GetOrCreateReferralCode(ctx *gin.Context, userID int64) (*string, error) {
- referralCode, err := c.StorageBonus.GetCode(ctx, userID)
- if err != nil {
- if !errors.Is(err, sql.ErrNoRows) {
- return nil, stacktrace.Propagate(err, "failed to get storagebonus code")
- }
- code, err := random.GenerateAlphaNumString(codeLength)
- if err != nil {
- return nil, stacktrace.Propagate(err, "")
- }
- err = c.StorageBonus.InsertCode(ctx, userID, code)
- if err != nil {
- return nil, stacktrace.Propagate(err, "failed to insert storagebonus code")
- }
- referralCode = &code
- }
- return referralCode, nil
- }
|