Merge branch 'develop'

This commit is contained in:
Fran Jurmanović
2021-06-20 15:48:09 +02:00
7 changed files with 137 additions and 74 deletions

View File

@@ -30,6 +30,9 @@ func Routes(s *gin.Engine, db *pg.DB) {
subscriptionService := services.SubscriptionService{Db: db} subscriptionService := services.SubscriptionService{Db: db}
subscriptionTypeService := services.SubscriptionTypeService{Db: db} subscriptionTypeService := services.SubscriptionTypeService{Db: db}
walletService.Ss = &subscriptionService
transactionService.Ss = &subscriptionService
controllers.NewApiController(&apiService, api) controllers.NewApiController(&apiService, api)
controllers.NewAuthController(&usersService, auth) controllers.NewAuthController(&usersService, auth)
controllers.NewWalletsController(&walletService, wallet) controllers.NewWalletsController(&walletService, wallet)

View File

@@ -20,7 +20,7 @@ type Subscription struct {
TransactionTypeID string `json:"transactionTypeId", pg:"transaction_type_id"` TransactionTypeID string `json:"transactionTypeId", pg:"transaction_type_id"`
TransactionType *TransactionType `json:"transactionType", pg:"rel:has-one, fk:transaction_type_id"` TransactionType *TransactionType `json:"transactionType", pg:"rel:has-one, fk:transaction_type_id"`
LastTransactionDate time.Time `json:"lastTransactionDate", pg:"last_transaction_date"` LastTransactionDate time.Time `json:"lastTransactionDate", pg:"last_transaction_date"`
Amount int `json:"amount", pg:"amount"` Amount float32 `json:"amount", pg:"amount"`
} }
type NewSubscriptionBody struct { type NewSubscriptionBody struct {
@@ -45,5 +45,6 @@ func (cm *Subscription) ToTrans() *Transaction {
trans.TransactionTypeID = cm.TransactionTypeID trans.TransactionTypeID = cm.TransactionTypeID
trans.TransactionType = cm.TransactionType trans.TransactionType = cm.TransactionType
trans.DateCreated = cm.DateCreated trans.DateCreated = cm.DateCreated
trans.SubscriptionID = cm.Id
return trans return trans
} }

View File

@@ -12,7 +12,7 @@ type Transaction struct {
TransactionTypeID string `json:"transactionTypeId", pg:"transaction_type_id"` TransactionTypeID string `json:"transactionTypeId", pg:"transaction_type_id"`
TransactionType *TransactionType `json:"transactionType", pg:"rel:has-one, fk:transaction_type_id"` TransactionType *TransactionType `json:"transactionType", pg:"rel:has-one, fk:transaction_type_id"`
WalletID string `json:"walletId", pg:"wallet_id"` WalletID string `json:"walletId", pg:"wallet_id"`
Amount int `json:"amount", pg:"amount"` Amount float32 `json:"amount", pg:"amount"`
Wallet *Wallet `json:"wallet" pg:"rel:has-one, fk:wallet_id"` Wallet *Wallet `json:"wallet" pg:"rel:has-one, fk:wallet_id"`
TransactionDate time.Time `json:"transactionDate" pg:"transaction_date"` TransactionDate time.Time `json:"transactionDate" pg:"transaction_date"`
SubscriptionID string `json:"subscriptionId", pg:"subscription_id"` SubscriptionID string `json:"subscriptionId", pg:"subscription_id"`

View File

@@ -15,13 +15,16 @@ type NewWalletBody struct {
type WalletHeader struct { type WalletHeader struct {
WalletId string `json:"walletId"` WalletId string `json:"walletId"`
CurrentBalance int `json:"currentBalance"` CurrentBalance float32 `json:"currentBalance"`
LastMonth int `json:"lastMonth"` LastMonth float32 `json:"lastMonth"`
NextMonth int `json:"nextMonth"` NextMonth float32 `json:"nextMonth"`
Currency string `json:"currency"` Currency string `json:"currency"`
} }
type WalletTransactions struct { type WalletTransactions struct {
WalletId string WalletId string
Transactions []Transaction Transactions []Transaction
CurrentBalance float32
LastMonth float32
NextMonth float32
} }

View File

@@ -1,6 +1,7 @@
package services package services
import ( import (
"math"
"time" "time"
"wallet-api/pkg/models" "wallet-api/pkg/models"
@@ -14,7 +15,7 @@ type SubscriptionService struct {
func (as *SubscriptionService) New(body *models.NewSubscriptionBody) *models.Subscription { func (as *SubscriptionService) New(body *models.NewSubscriptionBody) *models.Subscription {
tm := new(models.Subscription) tm := new(models.Subscription)
amount, _ := body.Amount.Int64() amount, _ := body.Amount.Float64()
customRange, _ := body.CustomRange.Int64() customRange, _ := body.CustomRange.Int64()
tm.Init() tm.Init()
@@ -26,7 +27,7 @@ func (as *SubscriptionService) New(body *models.NewSubscriptionBody) *models.Sub
tm.StartDate = body.StartDate tm.StartDate = body.StartDate
tm.HasEnd = body.HasEnd tm.HasEnd = body.HasEnd
tm.EndDate = body.EndDate tm.EndDate = body.EndDate
tm.Amount = int(amount) tm.Amount = float32(math.Round(amount*100) / 100)
if body.StartDate.IsZero() { if body.StartDate.IsZero() {
tm.StartDate = time.Now() tm.StartDate = time.Now()
@@ -34,6 +35,8 @@ func (as *SubscriptionService) New(body *models.NewSubscriptionBody) *models.Sub
as.Db.Model(tm).Insert() as.Db.Model(tm).Insert()
as.SubToTrans(tm)
return tm return tm
} }
@@ -46,3 +49,50 @@ func (as *SubscriptionService) GetAll(am *models.Auth, walletId string, filtered
} }
FilteredResponse(query, wm, filtered) FilteredResponse(query, wm, filtered)
} }
func (as *SubscriptionService) SubToTrans(subModel *models.Subscription) {
now := time.Now()
currentYear, currentMonth, _ := now.Date()
currentLocation := now.Location()
firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation)
startDate := subModel.StartDate.Local()
stopDate := firstOfNextMonth
if subModel.HasEnd && subModel.EndDate.Local().Before(firstOfNextMonth) {
stopDate = subModel.EndDate.Local()
}
transactions := new([]models.Transaction)
if subModel.SubscriptionType == nil {
st := new(models.SubscriptionType)
as.Db.Model(st).Where("? = ?", pg.Ident("id"), subModel.SubscriptionTypeID).Select()
subModel.SubscriptionType = st
}
for startDate.Before(stopDate) {
trans := subModel.ToTrans()
trans.TransactionDate = startDate
if startDate.After(subModel.LastTransactionDate) {
*transactions = append(*transactions, *trans)
}
if subModel.SubscriptionType.Type == "monthly" {
startDate = startDate.AddDate(0, subModel.CustomRange, 0)
} else if subModel.SubscriptionType.Type == "weekly" {
startDate = startDate.AddDate(0, 0, 7*subModel.CustomRange)
} else if subModel.SubscriptionType.Type == "daily" {
startDate = startDate.AddDate(0, 0, subModel.CustomRange)
} else {
startDate = startDate.AddDate(subModel.CustomRange, 0, 0)
}
}
if len(*transactions) > 0 {
as.Db.Model(transactions).Insert()
subModel.LastTransactionDate = (*transactions)[len(*transactions)-1].TransactionDate
as.Db.Model(subModel).WherePK().Update()
}
}

View File

@@ -1,6 +1,7 @@
package services package services
import ( import (
"math"
"time" "time"
"wallet-api/pkg/models" "wallet-api/pkg/models"
@@ -9,19 +10,20 @@ import (
type TransactionService struct { type TransactionService struct {
Db *pg.DB Db *pg.DB
Ss *SubscriptionService
} }
func (as *TransactionService) New(body *models.NewTransactionBody) *models.Transaction { func (as *TransactionService) New(body *models.NewTransactionBody) *models.Transaction {
tm := new(models.Transaction) tm := new(models.Transaction)
amount, _ := body.Amount.Int64() amount, _ := body.Amount.Float64()
tm.Init() tm.Init()
tm.WalletID = body.WalletID tm.WalletID = body.WalletID
tm.TransactionTypeID = body.TransactionTypeID tm.TransactionTypeID = body.TransactionTypeID
tm.Description = body.Description tm.Description = body.Description
tm.TransactionDate = body.TransactionDate tm.TransactionDate = body.TransactionDate
tm.Amount = int(amount) tm.Amount = float32(math.Round(amount*100) / 100)
if body.TransactionDate.IsZero() { if body.TransactionDate.IsZero() {
tm.TransactionDate = time.Now() tm.TransactionDate = time.Now()
@@ -34,8 +36,18 @@ func (as *TransactionService) New(body *models.NewTransactionBody) *models.Trans
func (as *TransactionService) GetAll(am *models.Auth, walletId string, filtered *models.FilteredResponse) { func (as *TransactionService) GetAll(am *models.Auth, walletId string, filtered *models.FilteredResponse) {
wm := new([]models.Transaction) wm := new([]models.Transaction)
sm := new([]models.Subscription)
query := as.Db.Model((wm)).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id) query2 := as.Db.Model(sm).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id)
if walletId != "" {
query2 = query2.Where("? = ?", pg.Ident("wallet_id"), walletId)
}
for _, sub := range *sm {
as.Ss.SubToTrans(&sub)
}
query := as.Db.Model(wm).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id)
if walletId != "" { if walletId != "" {
query = query.Where("? = ?", pg.Ident("wallet_id"), walletId) query = query.Where("? = ?", pg.Ident("wallet_id"), walletId)
} }

View File

@@ -11,6 +11,7 @@ import (
type WalletService struct { type WalletService struct {
Db *pg.DB Db *pg.DB
Ss *SubscriptionService
} }
func (as *WalletService) New(am *models.NewWalletBody) *models.Wallet { func (as *WalletService) New(am *models.NewWalletBody) *models.Wallet {
@@ -41,7 +42,7 @@ func (as *WalletService) GetAll(am *models.Auth, filtered *models.FilteredRespon
func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId string) *models.WalletHeader { func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId string) *models.WalletHeader {
wm := new(models.WalletHeader) wm := new(models.WalletHeader)
var wallets []models.WalletTransactions wallets := new([]models.WalletTransactions)
var wg sync.WaitGroup var wg sync.WaitGroup
transactions := new([]models.Transaction) transactions := new([]models.Transaction)
subscriptions := new([]models.Subscription) subscriptions := new([]models.Subscription)
@@ -67,14 +68,6 @@ func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId strin
wg.Wait() wg.Wait()
currentBalance := 0
lastMonthBalance := 0
nextMonth := 0
subCurrentBalance := 0
subLastMonthBalance := 0
subNextMonth := 0
now := time.Now() now := time.Now()
currentYear, currentMonth, _ := now.Date() currentYear, currentMonth, _ := now.Date()
@@ -85,57 +78,59 @@ func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId strin
firstOfMonthAfterNext := time.Date(currentYear, currentMonth+2, 1, 0, 0, 0, 0, currentLocation) firstOfMonthAfterNext := time.Date(currentYear, currentMonth+2, 1, 0, 0, 0, 0, currentLocation)
for _, trans := range *transactions { for _, trans := range *transactions {
addWhere(&wallets, trans.WalletID, trans) addWhere(wallets, trans.WalletID, trans)
} }
for _, sub := range *subscriptions { for _, sub := range *subscriptions {
startDate := sub.StartDate.Local() as.Ss.SubToTrans(&sub)
stopDate := firstOfMonthAfterNext // startDate := sub.StartDate.Local()
if sub.HasEnd { // stopDate := firstOfMonthAfterNext
stopDate = sub.EndDate.Local() // if sub.HasEnd {
} // stopDate = sub.EndDate.Local()
for startDate.Before(stopDate) { // }
trans := sub.ToTrans() // for startDate.Before(stopDate) {
trans.TransactionDate = startDate // trans := sub.ToTrans()
addWhere(&wallets, sub.WalletID, *trans) // trans.TransactionDate = startDate
if sub.SubscriptionType.Type == "monthly" { // addWhere(&wallets, sub.WalletID, *trans)
startDate = startDate.AddDate(0, sub.CustomRange, 0) // if sub.SubscriptionType.Type == "monthly" {
} else if sub.SubscriptionType.Type == "weekly" { // startDate = startDate.AddDate(0, sub.CustomRange, 0)
startDate = startDate.AddDate(0, 0, 7*sub.CustomRange) // } else if sub.SubscriptionType.Type == "weekly" {
} else if sub.SubscriptionType.Type == "daily" { // startDate = startDate.AddDate(0, 0, 7*sub.CustomRange)
startDate = startDate.AddDate(0, 0, sub.CustomRange) // } else if sub.SubscriptionType.Type == "daily" {
} else { // startDate = startDate.AddDate(0, 0, sub.CustomRange)
startDate = startDate.AddDate(sub.CustomRange, 0, 0) // } else {
} // startDate = startDate.AddDate(sub.CustomRange, 0, 0)
} // }
// }
} }
for _, wallet := range wallets { for i, wallet := range *wallets {
wg.Add(1) // wg.Add(1)
go func() { // go func() {
defer wg.Done() // defer wg.Done()
for _, trans := range wallet.Transactions { for _, trans := range wallet.Transactions {
if trans.TransactionDate.Local().Before(firstOfNextMonth) && trans.TransactionDate.Local().After(firstOfMonth) { if trans.TransactionDate.Local().Before(firstOfNextMonth) && trans.TransactionDate.Local().After(firstOfMonth) {
if trans.TransactionType.Type == "expense" { if trans.TransactionType.Type == "expense" {
currentBalance -= trans.Amount (*wallets)[i].CurrentBalance -= trans.Amount
} else { } else {
currentBalance += trans.Amount (*wallets)[i].CurrentBalance += trans.Amount
} }
} else if trans.TransactionDate.Local().Before(firstOfMonthAfterNext) && trans.TransactionDate.Local().After(firstOfNextMonth) { } else if trans.TransactionDate.Local().Before(firstOfMonthAfterNext) && trans.TransactionDate.Local().After(firstOfNextMonth) {
if trans.TransactionType.Type == "expense" { if trans.TransactionType.Type == "expense" {
nextMonth -= trans.Amount (*wallets)[i].NextMonth -= trans.Amount
} else { } else {
nextMonth += trans.Amount (*wallets)[i].NextMonth += trans.Amount
} }
} else if trans.TransactionDate.Local().Before(firstOfMonth) { } else if trans.TransactionDate.Local().Before(firstOfMonth) {
if trans.TransactionType.Type == "expense" { if trans.TransactionType.Type == "expense" {
lastMonthBalance -= trans.Amount (*wallets)[i].LastMonth -= trans.Amount
} else { } else {
lastMonthBalance += trans.Amount (*wallets)[i].LastMonth += trans.Amount
} }
} }
} }
}() // }()
} }
// for _, sub := range *subscriptions { // for _, sub := range *subscriptions {
@@ -171,13 +166,12 @@ func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId strin
wg.Wait() wg.Wait()
combinedCurrent := currentBalance + subCurrentBalance for _, wallet := range *wallets {
combinedLast := lastMonthBalance + subLastMonthBalance wm.LastMonth += wallet.LastMonth
combinedNext := nextMonth + subNextMonth wm.CurrentBalance += wallet.CurrentBalance + wallet.LastMonth
wm.NextMonth += wallet.NextMonth + wallet.CurrentBalance + wallet.LastMonth
}
wm.LastMonth = combinedLast
wm.CurrentBalance = combinedCurrent + combinedLast
wm.NextMonth = combinedLast + combinedCurrent + combinedNext
wm.Currency = "USD" wm.Currency = "USD"
wm.WalletId = walletId wm.WalletId = walletId
@@ -191,9 +185,9 @@ func addWhere(s *[]models.WalletTransactions, walletId string, e models.Transact
for a, _ := range *s { for a, _ := range *s {
if (*s)[a].WalletId == walletId { if (*s)[a].WalletId == walletId {
(*s)[a].Transactions = append((*s)[a].Transactions, e) (*s)[a].Transactions = append((*s)[a].Transactions, e)
}
exists = true exists = true
} }
}
if !exists { if !exists {
var walletTransaction models.WalletTransactions var walletTransaction models.WalletTransactions
walletTransaction.WalletId = walletId walletTransaction.WalletId = walletId