Item refunding

This commit is contained in:
Eccentric 2024-02-04 15:21:16 +00:00
parent 09f7d2b891
commit 4b8047ae34
12 changed files with 353 additions and 92 deletions

View File

@ -151,7 +151,7 @@ func NewFortnitePersonWithId(id string, displayName string, everything bool) *p.
person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("allowed_to_send_gifts", true)).Save() person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("allowed_to_send_gifts", true)).Save()
person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("gift_history", aid.JSON{})).Save() person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("gift_history", aid.JSON{})).Save()
loadout := p.NewLoadoutWithID("sandbox_loadout", "", person.AthenaProfile) loadout := p.NewLoadout("PRESET 1", person.AthenaProfile)
person.AthenaProfile.Loadouts.AddLoadout(loadout).Save() person.AthenaProfile.Loadouts.AddLoadout(loadout).Save()
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("loadouts", []string{loadout.ID})).Save() person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("loadouts", []string{loadout.ID})).Save()
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("last_applied_loadout", loadout.ID)).Save() person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("last_applied_loadout", loadout.ID)).Save()

View File

@ -27,6 +27,7 @@ var (
"CopyCosmeticLoadout": clientCopyCosmeticLoadoutAction, "CopyCosmeticLoadout": clientCopyCosmeticLoadoutAction,
"DeleteCosmeticLoadout": clientDeleteCosmeticLoadoutAction, "DeleteCosmeticLoadout": clientDeleteCosmeticLoadoutAction,
"PurchaseCatalogEntry": clientPurchaseCatalogEntryAction, "PurchaseCatalogEntry": clientPurchaseCatalogEntryAction,
"RefundMtxPurchase": clientRefundMtxPurchaseAction,
"GiftCatalogEntry": clientGiftCatalogEntryAction, "GiftCatalogEntry": clientGiftCatalogEntryAction,
"RemoveGiftBox": clientRemoveGiftBoxAction, "RemoveGiftBox": clientRemoveGiftBoxAction,
} }
@ -449,7 +450,7 @@ func clientCopyCosmeticLoadoutAction(c *fiber.Ctx, person *p.Person, profile *p.
return fmt.Errorf("source index out of range") return fmt.Errorf("source index out of range")
} }
sandboxLoadout := profile.Loadouts.GetLoadout("sandbox_loadout") sandboxLoadout := profile.Loadouts.GetLoadout(loadouts[0])
if sandboxLoadout == nil { if sandboxLoadout == nil {
return fmt.Errorf("sandbox loadout not found") return fmt.Errorf("sandbox loadout not found")
} }
@ -626,6 +627,7 @@ func clientPurchaseCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p
} }
loot := []aid.JSON{} loot := []aid.JSON{}
purchase := p.NewPurchase(body.OfferID, body.ExpectedTotalPrice)
for i := 0; i < body.PurchaseQuantity; i++ { for i := 0; i < body.PurchaseQuantity; i++ {
for _, grant := range offer.Grants { for _, grant := range offer.Grants {
if profile.Items.GetItemByTemplateID(grant) != nil { if profile.Items.GetItemByTemplateID(grant) != nil {
@ -638,6 +640,7 @@ func clientPurchaseCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p
item := p.NewItem(grant, 1) item := p.NewItem(grant, 1)
person.AthenaProfile.Items.AddItem(item) person.AthenaProfile.Items.AddItem(item)
purchase.AddLoot(item)
loot = append(loot, aid.JSON{ loot = append(loot, aid.JSON{
"itemType": item.TemplateID, "itemType": item.TemplateID,
@ -648,6 +651,8 @@ func clientPurchaseCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p
} }
} }
person.AthenaProfile.Purchases.AddPurchase(purchase).Save()
*notifications = append(*notifications, aid.JSON{ *notifications = append(*notifications, aid.JSON{
"type": "CatalogPurchase", "type": "CatalogPurchase",
"lootResult": aid.JSON{ "lootResult": aid.JSON{
@ -659,6 +664,62 @@ func clientPurchaseCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p
return nil return nil
} }
func clientRefundMtxPurchaseAction(c *fiber.Ctx, person *p.Person, profile *p.Profile, notifications *[]aid.JSON) error {
var body struct {
PurchaseID string `json:"purchaseId" binding:"required"`
}
if err := c.BodyParser(&body); err != nil {
return fmt.Errorf("invalid Body")
}
aid.Print(person.AthenaProfile.Purchases.Count())
aid.Print(person.CommonCoreProfile.Purchases.Count())
person.AthenaProfile.Purchases.RangePurchases(func(key string, value *p.Purchase) bool {
aid.Print(key, value.ID)
return true
})
purchase := person.AthenaProfile.Purchases.GetPurchase(body.PurchaseID)
if purchase == nil {
return fmt.Errorf("purchase not found")
}
if person.RefundTickets <= 0 {
return fmt.Errorf("not enough refund tickets")
}
if time.Now().After(purchase.FreeRefundExpiry) {
person.RefundTickets--
}
for _, item := range purchase.Loot {
profile.Items.DeleteItem(item.ID)
}
purchase.RefundedAt = time.Now()
purchase.Save()
vbucks := profile.Items.GetItemByTemplateID("Currency:MtxPurchased")
if vbucks == nil {
return fmt.Errorf("vbucks not found")
}
vbucks.Quantity += purchase.TotalPaid
vbucks.Save()
profile0Vbucks := person.Profile0Profile.Items.GetItemByTemplateID("Currency:MtxPurchased")
if profile0Vbucks == nil {
return fmt.Errorf("profile0vbucks not found")
}
profile0Vbucks.Quantity = vbucks.Quantity
profile0Vbucks.Save()
return nil
}
func clientGiftCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p.Profile, notifications *[]aid.JSON) error { func clientGiftCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p.Profile, notifications *[]aid.JSON) error {
var body struct { var body struct {
Currency string `json:"currency" binding:"required"` Currency string `json:"currency" binding:"required"`

View File

@ -35,7 +35,7 @@ func FromDatabaseGift(gift *storage.DB_Gift) *Gift {
loot := []*Item{} loot := []*Item{}
for _, item := range gift.Loot { for _, item := range gift.Loot {
loot = append(loot, FromDatabaseLoot(&item)) loot = append(loot, FromDatabaseGiftLoot(&item))
} }
return &Gift{ return &Gift{
@ -99,7 +99,7 @@ func (g *Gift) ToDatabase(profileId string) *storage.DB_Gift {
profileLoot := []storage.DB_GiftLoot{} profileLoot := []storage.DB_GiftLoot{}
for _, item := range g.Loot { for _, item := range g.Loot {
profileLoot = append(profileLoot, *item.ToLootDatabase(g.ID)) profileLoot = append(profileLoot, *item.ToGiftLootDatabase(g.ID))
} }
return &storage.DB_Gift{ return &storage.DB_Gift{

117
person/history.go Normal file
View File

@ -0,0 +1,117 @@
package person
import (
"time"
"github.com/ectrc/snow/aid"
"github.com/ectrc/snow/storage"
"github.com/google/uuid"
)
type Purchase struct {
ID string
ProfileID string
PersonID string
Loot []*Item
OfferID string
PurchaseDate time.Time
FreeRefundExpiry time.Time
RefundExpiry time.Time
RefundedAt time.Time
TotalPaid int
}
func NewPurchase(offerID string, price int) *Purchase {
return &Purchase{
ID: uuid.New().String(),
OfferID: offerID,
PurchaseDate: time.Now(),
RefundedAt: time.Unix(0, 0),
FreeRefundExpiry: time.Now().Add(time.Hour * 24),
RefundExpiry: time.Now().Add(time.Hour * 24 * 30),
Loot: []*Item{},
TotalPaid: price,
}
}
func FromDatabasePurchase(purchase *storage.DB_Purchase) *Purchase {
loot := []*Item{}
for _, item := range purchase.Loot {
loot = append(loot, FromDatabasePurchaseLoot(&item))
}
return &Purchase{
ID: purchase.ID,
ProfileID: purchase.ProfileID,
Loot: loot,
OfferID: purchase.OfferID,
PurchaseDate: time.Unix(purchase.PurchaseDate, 0),
FreeRefundExpiry: time.Unix(purchase.FreeRefundExpiry, 0),
RefundExpiry: time.Unix(purchase.RefundExpiry, 0),
RefundedAt: time.Unix(purchase.RefundedAt, 0),
}
}
func (p *Purchase) GenerateFortnitePurchaseEntry() aid.JSON {
json := aid.JSON{
"offerId": p.OfferID,
"freeRefundEligible": time.Now().Before(p.FreeRefundExpiry),
"purchaseId": p.ID,
"purchaseDate": p.PurchaseDate.Format(time.RFC3339),
"undoTimeout": p.FreeRefundExpiry.Format(time.RFC3339),
"totalMtxPaid": p.TotalPaid,
"lootResult": []aid.JSON{},
"gameContext": "",
"metadata": aid.JSON{},
"fulfillments": []aid.JSON{},
}
for _, item := range p.Loot {
json["lootResult"] = append(json["lootResult"].([]aid.JSON), aid.JSON{
"itemGuid": item.ID,
"itemType": item.TemplateID,
"itemProfile": item.ProfileType,
"quantity": item.Quantity,
})
}
if p.RefundedAt.Unix() > 0 {
json["refundDate"] = p.RefundedAt.Format(time.RFC3339)
}
return json
}
func (p *Purchase) AddLoot(item *Item) {
p.Loot = append(p.Loot, item)
}
func (p *Purchase) Delete() {
storage.Repo.DeletePurchase(p.ID)
}
func (p *Purchase) ToDatabase(profileId string) *storage.DB_Purchase {
loot := []storage.DB_PurchaseLoot{}
for _, item := range p.Loot {
loot = append(loot, *item.ToPurchaseLootDatabase(p.ID))
}
return &storage.DB_Purchase{
ID: p.ID,
ProfileID: profileId,
Loot: loot,
OfferID: p.OfferID,
PurchaseDate: p.PurchaseDate.Unix(),
FreeRefundExpiry: p.FreeRefundExpiry.Unix(),
RefundExpiry: p.RefundExpiry.Unix(),
RefundedAt: p.RefundedAt.Unix(),
TotalPaid: p.TotalPaid,
}
}
func (p *Purchase) Save() {
storage.Repo.SavePurchase(p.ToDatabase(p.ProfileID))
Find(p.PersonID).SetPurchaseHistoryAttribute()
}

View File

@ -58,7 +58,19 @@ func FromDatabaseItem(item *storage.DB_Item) *Item {
} }
} }
func FromDatabaseLoot(item *storage.DB_GiftLoot) *Item { func FromDatabaseGiftLoot(item *storage.DB_GiftLoot) *Item {
return &Item{
ID: item.ID,
TemplateID: item.TemplateID,
Quantity: item.Quantity,
Favorite: false,
HasSeen: false,
Variants: []*VariantChannel{},
ProfileType: item.ProfileType,
}
}
func FromDatabasePurchaseLoot(item *storage.DB_PurchaseLoot) *Item {
return &Item{ return &Item{
ID: item.ID, ID: item.ID,
TemplateID: item.TemplateID, TemplateID: item.TemplateID,
@ -202,7 +214,7 @@ func (i *Item) Save() {
storage.Repo.SaveItem(i.ToDatabase(i.ProfileID)) storage.Repo.SaveItem(i.ToDatabase(i.ProfileID))
} }
func (i *Item) ToLootDatabase(giftId string) *storage.DB_GiftLoot { func (i *Item) ToGiftLootDatabase(giftId string) *storage.DB_GiftLoot {
return &storage.DB_GiftLoot{ return &storage.DB_GiftLoot{
GiftID: giftId, GiftID: giftId,
ProfileType: i.ProfileType, ProfileType: i.ProfileType,
@ -212,6 +224,16 @@ func (i *Item) ToLootDatabase(giftId string) *storage.DB_GiftLoot {
} }
} }
func (i *Item) ToPurchaseLootDatabase(purchaseId string) *storage.DB_PurchaseLoot {
return &storage.DB_PurchaseLoot{
ID: i.ID,
PurchaseID: purchaseId,
ProfileType: i.ProfileType,
TemplateID: i.TemplateID,
Quantity: i.Quantity,
}
}
func (i *Item) SaveLoot(giftId string) { func (i *Item) SaveLoot(giftId string) {
//storage.Repo.SaveLoot(i.ToLootDatabase(giftId)) //storage.Repo.SaveLoot(i.ToLootDatabase(giftId))
} }

View File

@ -11,6 +11,7 @@ import (
type Person struct { type Person struct {
ID string ID string
DisplayName string DisplayName string
RefundTickets int
Permissions []string Permissions []string
AthenaProfile *Profile AthenaProfile *Profile
CommonCoreProfile *Profile CommonCoreProfile *Profile
@ -28,6 +29,7 @@ func NewPerson() *Person {
ID: uuid.New().String(), ID: uuid.New().String(),
DisplayName: uuid.New().String(), DisplayName: uuid.New().String(),
Permissions: []string{}, Permissions: []string{},
RefundTickets: 3,
AthenaProfile: NewProfile("athena"), AthenaProfile: NewProfile("athena"),
CommonCoreProfile: NewProfile("common_core"), CommonCoreProfile: NewProfile("common_core"),
CommonPublicProfile: NewProfile("common_public"), CommonPublicProfile: NewProfile("common_public"),
@ -42,6 +44,7 @@ func NewPersonWithCustomID(id string) *Person {
ID: id, ID: id,
DisplayName: uuid.New().String(), DisplayName: uuid.New().String(),
Permissions: []string{}, Permissions: []string{},
RefundTickets: 3,
AthenaProfile: NewProfile("athena"), AthenaProfile: NewProfile("athena"),
CommonCoreProfile: NewProfile("common_core"), CommonCoreProfile: NewProfile("common_core"),
CommonPublicProfile: NewProfile("common_public"), CommonPublicProfile: NewProfile("common_public"),
@ -193,6 +196,7 @@ func findHelper(databasePerson *storage.DB_Person, shallow bool, save bool) *Per
CollectionsProfile: collectionsProfile, CollectionsProfile: collectionsProfile,
CreativeProfile: creativeProfile, CreativeProfile: creativeProfile,
Discord: &databasePerson.Discord, Discord: &databasePerson.Discord,
RefundTickets: databasePerson.RefundTickets,
Relationships: aid.GenericSyncMap[Relationship]{}, Relationships: aid.GenericSyncMap[Relationship]{},
} }
@ -313,6 +317,7 @@ func (p *Person) ToDatabase() *storage.DB_Person {
DisplayName: p.DisplayName, DisplayName: p.DisplayName,
Permissions: p.Permissions, Permissions: p.Permissions,
BanHistory: p.BanHistory, BanHistory: p.BanHistory,
RefundTickets: p.RefundTickets,
Profiles: []storage.DB_Profile{}, Profiles: []storage.DB_Profile{},
Stats: []storage.DB_SeasonStat{}, Stats: []storage.DB_SeasonStat{},
Discord: storage.DB_DiscordPerson{}, Discord: storage.DB_DiscordPerson{},
@ -381,6 +386,7 @@ func (p *Person) ToDatabaseShallow() *storage.DB_Person {
DisplayName: p.DisplayName, DisplayName: p.DisplayName,
Permissions: p.Permissions, Permissions: p.Permissions,
BanHistory: p.BanHistory, BanHistory: p.BanHistory,
RefundTickets: p.RefundTickets,
Profiles: []storage.DB_Profile{}, Profiles: []storage.DB_Profile{},
Stats: []storage.DB_SeasonStat{}, Stats: []storage.DB_SeasonStat{},
Discord: storage.DB_DiscordPerson{}, Discord: storage.DB_DiscordPerson{},
@ -393,19 +399,6 @@ func (p *Person) ToDatabaseShallow() *storage.DB_Person {
return &dbPerson return &dbPerson
} }
func (p *Person) AddAttribute(value *Attribute) {
p.AthenaProfile.Attributes.AddAttribute(value)
}
func (p *Person) GetAttribute(key string) *Attribute {
attribute := p.AthenaProfile.Attributes.GetAttribute(key)
return attribute
}
func (p *Person) RemoveAttribute(key string) {
p.AthenaProfile.Attributes.DeleteAttribute(key)
}
func (p *Person) Snapshot() *PersonSnapshot { func (p *Person) Snapshot() *PersonSnapshot {
return &PersonSnapshot{ return &PersonSnapshot{
ID: p.ID, ID: p.ID,
@ -424,4 +417,21 @@ func (p *Person) Snapshot() *PersonSnapshot {
func (p *Person) Delete() { func (p *Person) Delete() {
storage.Repo.DeletePerson(p.ID) storage.Repo.DeletePerson(p.ID)
}
func (p *Person) SetPurchaseHistoryAttribute() {
purchases := []aid.JSON{}
p.AthenaProfile.Purchases.RangePurchases(func(key string, value *Purchase) bool {
purchases = append(purchases, value.GenerateFortnitePurchaseEntry())
return true
})
purchaseAttribute := p.CommonCoreProfile.Attributes.GetAttributeByKey("mtx_purchase_history")
purchaseAttribute.ValueJSON = aid.JSONStringify(aid.JSON{
"refundsUsed": p.AthenaProfile.Purchases.CountRefunded(),
"refundCredits": p.RefundTickets,
"purchases": purchases,
})
purchaseAttribute.Save()
} }

View File

@ -17,6 +17,7 @@ type Profile struct {
Quests *QuestMutex Quests *QuestMutex
Attributes *AttributeMutex Attributes *AttributeMutex
Loadouts *LoadoutMutex Loadouts *LoadoutMutex
Purchases *PurchaseMutex
Type string Type string
Revision int Revision int
Changes []interface{} Changes []interface{}
@ -32,6 +33,7 @@ func NewProfile(profile string) *Profile {
Quests: NewQuestMutex(&storage.DB_Profile{ID: id, Type: profile}), Quests: NewQuestMutex(&storage.DB_Profile{ID: id, Type: profile}),
Attributes: NewAttributeMutex(&storage.DB_Profile{ID: id, Type: profile}), Attributes: NewAttributeMutex(&storage.DB_Profile{ID: id, Type: profile}),
Loadouts: NewLoadoutMutex(&storage.DB_Profile{ID: id, Type: profile}), Loadouts: NewLoadoutMutex(&storage.DB_Profile{ID: id, Type: profile}),
Purchases: NewPurchaseMutex(&storage.DB_Profile{ID: id, Type: profile}),
Type: profile, Type: profile,
Revision: 0, Revision: 0,
Changes: []interface{}{}, Changes: []interface{}{},
@ -44,6 +46,7 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
quests := NewQuestMutex(profile) quests := NewQuestMutex(profile)
attributes := NewAttributeMutex(profile) attributes := NewAttributeMutex(profile)
loadouts := NewLoadoutMutex(profile) loadouts := NewLoadoutMutex(profile)
purchases := NewPurchaseMutex(profile)
for _, item := range profile.Items { for _, item := range profile.Items {
items.AddItem(FromDatabaseItem(&item)) items.AddItem(FromDatabaseItem(&item))
@ -71,6 +74,10 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
attributes.AddAttribute(parsed) attributes.AddAttribute(parsed)
} }
for _, purchase := range profile.Purchases {
purchases.AddPurchase(FromDatabasePurchase(&purchase))
}
return &Profile{ return &Profile{
ID: profile.ID, ID: profile.ID,
PersonID: profile.PersonID, PersonID: profile.PersonID,
@ -79,6 +86,7 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
Quests: quests, Quests: quests,
Attributes: attributes, Attributes: attributes,
Loadouts: loadouts, Loadouts: loadouts,
Purchases: purchases,
Type: profile.Type, Type: profile.Type,
Revision: profile.Revision, Revision: profile.Revision,
Changes: []interface{}{}, Changes: []interface{}{},
@ -437,6 +445,7 @@ func (p *Profile) ToDatabase() *storage.DB_Profile {
Gifts: []storage.DB_Gift{}, Gifts: []storage.DB_Gift{},
Quests: []storage.DB_Quest{}, Quests: []storage.DB_Quest{},
Loadouts: []storage.DB_Loadout{}, Loadouts: []storage.DB_Loadout{},
Purchases: []storage.DB_Purchase{},
Attributes: []storage.DB_Attribute{}, Attributes: []storage.DB_Attribute{},
Revision: p.Revision, Revision: p.Revision,
} }
@ -466,5 +475,10 @@ func (p *Profile) ToDatabase() *storage.DB_Profile {
return true return true
}) })
p.Purchases.RangePurchases(func(id string, purchase *Purchase) bool {
dbProfile.Purchases = append(dbProfile.Purchases, *purchase.ToDatabase(dbProfile.PersonID))
return true
})
return &dbProfile return &dbProfile
} }

View File

@ -6,13 +6,13 @@ type PersonSnapshot struct {
ID string ID string
DisplayName string DisplayName string
Permissions []string Permissions []string
IsBanned bool
AthenaProfile ProfileSnapshot AthenaProfile ProfileSnapshot
CommonCoreProfile ProfileSnapshot CommonCoreProfile ProfileSnapshot
CommonPublicProfile ProfileSnapshot CommonPublicProfile ProfileSnapshot
Profile0Profile ProfileSnapshot Profile0Profile ProfileSnapshot
CollectionsProfile ProfileSnapshot CollectionsProfile ProfileSnapshot
CreativeProfile ProfileSnapshot CreativeProfile ProfileSnapshot
BanHistory []storage.DB_BanStatus
Discord storage.DB_DiscordPerson Discord storage.DB_DiscordPerson
} }

View File

@ -265,7 +265,6 @@ func (m *LoadoutMutex) DeleteLoadout(id string) {
return return
} }
loadout.Delete()
m.Delete(id) m.Delete(id)
storage.Repo.DeleteItem(id) storage.Repo.DeleteItem(id)
} }
@ -307,4 +306,62 @@ func (m *LoadoutMutex) Count() int {
return true return true
}) })
return count return count
}
type PurchaseMutex struct {
sync.Map
PersonID string
ProfileID string
}
func NewPurchaseMutex(profile *storage.DB_Profile) *PurchaseMutex {
return &PurchaseMutex{
PersonID: profile.PersonID,
ProfileID: profile.ID,
}
}
func (m *PurchaseMutex) AddPurchase(purchase *Purchase) *Purchase {
purchase.ProfileID = m.ProfileID
purchase.PersonID = m.PersonID
m.Store(purchase.ID, purchase)
// storage.Repo.SavePurchase(purchase.ToDatabase(m.ProfileID))
// Find(m.PersonID).SetPurchaseHistoryAttribute()
return purchase
}
func (m *PurchaseMutex) GetPurchase(id string) *Purchase {
purchase, ok := m.Load(id)
if !ok {
return nil
}
return purchase.(*Purchase)
}
func (m *PurchaseMutex) RangePurchases(f func(key string, value *Purchase) bool) {
m.Range(func(key, value interface{}) bool {
return f(key.(string), value.(*Purchase))
})
}
func (m *PurchaseMutex) Count() int {
count := 0
m.Range(func(key, value interface{}) bool {
count++
return true
})
return count
}
func (m *PurchaseMutex) CountRefunded() int {
count := 0
m.RangePurchases(func(key string, value *Purchase) bool {
if value.RefundedAt.Unix() > 0 {
count++
}
return true
})
return count
} }

View File

@ -47,6 +47,7 @@ func (s *PostgresStorage) MigrateAll() {
s.Migrate(&DB_Gift{}, "Gifts") s.Migrate(&DB_Gift{}, "Gifts")
s.Migrate(&DB_GiftLoot{}, "GiftLoot") s.Migrate(&DB_GiftLoot{}, "GiftLoot")
s.Migrate(&DB_DiscordPerson{}, "Discords") s.Migrate(&DB_DiscordPerson{}, "Discords")
s.Migrate(&DB_BanStatus{}, "Bans")
s.Migrate(&DB_SeasonStat{}, "Stats") s.Migrate(&DB_SeasonStat{}, "Stats")
} }
@ -54,9 +55,8 @@ func (s *PostgresStorage) DropTables() {
s.Postgres.Exec(`DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public;`) s.Postgres.Exec(`DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public;`)
} }
func (s *PostgresStorage) GetPerson(personId string) *DB_Person { func (s *PostgresStorage) PreloadPerson() (tx *gorm.DB) {
var dbPerson DB_Person return s.Postgres.
s.Postgres.
Model(&DB_Person{}). Model(&DB_Person{}).
Preload("Profiles"). Preload("Profiles").
Preload("Profiles.Loadouts"). Preload("Profiles.Loadouts").
@ -66,9 +66,16 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
Preload("Profiles.Gifts"). Preload("Profiles.Gifts").
Preload("Profiles.Gifts.Loot"). Preload("Profiles.Gifts.Loot").
Preload("Profiles.Quests"). Preload("Profiles.Quests").
Preload("Profiles.Purchases").
Preload("Profiles.Purchases.Loot").
Preload("Discord"). Preload("Discord").
Where("id = ?", personId). Preload("BanHistory").
Find(&dbPerson) Preload("Stats")
}
func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
var dbPerson DB_Person
s.PreloadPerson().Where("id = ?", personId).Find(&dbPerson)
if dbPerson.ID == "" { if dbPerson.ID == "" {
return nil return nil
@ -79,19 +86,7 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person { func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
var dbPerson DB_Person var dbPerson DB_Person
s.Postgres. s.PreloadPerson().Where("display_name = ?", displayName).Find(&dbPerson)
Model(&DB_Person{}).
Preload("Profiles").
Preload("Profiles.Loadouts").
Preload("Profiles.Attributes").
Preload("Profiles.Items").
Preload("Profiles.Items.Variants").
Preload("Profiles.Gifts").
Preload("Profiles.Gifts.Loot").
Preload("Profiles.Quests").
Preload("Discord").
Where("display_name = ?", displayName).
Find(&dbPerson)
if dbPerson.ID == "" { if dbPerson.ID == "" {
return nil return nil
@ -102,19 +97,7 @@ func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
func (s *PostgresStorage) GetPersonsByPartialDisplay(displayName string) []*DB_Person { func (s *PostgresStorage) GetPersonsByPartialDisplay(displayName string) []*DB_Person {
var dbPersons []*DB_Person var dbPersons []*DB_Person
s.Postgres. s.PreloadPerson().Where("display_name LIKE ?", "%" + displayName + "%").Find(&dbPersons)
Model(&DB_Person{}).
Preload("Profiles").
Preload("Profiles.Loadouts").
Preload("Profiles.Attributes").
Preload("Profiles.Items").
Preload("Profiles.Items.Variants").
Preload("Profiles.Gifts").
Preload("Profiles.Gifts.Loot").
Preload("Profiles.Quests").
Preload("Discord").
Where("display_name LIKE ?", "%" + displayName + "%").
Find(&dbPersons)
if len(dbPersons) == 0 { if len(dbPersons) == 0 {
return nil return nil
@ -136,19 +119,7 @@ func (s *PostgresStorage) GetPersonByDiscordID(discordId string) *DB_Person {
func (s *PostgresStorage) GetAllPersons() []*DB_Person { func (s *PostgresStorage) GetAllPersons() []*DB_Person {
var dbPersons []*DB_Person var dbPersons []*DB_Person
s.PreloadPerson().Find(&dbPersons)
s.Postgres.
Model(&DB_Person{}).
Preload("Profiles").
Preload("Profiles.Loadouts").
Preload("Profiles.Attributes").
Preload("Profiles.Items").
Preload("Profiles.Items.Variants").
Preload("Profiles.Gifts").
Preload("Profiles.Gifts.Loot").
Preload("Profiles.Quests").
Preload("Discord").
Find(&dbPersons)
return dbPersons return dbPersons
} }
@ -170,18 +141,7 @@ func (s *PostgresStorage) SavePerson(person *DB_Person) {
} }
func (s *PostgresStorage) DeletePerson(personId string) { func (s *PostgresStorage) DeletePerson(personId string) {
s.Postgres. s.PreloadPerson().Delete(&DB_Person{}, "id = ?", personId)
Model(&DB_Person{}).
Preload("Profiles").
Preload("Profiles.Loadouts").
Preload("Profiles.Attributes").
Preload("Profiles.Items").
Preload("Profiles.Items.Variants").
Preload("Profiles.Gifts").
Preload("Profiles.Gifts.Loot").
Preload("Profiles.Quests").
Preload("Discord").
Delete(&DB_Person{}, "id = ?", personId)
} }
func (s *PostgresStorage) GetIncomingRelationships(personId string) []*DB_Relationship { func (s *PostgresStorage) GetIncomingRelationships(personId string) []*DB_Relationship {
@ -276,6 +236,14 @@ func (s *PostgresStorage) DeleteLoadout(loadoutId string) {
s.Postgres.Delete(&DB_Loadout{}, "id = ?", loadoutId) s.Postgres.Delete(&DB_Loadout{}, "id = ?", loadoutId)
} }
func (s *PostgresStorage) SavePurchase(purchase *DB_Purchase) {
s.Postgres.Save(purchase)
}
func (s *PostgresStorage) DeletePurchase(purchaseId string) {
s.Postgres.Delete(&DB_Purchase{}, "id = ?", purchaseId)
}
func (s *PostgresStorage) SaveDiscordPerson(discordPerson *DB_DiscordPerson) { func (s *PostgresStorage) SaveDiscordPerson(discordPerson *DB_DiscordPerson) {
s.Postgres.Save(discordPerson) s.Postgres.Save(discordPerson)
} }

View File

@ -49,6 +49,9 @@ type Storage interface {
SaveLoadout(loadout *DB_Loadout) SaveLoadout(loadout *DB_Loadout)
DeleteLoadout(loadoutId string) DeleteLoadout(loadoutId string)
SavePurchase(purchase *DB_Purchase)
DeletePurchase(purchaseId string)
SaveDiscordPerson(person *DB_DiscordPerson) SaveDiscordPerson(person *DB_DiscordPerson)
DeleteDiscordPerson(personId string) DeleteDiscordPerson(personId string)
} }
@ -207,6 +210,14 @@ func (r *Repository) DeleteLoadout(loadoutId string) {
r.Storage.DeleteLoadout(loadoutId) r.Storage.DeleteLoadout(loadoutId)
} }
func (r *Repository) SavePurchase(purchase *DB_Purchase) {
r.Storage.SavePurchase(purchase)
}
func (r *Repository) DeletePurchase(purchaseId string) {
r.Storage.DeletePurchase(purchaseId)
}
func (r *Repository) SaveDiscordPerson(person *DB_DiscordPerson) { func (r *Repository) SaveDiscordPerson(person *DB_DiscordPerson) {
r.Storage.SaveDiscordPerson(person) r.Storage.SaveDiscordPerson(person)
} }

View File

@ -9,12 +9,12 @@ type Tabler interface {
type DB_Person struct { type DB_Person struct {
ID string ID string
DisplayName string DisplayName string
RefundTickets int
Permissions pq.StringArray `gorm:"type:text[]"` Permissions pq.StringArray `gorm:"type:text[]"`
Profiles []DB_Profile `gorm:"foreignkey:PersonID"` Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
Stats []DB_SeasonStat `gorm:"foreignkey:PersonID"` Stats []DB_SeasonStat `gorm:"foreignkey:PersonID"`
Purchases []DB_Purchase `gorm:"foreignkey:ProfileID"`
Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"` Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"`
BanHistory []DB_BanStatus `gorm:"foreignkey:PersonID"` BanHistory []DB_BanStatus `gorm:"foreignkey:PersonID"`
} }
func (DB_Person) TableName() string { func (DB_Person) TableName() string {
@ -39,6 +39,7 @@ type DB_Profile struct {
Quests []DB_Quest `gorm:"foreignkey:ProfileID"` Quests []DB_Quest `gorm:"foreignkey:ProfileID"`
Attributes []DB_Attribute `gorm:"foreignkey:ProfileID"` Attributes []DB_Attribute `gorm:"foreignkey:ProfileID"`
Loadouts []DB_Loadout `gorm:"foreignkey:ProfileID"` Loadouts []DB_Loadout `gorm:"foreignkey:ProfileID"`
Purchases []DB_Purchase `gorm:"foreignkey:ProfileID"`
Type string Type string
Revision int Revision int
} }
@ -95,16 +96,28 @@ func (DB_Item) TableName() string {
return "Items" return "Items"
} }
type DB_VariantChannel struct {
ID string `gorm:"primary_key"`
ItemID string `gorm:"index"`
Channel string
Owned pq.StringArray `gorm:"type:text[]"`
Active string
}
func (DB_VariantChannel) TableName() string {
return "Variants"
}
type DB_Purchase struct { type DB_Purchase struct {
ID string `gorm:"primary_key"` ID string `gorm:"primary_key"`
ProfileID string `gorm:"index"` ProfileID string `gorm:"index"`
Loot []DB_PurchaseLoot `gorm:"foreignkey:PurchaseID"`
OfferID string OfferID string
PurchaseDate int64 PurchaseDate int64
FreeRefundExpiry int64 FreeRefundExpiry int64
RefundExpiry int64 RefundExpiry int64
RefundedAt int64 RefundedAt int64
TotalPaid int TotalPaid int
Loot []DB_PurchaseLoot `gorm:"foreignkey:PurchaseID"`
} }
func (DB_Purchase) TableName() string { func (DB_Purchase) TableName() string {
@ -123,18 +136,6 @@ func (DB_PurchaseLoot) TableName() string {
return "PurchaseLoot" return "PurchaseLoot"
} }
type DB_VariantChannel struct {
ID string `gorm:"primary_key"`
ItemID string `gorm:"index"`
Channel string
Owned pq.StringArray `gorm:"type:text[]"`
Active string
}
func (DB_VariantChannel) TableName() string {
return "Variants"
}
type DB_Quest struct { type DB_Quest struct {
ID string `gorm:"primary_key"` ID string `gorm:"primary_key"`
ProfileID string `gorm:"index"` ProfileID string `gorm:"index"`