package incentives import ( "fmt" "time" "git.coopgo.io/coopgo-platform/carpool-incentives/storage" "github.com/google/uuid" "github.com/rs/zerolog/log" "github.com/spf13/viper" ) type IncentivesHandler struct { Config *viper.Viper Storage storage.Storage } func NewIncentivesHandler(cfg *viper.Viper, storage storage.Storage) (*IncentivesHandler, error) { return &IncentivesHandler{ Config: cfg, Storage: storage, }, nil } func (h *IncentivesHandler) GetIncentives() ([]storage.Incentive, error) { results := []storage.Incentive{} from_config := h.Config.GetStringMap("incentives") for k, i := range from_config { if incentive, ok := i.(map[string]any); ok { name, ok := incentive["name"].(string) if !ok { return nil, fmt.Errorf("could not read incentives from config, issue reading name in %s", k) } t, err := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") if err != nil { return nil, fmt.Errorf("could not read incentives from config: %s", err) } accepted_proof_levels := h.Config.GetStringSlice(fmt.Sprintf("incentives.%s.accepted_proof_levels", k)) new_incentive := storage.Incentive{ ID: k, Name: name, Start: t, AcceptedProofLevels: accepted_proof_levels, } results = append(results, new_incentive) } else { return nil, fmt.Errorf("could not read incentives from config, issue reading %s", k) } } return results, nil } func (h *IncentivesHandler) GetAvailableIncentives(userid string) ([]storage.Incentive, error) { available_incentives := []storage.Incentive{} incentives, err := h.GetIncentives() if err != nil { return nil, err } incentiveSubscriptions, err := h.Storage.GetUserSubscriptions(userid) if err != nil { log.Error().Err(err).Msg("error retrieving subscriptions") return nil, err } for _, i := range incentives { if i.SubscriptionStatus(incentiveSubscriptions) == storage.SubscriptionStatusAvailable { available_incentives = append(available_incentives, i) } } return available_incentives, nil } func (h *IncentivesHandler) GetInitiatedIncentives(userid string) ([]storage.Incentive, error) { available_incentives := []storage.Incentive{} incentives, err := h.GetIncentives() if err != nil { return nil, err } incentiveSubscriptions, err := h.Storage.GetUserSubscriptions(userid) if err != nil { return nil, err } for _, i := range incentives { if i.SubscriptionStatus(incentiveSubscriptions) == storage.SubscriptionStatusInitiated { available_incentives = append(available_incentives, i) } } return available_incentives, nil } func (h *IncentivesHandler) GetDeclinedIncentives(userid string) ([]storage.Incentive, error) { available_incentives := []storage.Incentive{} incentives, err := h.GetIncentives() if err != nil { return nil, err } incentiveSubscriptions, err := h.Storage.GetUserSubscriptions(userid) if err != nil { return nil, err } for _, i := range incentives { if i.SubscriptionStatus(incentiveSubscriptions) == storage.SubscriptionStatusDeclined { available_incentives = append(available_incentives, i) } } return available_incentives, nil } func (h *IncentivesHandler) SubscribeIncentive(incentiveid string, userid string, identity_verification_ids []string, data map[string]any, declined bool) (*storage.IncentiveSubscription, error) { // TODO check if there is a conflict with other subscriptions for userid and identity verification IDs subscription := storage.IncentiveSubscription{ ID: uuid.NewString(), IncentiveID: incentiveid, UserID: userid, IdentityVerificationIDs: identity_verification_ids, Data: data, SubscriptionDatetime: time.Now(), Declined: declined, } err := h.Storage.SubscribeIncentive(subscription) if err != nil { return nil, err } return &subscription, nil }