storj/satellite/rewards/rewards.go
Faris Huskovic 0d294103e9
satellite/rewards: nicer offers handling (#2390)
* organize offers

* revert changes to go.mod and go.sum

* change OfferStatus enums back to original

* revert modified auto-gen files

* don't render empty row if offers is empty

* change return val of ListAll to Offers

* fix build

* add method to check for empty offer when rendering template

* fix typo

* fix lint and typos

* lean out IsEmpty

* dont use named return vals

* better clarify offer statuses

* change back order of setting offer.Status

* lint

* satellite/marketingweb: allow disabling rewards (#2392)

* implement handler for stop offer endpoint

* use proper text and fix data-target for free-credit stop modal
2019-07-10 13:12:40 -04:00

157 lines
3.3 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package rewards
import (
"context"
"time"
"storj.io/storj/internal/currency"
)
// DB holds information about offer
type DB interface {
ListAll(ctx context.Context) (Offers, error)
GetCurrentByType(ctx context.Context, offerType OfferType) (*Offer, error)
Create(ctx context.Context, offer *NewOffer) (*Offer, error)
Redeem(ctx context.Context, offerID int, isDefault bool) error
Finish(ctx context.Context, offerID int) error
}
// NewOffer holds information that's needed for creating a new offer
type NewOffer struct {
Name string
Description string
AwardCredit currency.USD
InviteeCredit currency.USD
RedeemableCap int
AwardCreditDurationDays int
InviteeCreditDurationDays int
ExpiresAt time.Time
Status OfferStatus
Type OfferType
}
// UpdateOffer holds fields needed for update an offer
type UpdateOffer struct {
ID int
Status OfferStatus
ExpiresAt time.Time
}
// OfferType indicates the type of an offer
type OfferType int
const (
// Invalid is a default value for offers that don't have correct type associated with it
Invalid = OfferType(0)
// FreeCredit is a type of offers used for Free Credit Program
FreeCredit = OfferType(1)
// Referral is a type of offers used for Referral Program
Referral = OfferType(2)
)
// OfferStatus represents the different stage an offer can have in its life-cycle.
type OfferStatus int
const (
// Done is the status of an offer that is no longer in use.
Done = OfferStatus(iota)
// Active is the status of an offer that is currently in use.
Active
// Default is the status of an offer when there is no active offer.
Default
)
// Offer contains info needed for giving users free credits through different offer programs
type Offer struct {
ID int
Name string
Description string
AwardCredit currency.USD
InviteeCredit currency.USD
AwardCreditDurationDays int
InviteeCreditDurationDays int
RedeemableCap int
NumRedeemed int
ExpiresAt time.Time
CreatedAt time.Time
Status OfferStatus
Type OfferType
}
// IsEmpty evaluates whether or not an on offer is empty
func (o Offer) IsEmpty() bool {
return o.Name == ""
}
// Offers contains a slice of offers.
type Offers []Offer
// OrganizedOffers contains a list of offers organized by status.
type OrganizedOffers struct {
Active Offer
Default Offer
Done Offers
}
// OfferSet provides a separation of marketing offers by type.
type OfferSet struct {
ReferralOffers OrganizedOffers
FreeCredits OrganizedOffers
}
// OrganizeOffersByStatus organizes offers by OfferStatus.
func (offers Offers) OrganizeOffersByStatus() OrganizedOffers {
var oo OrganizedOffers
for _, offer := range offers {
switch offer.Status {
case Active:
oo.Active = offer
case Default:
oo.Default = offer
case Done:
oo.Done = append(oo.Done, offer)
}
}
return oo
}
// OrganizeOffersByType organizes offers by OfferType.
func (offers Offers) OrganizeOffersByType() OfferSet {
var (
fc, ro Offers
offerSet OfferSet
)
for _, offer := range offers {
switch offer.Type {
case FreeCredit:
fc = append(fc, offer)
case Referral:
ro = append(ro, offer)
default:
continue
}
}
offerSet.FreeCredits = fc.OrganizeOffersByStatus()
offerSet.ReferralOffers = ro.OrganizeOffersByStatus()
return offerSet
}