175 lines
4.3 KiB
Go
175 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/szabadpalya/api/internal/store"
|
|
"github.com/szabadpalya/api/internal/store/dbgen"
|
|
"github.com/szabadpalya/api/test/seeddata"
|
|
)
|
|
|
|
// reset clears the campaign side of the database. Relations cascade, so
|
|
// campaigns and owners are enough; users go too because the seed's
|
|
// pledges are anonymous and any account left behind would be an orphan.
|
|
//
|
|
// Four statements rather than a loop over table names: the order matters, and
|
|
// a name interpolated into SQL is the one thing the generated layer cannot
|
|
// check.
|
|
func (s *seeder) reset(ctx context.Context) error {
|
|
if err := s.q.SeedReset(ctx); err != nil {
|
|
return err
|
|
}
|
|
if err := s.q.SeedResetCampaigns(ctx); err != nil {
|
|
return err
|
|
}
|
|
if err := s.q.SeedResetOwners(ctx); err != nil {
|
|
return err
|
|
}
|
|
return s.q.SeedResetUsers(ctx)
|
|
}
|
|
|
|
// campaign writes one fixture campaign and returns how many pledges it created
|
|
// and what they add up to.
|
|
func (s *seeder) campaign(ctx context.Context, c seeddata.Campaign) (int, int, error) {
|
|
endsAt, err := s.store.EndOfDay(c.EndsAt)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
tx, err := s.pool.Begin(ctx)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
defer tx.Rollback(ctx)
|
|
|
|
q := s.q.WithTx(tx)
|
|
|
|
ownerID, err := q.SeedOwner(ctx, dbgen.SeedOwnerParams{
|
|
ID: store.NewID(),
|
|
Slug: c.Owner.Slug,
|
|
Name: c.Owner.Name,
|
|
Initials: c.Owner.Initials,
|
|
Location: c.Owner.Location,
|
|
Blurb: c.Owner.Blurb,
|
|
AvatarUrl: c.Owner.AvatarURL,
|
|
})
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
campaignID := store.NewID()
|
|
if err := q.SeedCampaign(ctx, dbgen.SeedCampaignParams{
|
|
ID: campaignID,
|
|
Slug: c.Slug,
|
|
Title: c.Title,
|
|
Category: c.Category,
|
|
Summary: c.Summary,
|
|
Art: c.Art,
|
|
GoalAmount: c.GoalAmount,
|
|
EndsAt: endsAt,
|
|
Status: c.Status,
|
|
OwnerID: ownerID,
|
|
}); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
for i, sec := range c.Story {
|
|
if err := q.SeedStorySection(ctx, dbgen.SeedStorySectionParams{
|
|
ID: store.NewID(),
|
|
CampaignID: campaignID,
|
|
Heading: sec.Heading,
|
|
Body: sec.Body,
|
|
Position: i,
|
|
}); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
|
|
// Was the goal reached? That decides whether physical tiers were charged.
|
|
raised := 0
|
|
for _, t := range c.Tiers {
|
|
raised += t.Price * t.Backers
|
|
}
|
|
goalReached := raised >= c.GoalAmount
|
|
|
|
pledgeCount := 0
|
|
now := time.Now()
|
|
for i, t := range c.Tiers {
|
|
var delivery *time.Time
|
|
if t.EstimatedDelivery != "" {
|
|
d, err := s.store.EndOfDay(t.EstimatedDelivery)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
delivery = &d
|
|
}
|
|
tierID := store.NewID()
|
|
if err := q.SeedTier(ctx, dbgen.SeedTierParams{
|
|
ID: tierID,
|
|
CampaignID: campaignID,
|
|
Type: t.Type,
|
|
Price: t.Price,
|
|
ListPrice: t.ListPrice,
|
|
Title: t.Title,
|
|
Includes: t.Includes,
|
|
InventoryLimit: t.InventoryLimit,
|
|
EstimatedDelivery: delivery,
|
|
Featured: t.Featured,
|
|
Position: i,
|
|
}); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
// A physical tier on a campaign that missed its goal is still only
|
|
// authorized — that is the fulfillment guard, visible in the fixture.
|
|
held := t.Type == "PHYSICAL" && !goalReached
|
|
status := "CAPTURED"
|
|
var capturedAt *time.Time
|
|
if held {
|
|
status = "AUTHORIZED"
|
|
} else {
|
|
capturedAt = &now
|
|
}
|
|
|
|
for n := 0; n < t.Backers; n++ {
|
|
pledgeCount++
|
|
if err := q.SeedPledge(ctx, dbgen.SeedPledgeParams{
|
|
ID: store.NewID(),
|
|
CampaignID: campaignID,
|
|
TierID: tierID,
|
|
BackerEmail: fmt.Sprintf("tamogato-%s@example.invalid", store.NewID()),
|
|
Amount: t.Price,
|
|
Status: status,
|
|
CapturedAt: capturedAt,
|
|
}); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, u := range c.Updates {
|
|
if err := q.SeedCampaignUpdate(ctx, dbgen.SeedCampaignUpdateParams{
|
|
ID: store.NewID(),
|
|
CampaignID: campaignID,
|
|
Title: u.Title,
|
|
Body: u.Body,
|
|
}); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
for _, m := range c.Comments {
|
|
if err := q.SeedComment(ctx, dbgen.SeedCommentParams{
|
|
ID: store.NewID(),
|
|
CampaignID: campaignID,
|
|
AuthorName: m.AuthorName,
|
|
Body: m.Body,
|
|
}); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
|
|
return pledgeCount, raised, tx.Commit(ctx)
|
|
}
|