package abono import ( "context" "strings" "time" ) // Member is one holding and whose it is, for an owner's screen. type Member struct { Subject string Holding } // Members is every holding of every subject: subscriptions and comps, // the ones that no longer grant included, ordered by subject and then // newest first, as Holdings orders one subject's. Rows not tied to a // subject (unclaimed payments) and subscriptions on a price no offer // recognises are left out, as Holdings leaves them out; Unrecognised // lists the second kind. func (s *Service) Members(ctx context.Context) ([]Member, error) { var subjects []string if err := s.cfg.DB.WithContext(ctx).Raw(`SELECT subject FROM abono_subscriptions WHERE subject <> '' AND plan <> '' UNION SELECT subject FROM abono_comps WHERE subject <> '' ORDER BY subject`).Scan(&subjects).Error; err != nil { return nil, err } var out []Member for _, subject := range subjects { hs, err := s.Holdings(ctx, subject) if err != nil { return nil, err } for _, h := range hs { out = append(out, Member{Subject: subject, Holding: h}) } } return out, nil } // TestMode reports whether the service runs on a Stripe test key // (sk_test_ or rk_test_), read from the key's prefix (ruling R8): a // restricted key may not be allowed to ask Stripe. The sandbox is not // test mode; Sandbox says so. func (s *Service) TestMode() bool { if s == nil { return false } return strings.HasPrefix(s.cfg.Key, "sk_test_") || strings.HasPrefix(s.cfg.Key, "rk_test_") } // Sandbox reports whether the sandbox stands in for Stripe. func (s *Service) Sandbox() bool { return s != nil && s.sandbox != nil } // Origin is Config.Origin, the site's own address: the webhook's address // is Origin plus wherever the app mounted ServeWebhook. func (s *Service) Origin() string { return s.cfg.Origin } // Now is the moment holdings are judged at, the clock Config.Now gave, // in UTC. A page that describes a Holding passes this as the status // partial's Now, so its words agree with Holding.Grants. func (s *Service) Now() time.Time { return s.now() }