diff --git a/pkg/controller/api.go b/pkg/controller/api.go index ff1e972..e8c7a4e 100644 --- a/pkg/controller/api.go +++ b/pkg/controller/api.go @@ -56,11 +56,11 @@ Requires "SECRET_CODE", "VERSION" (optional) from body. func (ac *ApiController) postMigrate(c *gin.Context) { migrateModel := c.MustGet("migrate") version := migrateModel.(middleware.SecretCodeModel).Version - mr, er := ac.service.PostMigrate(c, version) + er := ac.service.PostMigrate(c, version) - if er.Message != "" { - c.JSON(er.StatusCode, er) + if len(er) > 0 { + c.JSON(500, er) } else { - c.JSON(200, mr) + c.JSON(200, nil) } } diff --git a/pkg/controller/subscription.go b/pkg/controller/subscription.go index ddd3150..f413c3a 100644 --- a/pkg/controller/subscription.go +++ b/pkg/controller/subscription.go @@ -56,7 +56,9 @@ func (wc *SubscriptionController) New(c *gin.Context) { return } - wm, exception := wc.service.New(c, body) + mdl := body.ToSubscription() + + wm, exception := wc.service.New(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) @@ -81,7 +83,10 @@ func (wc *SubscriptionController) Edit(c *gin.Context) { id := c.Param("id") - wm, exception := wc.service.Edit(c, body, id) + mdl := body.ToSubscription() + mdl.Id = id + + wm, exception := wc.service.Edit(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -96,11 +101,10 @@ Get */ // ROUTE (GET /subscription/:id) func (wc *SubscriptionController) Get(c *gin.Context) { - body := new(model.Auth) params := new(model.Params) auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id + userId := auth.(*model.Auth).Id id := c.Param("id") @@ -109,8 +113,9 @@ func (wc *SubscriptionController) Get(c *gin.Context) { flt := filter.NewSubscriptionFilter(*params) flt.Id = id + flt.UserId = userId - fr, exception := wc.service.Get(c, body, *flt) + fr, exception := wc.service.Get(c, *flt) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -121,17 +126,6 @@ func (wc *SubscriptionController) Get(c *gin.Context) { // ROUTE (PUT /subscription/end/:id) func (wc *SubscriptionController) End(c *gin.Context) { - body := new(model.Auth) - - auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id - - end := new(model.SubscriptionEnd) - if err := c.ShouldBind(end); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - id := c.Param("id") fr, exception := wc.service.End(c, id) @@ -152,14 +146,14 @@ GetAll func (wc *SubscriptionController) GetAll(c *gin.Context) { auth := c.MustGet("auth") - fr := FilteredResponse(c) wallet, _ := c.GetQuery("walletId") + embed, _ := c.GetQuery("embed") - flt := filter.NewSubscriptionFilter(model.Params{}) + flt := filter.NewSubscriptionFilter(model.Params{Embed: embed}) flt.WalletId = wallet - flt.Id = auth.(*model.Auth).Id + flt.UserId = auth.(*model.Auth).Id - exception := wc.service.GetAll(c, flt, fr) + fr, exception := wc.service.GetAll(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/controller/subscriptionType.go b/pkg/controller/subscriptionType.go index f55aba5..f0d5169 100644 --- a/pkg/controller/subscriptionType.go +++ b/pkg/controller/subscriptionType.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" @@ -48,7 +49,9 @@ func (wc *SubscriptionTypeController) New(c *gin.Context) { return } - wm, exception := wc.service.New(c, body) + mdl := body.ToSubscriptionType() + + wm, exception := wc.service.New(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -65,7 +68,9 @@ GetAll func (wc *SubscriptionTypeController) GetAll(c *gin.Context) { embed, _ := c.GetQuery("embed") - wm, exception := wc.service.GetAll(c, embed) + flt := filter.NewSubscriptionTypeFilter(model.Params{Embed: embed}) + + wm, exception := wc.service.GetAll(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/controller/transaction.go b/pkg/controller/transaction.go index 2b8a6c7..760ab3f 100644 --- a/pkg/controller/transaction.go +++ b/pkg/controller/transaction.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" @@ -60,7 +61,9 @@ func (wc *TransactionController) New(c *gin.Context) { return } - wm, exception := wc.service.New(c, body) + mdl := body.ToTransaction() + + wm, exception := wc.service.New(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -75,17 +78,22 @@ GetAll */ // ROUTE (GET /transactions) func (wc *TransactionController) GetAll(c *gin.Context) { - body := new(model.Auth) auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id + userId := auth.(*model.Auth).Id fr := FilteredResponse(c) wallet, _ := c.GetQuery("walletId") + embed, _ := c.GetQuery("embed") noPendingQry, _ := c.GetQuery("noPending") noPending := noPendingQry != "" - exception := wc.service.GetAll(c, body, wallet, fr, noPending) + flt := filter.NewTransactionFilter(model.Params{Embed: embed}) + flt.WalletId = wallet + flt.NoPending = noPending + flt.UserId = userId + + fr, exception := wc.service.GetAll(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -101,14 +109,17 @@ Check */ // ROUTE (GET /transactions) func (wc *TransactionController) Check(c *gin.Context) { - body := new(model.Auth) auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id + userId := auth.(*model.Auth).Id fr := FilteredResponse(c) wallet, _ := c.GetQuery("walletId") - exception := wc.service.Check(c, body, wallet, fr) + flt := filter.NewTransactionFilter(model.Params{}) + flt.WalletId = wallet + flt.UserId = userId + + fr, exception := wc.service.Check(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -131,8 +142,10 @@ func (wc *TransactionController) Edit(c *gin.Context) { } id := c.Param("id") + mdl := body.ToTransaction() + mdl.Id = id - wm, exception := wc.service.Edit(c, body, id) + wm, exception := wc.service.Edit(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -153,7 +166,13 @@ func (wc *TransactionController) BulkEdit(c *gin.Context) { return } - wm, exception := wc.service.BulkEdit(c, body) + mdl := new([]model.Transaction) + for _, transaction := range *body { + tm := transaction.ToTransaction() + *mdl = append(*mdl, *tm) + } + + wm, exception := wc.service.BulkEdit(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -168,18 +187,21 @@ Get */ // ROUTE (GET /transactions/:id) func (wc *TransactionController) Get(c *gin.Context) { - body := new(model.Auth) params := new(model.Params) auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id + userId := auth.(*model.Auth).Id id := c.Param("id") embed, _ := c.GetQuery("embed") params.Embed = embed - fr, exception := wc.service.Get(c, body, id, params) + flt := filter.NewTransactionFilter(*params) + flt.Id = id + flt.UserId = userId + + fr, exception := wc.service.Get(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/controller/transactionStatus.go b/pkg/controller/transactionStatus.go index 3f99aa9..e3fbd6a 100644 --- a/pkg/controller/transactionStatus.go +++ b/pkg/controller/transactionStatus.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" @@ -48,7 +49,9 @@ func (wc *TransactionStatusController) New(c *gin.Context) { return } - wm, exception := wc.service.New(c, body) + mdl := body.ToTransactionStatus() + + wm, exception := wc.service.New(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -64,8 +67,9 @@ GetAll // ROUTE (GET /transaction-status) func (wc *TransactionStatusController) GetAll(c *gin.Context) { embed, _ := c.GetQuery("embed") + flt := filter.NewTransactionStatusFilter(model.Params{Embed: embed}) - wm, exception := wc.service.GetAll(c, embed) + wm, exception := wc.service.GetAll(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/controller/transactionType.go b/pkg/controller/transactionType.go index c04d412..9b5e734 100644 --- a/pkg/controller/transactionType.go +++ b/pkg/controller/transactionType.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" @@ -47,8 +48,9 @@ func (wc *TransactionTypeController) New(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } + mdl := body.ToTransactionType() - wm, exception := wc.service.New(c, body) + wm, exception := wc.service.New(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -65,7 +67,9 @@ GetAll func (wc *TransactionTypeController) GetAll(c *gin.Context) { embed, _ := c.GetQuery("embed") - wm, exception := wc.service.GetAll(c, embed) + flt := filter.NewTransactionTypeFilter(model.Params{Embed: embed}) + + wm, exception := wc.service.GetAll(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/controller/user.go b/pkg/controller/user.go index cd12358..a33ecc6 100644 --- a/pkg/controller/user.go +++ b/pkg/controller/user.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "wallet-api/pkg/filter" "wallet-api/pkg/middleware" "wallet-api/pkg/model" "wallet-api/pkg/service" @@ -91,11 +92,13 @@ Delete */ // ROUTE (DELETE /auth/deactivate). func (rc *UserController) Delete(c *gin.Context) { - auth := new(model.Auth) authGet := c.MustGet("auth") - auth.Id = authGet.(*model.Auth).Id + userId := authGet.(*model.Auth).Id - mr, er := rc.service.Deactivate(c, auth) + flt := filter.NewUserFilter(model.Params{}) + flt.UserId = userId + + mr, er := rc.service.Deactivate(c, flt) if er.Message != "" { c.JSON(er.StatusCode, er) diff --git a/pkg/controller/wallet-header.go b/pkg/controller/wallet-header.go index 7b5b1ac..708b3b2 100644 --- a/pkg/controller/wallet-header.go +++ b/pkg/controller/wallet-header.go @@ -1,6 +1,7 @@ package controller import ( + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" @@ -40,14 +41,17 @@ Get */ // ROUTE (GET /wallet/wallet-header) func (wc *WalletHeaderController) Get(c *gin.Context) { - body := new(model.Auth) - walletId, _ := c.GetQuery("walletId") auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id + userId := auth.(*model.Auth).Id + embed, _ := c.GetQuery("embed") - wm, exception := wc.service.GetHeader(c, body, walletId) + flt := filter.NewWalletHeaderFilter(model.Params{Embed: embed}) + flt.UserId = userId + flt.WalletId = walletId + + wm, exception := wc.service.GetHeader(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/controller/wallet.go b/pkg/controller/wallet.go index dbdfc62..dac08a0 100644 --- a/pkg/controller/wallet.go +++ b/pkg/controller/wallet.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" @@ -69,13 +70,14 @@ GetAll */ // ROUTE (GET /wallet) func (wc *WalletController) GetAll(c *gin.Context) { - body := new(model.Auth) auth := c.MustGet("auth") - body.Id = auth.(*model.Auth).Id + userId := auth.(*model.Auth).Id - fr := FilteredResponse(c) + embed, _ := c.GetQuery("embed") + flt := filter.NewWalletFilter(model.Params{Embed: embed}) + flt.UserId = userId - exception := wc.service.GetAll(c, body, fr) + fr, exception := wc.service.GetAll(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -99,7 +101,10 @@ func (wc *WalletController) Edit(c *gin.Context) { id := c.Param("id") - wm, exception := wc.service.Edit(c, body, id) + mdl := body.ToWallet() + mdl.Id = id + + wm, exception := wc.service.Edit(c, mdl) if exception != nil { c.JSON(exception.StatusCode, exception) return @@ -121,7 +126,10 @@ func (wc *WalletController) Get(c *gin.Context) { embed, _ := c.GetQuery("embed") params.Embed = embed - fr, exception := wc.service.Get(c, id, params) + flt := filter.NewWalletFilter(*params) + flt.Id = id + + fr, exception := wc.service.Get(c, flt) if exception != nil { c.JSON(exception.StatusCode, exception) return diff --git a/pkg/filter/filter.go b/pkg/filter/filter.go index 10aa5c1..07924d9 100644 --- a/pkg/filter/filter.go +++ b/pkg/filter/filter.go @@ -1,6 +1,9 @@ package filter -import "go.uber.org/dig" +import ( + "go.uber.org/dig" + "wallet-api/pkg/model" +) /* InitializeFilters @@ -22,6 +25,13 @@ func InitializeFilters(c *dig.Container) { } type BaseFilter struct { + model.Params Id string WalletId string + UserId string +} + +type BBa interface { + BaseFilter + some() bool } diff --git a/pkg/model/api.go b/pkg/model/api.go index 787c9cc..a280ab7 100644 --- a/pkg/model/api.go +++ b/pkg/model/api.go @@ -1,6 +1,7 @@ package model type ApiModel struct { + BaseModel tableName struct{} `pg:"api,alias:api"` Api string `json:"api"` } diff --git a/pkg/model/model.go b/pkg/model/model.go index 3faa4f0..b8c6efe 100644 --- a/pkg/model/model.go +++ b/pkg/model/model.go @@ -1,6 +1,8 @@ package model -import "github.com/gin-gonic/gin" +import ( + "github.com/gin-gonic/gin" +) type FilteredResponse struct { Items interface{} `json:"items"` diff --git a/pkg/model/subscription.go b/pkg/model/subscription.go index 6229f93..a8e2e27 100644 --- a/pkg/model/subscription.go +++ b/pkg/model/subscription.go @@ -2,6 +2,7 @@ package model import ( "encoding/json" + "math" "time" ) @@ -45,6 +46,41 @@ type NewSubscriptionBody struct { Amount json.Number `json:"amount" form:"amount"` } +func (body *SubscriptionEdit) ToSubscription() *Subscription { + amount, _ := body.Amount.Float64() + tm := new(Subscription) + tm.Id = body.Id + tm.EndDate = body.EndDate + tm.HasEnd = body.HasEnd + tm.Description = body.Description + tm.WalletID = body.WalletID + tm.Amount = float32(math.Round(amount*100) / 100) + + return tm +} + +func (body *NewSubscriptionBody) ToSubscription() *Subscription { + tm := new(Subscription) + amount, _ := body.Amount.Float64() + customRange, _ := body.CustomRange.Int64() + + tm.Init() + tm.WalletID = body.WalletID + tm.TransactionTypeID = body.TransactionTypeID + tm.SubscriptionTypeID = body.SubscriptionTypeID + tm.CustomRange = int(customRange) + tm.Description = body.Description + tm.StartDate = body.StartDate + tm.HasEnd = body.HasEnd + tm.EndDate = body.EndDate + tm.Amount = float32(math.Round(amount*100) / 100) + + if body.StartDate.IsZero() { + tm.StartDate = time.Now() + } + return tm +} + type SubscriptionEnd struct { Id string `json:"id" form:"id"` } diff --git a/pkg/model/subscriptionType.go b/pkg/model/subscriptionType.go index 12a7cb8..1bdd153 100644 --- a/pkg/model/subscriptionType.go +++ b/pkg/model/subscriptionType.go @@ -11,3 +11,13 @@ type NewSubscriptionTypeBody struct { Name string `json:"name" form:"name"` Type string `json:"type" form:"type"` } + +func (body *NewSubscriptionTypeBody) ToSubscriptionType() *SubscriptionType { + tm := new(SubscriptionType) + + tm.Init() + tm.Name = body.Name + tm.Type = body.Type + + return tm +} \ No newline at end of file diff --git a/pkg/model/transaction.go b/pkg/model/transaction.go index 9eb8ac5..38b3b82 100644 --- a/pkg/model/transaction.go +++ b/pkg/model/transaction.go @@ -2,6 +2,7 @@ package model import ( "encoding/json" + "math" "time" ) @@ -29,6 +30,23 @@ type NewTransactionBody struct { Amount json.Number `json:"amount" form:"amount"` } +func (body *NewTransactionBody) ToTransaction() *Transaction { + tm := new(Transaction) + amount, _ := body.Amount.Float64() + + tm.Init() + tm.WalletID = body.WalletID + tm.TransactionTypeID = body.TransactionTypeID + tm.Description = body.Description + tm.TransactionDate = body.TransactionDate + tm.Amount = float32(math.Round(amount*100) / 100) + + if body.TransactionDate.IsZero() { + tm.TransactionDate = time.Now() + } + return tm +} + type TransactionEdit struct { Id string `json:"id" form:"id"` WalletID string `json:"walletId" form:"walletId"` @@ -38,3 +56,18 @@ type TransactionEdit struct { Description string `json:"description" form:"description"` Amount json.Number `json:"amount" form:"amount"` } + +func (body *TransactionEdit) ToTransaction() *Transaction { + tm := new(Transaction) + amount, _ := body.Amount.Float64() + + tm.Id = body.Id + tm.Description = body.Description + tm.WalletID = body.WalletID + tm.TransactionTypeID = body.TransactionTypeID + tm.TransactionDate = body.TransactionDate + tm.TransactionStatusID = body.TransactionStatusID + tm.Amount = float32(math.Round(amount*100) / 100) + + return tm +} diff --git a/pkg/model/transactionStatus.go b/pkg/model/transactionStatus.go index 39e50d2..8e17dbc 100644 --- a/pkg/model/transactionStatus.go +++ b/pkg/model/transactionStatus.go @@ -11,3 +11,11 @@ type NewTransactionStatusBody struct { Name string `json:"name" form:"name"` Status string `json:"status" form:"status"` } + +func (body *NewTransactionStatusBody) ToTransactionStatus() *TransactionStatus { + tm := new(TransactionStatus) + tm.Init() + tm.Name = body.Name + tm.Status = body.Status + return tm +} diff --git a/pkg/model/transactionType.go b/pkg/model/transactionType.go index e40ddea..7566ac9 100644 --- a/pkg/model/transactionType.go +++ b/pkg/model/transactionType.go @@ -11,3 +11,11 @@ type NewTransactionTypeBody struct { Name string `json:"name" form:"name"` Type string `json:"type" form:"type"` } + +func (body *NewTransactionTypeBody) ToTransactionType() *TransactionType { + tm := new(TransactionType) + tm.Init() + tm.Name = body.Name + tm.Type = body.Type + return tm +} diff --git a/pkg/model/wallet.go b/pkg/model/wallet.go index b0e72c6..5d0c39f 100644 --- a/pkg/model/wallet.go +++ b/pkg/model/wallet.go @@ -33,3 +33,18 @@ type WalletEdit struct { Id string `json:"id" form:"id"` Name string `json:"name" form:"name"` } + +func (body *NewWalletBody) ToWallet() *Wallet { + tm := new(Wallet) + tm.Init() + tm.Name = body.Name + tm.UserID = body.UserID + return tm +} + +func (body *WalletEdit) ToWallet() *Wallet { + tm := new(Wallet) + tm.Name = body.Name + tm.Id = body.Id + return tm +} diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index f9e9a58..348275d 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -30,14 +30,16 @@ func InitializeRepositories(c *dig.Container) { /* FilteredResponse -Adds filters to query and executes it. +Adds filter to query and executes it. Args: *pg.Query: postgres query interface{}: model to be mapped from query execution. *model.FilteredResponse: filter options. */ -func FilteredResponse(qry *pg.Query, mdl interface{}, filtered *model.FilteredResponse) error { +func FilteredResponse(qry *pg.Query, mdl interface{}, params model.Params) (*model.FilteredResponse, error) { + filtered := new(model.FilteredResponse) + filtered.Params = params if filtered.Page == 0 { filtered.Page = 1 } @@ -55,5 +57,5 @@ func FilteredResponse(qry *pg.Query, mdl interface{}, filtered *model.FilteredRe filtered.TotalRecords = count filtered.Items = mdl - return err + return filtered, err } diff --git a/pkg/repository/subscription.go b/pkg/repository/subscription.go index ae0dfb8..cbb8382 100644 --- a/pkg/repository/subscription.go +++ b/pkg/repository/subscription.go @@ -63,11 +63,14 @@ Gets row from subscription table by id. *model.Subscription: Subscription row object from database. *model.Exception: Exception payload. */ -func (as *SubscriptionRepository) Get(ctx context.Context, am *model.Subscription, flt filter.SubscriptionFilter) (*model.Subscription, error) { +func (as *SubscriptionRepository) Get(ctx context.Context, flt filter.SubscriptionFilter) (*model.Subscription, error) { db := as.db.WithContext(ctx) tx, _ := db.Begin() defer tx.Rollback() + am := new(model.Subscription) + am.Id = flt.Id + qry := tx.Model(am) as.OnBeforeGetSubscriptionFilter(qry, &flt) err := common.GenerateEmbed(qry, flt.Embed).WherePK().Select() @@ -93,22 +96,23 @@ Gets filtered rows from subscription table. Returns: *model.Exception: Exception payload. */ -func (as *SubscriptionRepository) GetAll(ctx context.Context, am *[]model.Subscription, filtered *model.FilteredResponse, flt *filter.SubscriptionFilter) error { +func (as *SubscriptionRepository) GetAll(ctx context.Context, flt *filter.SubscriptionFilter) (*model.FilteredResponse, error) { db := as.db.WithContext(ctx) tx, _ := db.Begin() defer tx.Rollback() + am := new([]model.Subscription) query := tx.Model(am) as.OnBeforeGetSubscriptionFilter(query, flt) - err := FilteredResponse(query, am, filtered) + filtered, err := FilteredResponse(query, am, flt.Params) if err != nil { - return err + return nil, err } tx.Commit() - return nil + return filtered, nil } /* @@ -124,17 +128,18 @@ Gets filtered rows from subscription table. Returns: *model.Exception: Exception payload. */ -func (as *SubscriptionRepository) GetAllTx(tx *pg.Tx, am *[]model.Subscription, flt *filter.SubscriptionFilter) error { +func (as *SubscriptionRepository) GetAllTx(tx *pg.Tx, flt *filter.SubscriptionFilter) (*[]model.Subscription, error) { + am := new([]model.Subscription) query := tx.Model(am) as.OnBeforeGetSubscriptionFilter(query, flt) + common.GenerateEmbed(query, flt.Embed) err := query.Select() if err != nil { - return err + return nil, err } - tx.Commit() - return nil + return am, nil } /* @@ -218,7 +223,6 @@ func (as *SubscriptionRepository) SubToTrans(subModel *model.Subscription, tx *p transactionStatus := new(model.TransactionStatus) firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation) tx.Model(transactionStatus).Where("? = ?", pg.Ident("status"), "pending").Select() - //tzFirstOfNextMonth := firstOfNextMonth.In(subModel.StartDate.Location()) startDate := subModel.StartDate stopDate := firstOfNextMonth @@ -271,8 +275,8 @@ func (as *SubscriptionRepository) SubToTrans(subModel *model.Subscription, tx *p } func (as *SubscriptionRepository) OnBeforeGetSubscriptionFilter(qry *orm.Query, flt *filter.SubscriptionFilter) { - if flt.Id != "" { - qry.Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), flt.Id) + if flt.UserId != "" { + qry.Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), flt.UserId) } if flt.WalletId != "" { qry.Where("? = ?", pg.Ident("wallet_id"), flt.WalletId) diff --git a/pkg/repository/subscriptionType.go b/pkg/repository/subscriptionType.go index 3c37301..477445a 100644 --- a/pkg/repository/subscriptionType.go +++ b/pkg/repository/subscriptionType.go @@ -54,7 +54,8 @@ Gets all rows from subscription type table. *[]model.SubscriptionType: List of subscription type objects. *model.Exception: Exception payload. */ -func (as *SubscriptionTypeRepository) GetAll(ctx context.Context, flt *filter.SubscriptionTypeFilter, wm *[]model.SubscriptionType) (*[]model.SubscriptionType, error) { +func (as *SubscriptionTypeRepository) GetAll(ctx context.Context, flt *filter.SubscriptionTypeFilter) (*[]model.SubscriptionType, error) { + wm := new([]model.SubscriptionType) db := as.db.WithContext(ctx) query := db.Model(wm) diff --git a/pkg/repository/transaction.go b/pkg/repository/transaction.go index 740c37e..289fd70 100644 --- a/pkg/repository/transaction.go +++ b/pkg/repository/transaction.go @@ -37,17 +37,26 @@ Inserts *model.Transaction: Transaction object *model.Exception: Exception payload. */ -func (as *TransactionRepository) New(ctx context.Context, tm *model.Transaction) (*model.Transaction, error) { - db := as.db.WithContext(ctx) +func (as *TransactionRepository) New(ctx context.Context, tm *model.Transaction, tx *pg.Tx) (*model.Transaction, error) { + var commit = false + if tx == nil { + commit = true + db := as.db.WithContext(ctx) + tx, _ = db.Begin() - tx, _ := db.Begin() - defer tx.Rollback() + } + + if commit { + defer tx.Rollback() + } _, err := tx.Model(tm).Insert() if err != nil { return nil, err } - tx.Commit() + if commit { + tx.Commit() + } return tm, nil } @@ -63,48 +72,76 @@ Gets all rows from subscription type table. *model.Exception: Exception payload. */ // Gets filtered rows from transaction table. -func (as *TransactionRepository) GetAll(ctx context.Context, filtered *model.FilteredResponse, flt *filter.TransactionFilter) *model.Exception { +func (as *TransactionRepository) GetAll(ctx context.Context, flt *filter.TransactionFilter) (*model.FilteredResponse, *model.Exception) { db := as.db.WithContext(ctx) exceptionReturn := new(model.Exception) wm := new([]model.Transaction) - transactionStatus := new(model.TransactionStatus) tx, _ := db.Begin() defer tx.Rollback() - tsFlt := filter.NewTransactionStatusFilter(model.Params{}) - tsFlt.Status = "completed" - _, err := as.transactionStatusRepository.GetTx(tx, transactionStatus, tsFlt) + if flt.NoPending { + tsFlt := filter.NewTransactionStatusFilter(model.Params{}) + tsFlt.Status = "completed" + transactionStatus, err := as.transactionStatusRepository.GetTx(tx, tsFlt) - if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400117" - exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transactionStatus\" table: %s", err) - return exceptionReturn + if err != nil { + exceptionReturn.StatusCode = 400 + exceptionReturn.ErrorCode = "400117" + exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transactionStatus\" table: %s", err) + return nil, exceptionReturn + } + + flt.TransactionStatusId = transactionStatus.Id } - flt.TransactionStatusId = transactionStatus.Id - query := tx.Model(wm) as.OnBeforeGetTransactionFilter(query, flt) - err = FilteredResponse(query, wm, filtered) + filtered, err := FilteredResponse(query, wm, flt.Params) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400118" exceptionReturn.Message = fmt.Sprintf("Error selecting row(s) in \"transaction\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } tx.Commit() - return nil + return filtered, nil +} + +/* +GetAllTx + +Gets filtered rows from transaction table. + + Args: + context.Context: Application context + *model.Auth: Authentication object + string: Wallet id to search + *model.FilteredResponse: filter options + Returns: + *model.Exception: Exception payload. +*/ +func (as *TransactionRepository) GetAllTx(tx *pg.Tx, flt *filter.TransactionFilter) (*[]model.Transaction, error) { + am := new([]model.Transaction) + query := tx.Model(am) + as.OnBeforeGetTransactionFilter(query, flt) + + common.GenerateEmbed(query, flt.Embed) + err := query.Select() + if err != nil { + return nil, err + } + + return am, nil } /* Check -Checks subscriptions and create transacitons. +Checks subscriptions and create transactions. Args: context.Context: Application context string: Relations to embed @@ -112,32 +149,37 @@ Checks subscriptions and create transacitons. *model.Exception: Exception payload. */ // Gets filtered rows from transaction table. -func (as *TransactionRepository) Check(ctx context.Context, filtered *model.FilteredResponse, flt *filter.TransactionFilter) *model.Exception { +func (as *TransactionRepository) Check(ctx context.Context, flt *filter.TransactionFilter) (*model.FilteredResponse, *model.Exception) { db := as.db.WithContext(ctx) wm := new([]model.Transaction) - sm := new([]model.Subscription) - transactionStatus := new(model.TransactionStatus) exceptionReturn := new(model.Exception) + filtered := new(model.FilteredResponse) tx, _ := db.Begin() defer tx.Rollback() tsFlt := filter.NewTransactionStatusFilter(model.Params{}) tsFlt.Status = "pending" - _, err := as.transactionStatusRepository.GetTx(tx, transactionStatus, tsFlt) + transactionStatus, err := as.transactionStatusRepository.GetTx(tx, tsFlt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400119" exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transactionStatus\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } flt.TransactionStatusId = transactionStatus.Id smFlt := filter.NewSubscriptionFilter(model.Params{}) smFlt.Id = flt.Id smFlt.WalletId = flt.WalletId - as.subscriptionRepository.GetAllTx(tx, sm, smFlt) + sm, err := as.subscriptionRepository.GetAllTx(tx, smFlt) + if err != nil { + exceptionReturn.StatusCode = 400 + exceptionReturn.ErrorCode = "400137" + exceptionReturn.Message = fmt.Sprintf("Error selecting rows in \"subscription\" table: %s", err) + return nil, exceptionReturn + } for _, sub := range *sm { if sub.HasNew() { @@ -147,16 +189,16 @@ func (as *TransactionRepository) Check(ctx context.Context, filtered *model.Filt qry := tx.Model(wm) as.OnBeforeGetTransactionFilter(qry, flt) - err = FilteredResponse(qry, wm, filtered) + filtered, err = FilteredResponse(qry, wm, flt.Params) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400120" exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transaction\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } tx.Commit() - return nil + return filtered, nil } /* @@ -195,7 +237,7 @@ func (as *TransactionRepository) Edit(ctx context.Context, tm *model.Transaction } /* -Bulk Edit +BulkEdit Updates row in transaction table by id. @@ -239,6 +281,7 @@ Gets row from transaction table by id. func (as *TransactionRepository) Get(ctx context.Context, flt *filter.TransactionFilter) (*model.Transaction, error) { db := as.db.WithContext(ctx) wm := new(model.Transaction) + wm.Id = flt.Id tx, _ := db.Begin() defer tx.Rollback() @@ -259,10 +302,15 @@ func (as *TransactionRepository) OnBeforeGetTransactionFilter(qry *orm.Query, fl if flt.WalletId != "" { qry.Where("? = ?", pg.Ident("wallet_id"), flt.WalletId) } - if flt.Id != "" { - qry.Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), flt.Id) + if flt.UserId != "" { + qry.Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), flt.UserId) } - if flt.NoPending && flt.TransactionStatusId != "" { + if flt.TransactionStatusId != "" { qry.Where("? = ?", pg.Ident("transaction_status_id"), flt.TransactionStatusId) } } + +func (as *TransactionRepository) CreateTx(ctx context.Context) (*pg.Tx, error) { + db := as.db.WithContext(ctx) + return db.Begin() +} diff --git a/pkg/repository/transactionStatus.go b/pkg/repository/transactionStatus.go index 1fdf042..778cc4b 100644 --- a/pkg/repository/transactionStatus.go +++ b/pkg/repository/transactionStatus.go @@ -2,7 +2,6 @@ package repository import ( "context" - "fmt" "github.com/go-pg/pg/v10/orm" "wallet-api/pkg/filter" "wallet-api/pkg/model" @@ -33,22 +32,12 @@ Inserts new row to transaction status table. *model.TransactionType: Transaction Type object from database. *model.Exception: Exception payload. */ -func (as *TransactionStatusRepository) New(ctx context.Context, body *model.NewTransactionStatusBody) (*model.TransactionStatus, *model.Exception) { +func (as *TransactionStatusRepository) New(ctx context.Context, tm *model.TransactionStatus) (*model.TransactionStatus, error) { db := as.db.WithContext(ctx) - tm := new(model.TransactionStatus) - exceptionReturn := new(model.Exception) - - tm.Init() - tm.Name = body.Name - tm.Status = body.Status - _, err := db.Model(tm).Insert() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400123" - exceptionReturn.Message = fmt.Sprintf("Error inserting row in \"transactionStatus\" table: %s", err) - return nil, exceptionReturn + return nil, err } return tm, nil @@ -66,19 +55,29 @@ Gets all rows from transaction status table. *[]model.TransactionStatus: List of Transaction status objects from database. *model.Exception: Exception payload. */ -func (as *TransactionStatusRepository) GetAll(ctx context.Context, embed string) (*[]model.TransactionStatus, *model.Exception) { - db := as.db.WithContext(ctx) +func (as *TransactionStatusRepository) GetAll(ctx context.Context, flt *filter.TransactionStatusFilter, tx *pg.Tx) (*[]model.TransactionStatus, error) { + var commit = false + if tx == nil { + commit = true + db := as.db.WithContext(ctx) + tx, _ = db.Begin() + } + + if commit { + defer tx.Rollback() + } wm := new([]model.TransactionStatus) - exceptionReturn := new(model.Exception) - query := db.Model(wm) - err := common.GenerateEmbed(query, embed).Select() + query := tx.Model(wm) + as.OnBeforeGetTransactionStatusFilter(query, flt) + err := common.GenerateEmbed(query, flt.Embed).Select() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400124" - exceptionReturn.Message = fmt.Sprintf("Error selecting rows in \"transactionStatus\" table: %s", err) - return nil, exceptionReturn + return nil, err + } + + if commit { + tx.Commit() } return wm, nil @@ -98,18 +97,25 @@ Gets row from transactionStatus table by id. *model.Subscription: Subscription row object from database. *model.Exception: Exception payload. */ -func (as *TransactionStatusRepository) Get(ctx context.Context, am *model.TransactionStatus, flt filter.TransactionStatusFilter) (*model.TransactionStatus, error) { - db := as.db.WithContext(ctx) - tx, _ := db.Begin() - defer tx.Rollback() +func (as *TransactionStatusRepository) Get(ctx context.Context, flt *filter.TransactionStatusFilter, tx *pg.Tx) (*model.TransactionStatus, error) { + am := new(model.TransactionStatus) + commit := false + if tx == nil { + commit = true + db := as.db.WithContext(ctx) + tx, _ = db.Begin() + defer tx.Rollback() + } qry := tx.Model(am) - err := common.GenerateEmbed(qry, flt.Embed).WherePK().Select() + err := common.GenerateEmbed(qry, flt.Embed).Select() if err != nil { return nil, err } - tx.Commit() + if commit { + tx.Commit() + } return am, nil } @@ -128,10 +134,11 @@ Gets row from transactionStatus table by id. *model.Subscription: Subscription row object from database. *model.Exception: Exception payload. */ -func (as *TransactionStatusRepository) GetTx(tx *pg.Tx, am *model.TransactionStatus, flt *filter.TransactionStatusFilter) (*model.TransactionStatus, error) { +func (as *TransactionStatusRepository) GetTx(tx *pg.Tx, flt *filter.TransactionStatusFilter) (*model.TransactionStatus, error) { + am := new(model.TransactionStatus) qry := tx.Model(am) as.OnBeforeGetTransactionStatusFilter(qry, flt) - err := common.GenerateEmbed(qry, flt.Embed).WherePK().Select() + err := common.GenerateEmbed(qry, flt.Embed).Select() if err != nil { return nil, err } @@ -140,6 +147,9 @@ func (as *TransactionStatusRepository) GetTx(tx *pg.Tx, am *model.TransactionSta } func (as *TransactionStatusRepository) OnBeforeGetTransactionStatusFilter(qry *orm.Query, flt *filter.TransactionStatusFilter) { + if flt.Id != "" { + qry.Where("? = ?", pg.Ident("id"), flt.Id) + } if flt.Status != "" { qry.Where("? = ?", pg.Ident("status"), flt.Status) } diff --git a/pkg/repository/transactionType.go b/pkg/repository/transactionType.go index 6ed029f..a69a9ff 100644 --- a/pkg/repository/transactionType.go +++ b/pkg/repository/transactionType.go @@ -2,7 +2,7 @@ package repository import ( "context" - "fmt" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/utl/common" @@ -31,22 +31,12 @@ Inserts new row to transaction type table. *model.TransactionType: Transaction Type object from database. *model.Exception: Exception payload. */ -func (as *TransactionTypeRepository) New(ctx context.Context, body *model.NewTransactionTypeBody) (*model.TransactionType, *model.Exception) { +func (as *TransactionTypeRepository) New(ctx context.Context, tm *model.TransactionType) (*model.TransactionType, error) { db := as.db.WithContext(ctx) - tm := new(model.TransactionType) - exceptionReturn := new(model.Exception) - - tm.Init() - tm.Name = body.Name - tm.Type = body.Type - _, err := db.Model(tm).Insert() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400125" - exceptionReturn.Message = fmt.Sprintf("Error inserting row in \"transactionTypes\" table: %s", err) - return nil, exceptionReturn + return nil, err } return tm, nil @@ -64,19 +54,15 @@ Gets all rows from transaction type table. *[]model.TransactionType: List of Transaction type objects from database. *model.Exception: Exception payload. */ -func (as *TransactionTypeRepository) GetAll(ctx context.Context, embed string) (*[]model.TransactionType, *model.Exception) { +func (as *TransactionTypeRepository) GetAll(ctx context.Context, flt *filter.TransactionTypeFilter) (*[]model.TransactionType, error) { db := as.db.WithContext(ctx) wm := new([]model.TransactionType) - exceptionReturn := new(model.Exception) query := db.Model(wm) - err := common.GenerateEmbed(query, embed).Select() + err := common.GenerateEmbed(query, flt.Embed).Select() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400133" - exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transactionTypes\" table: %s", err) - return nil, exceptionReturn + return nil, err } return wm, nil diff --git a/pkg/repository/user.go b/pkg/repository/user.go index b27eb51..0fa4b97 100644 --- a/pkg/repository/user.go +++ b/pkg/repository/user.go @@ -4,6 +4,7 @@ import ( "context" "os" "time" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/utl/common" "wallet-api/pkg/utl/configs" @@ -24,6 +25,118 @@ func NewUserRepository(db *pg.DB) *UserRepository { } } +/* +Get + +Gets row from transaction table by id. + + Args: + context.Context: Application context + *model.Auth: Authentication object + string: id to search + *model.Params: url query parameters + Returns: + *model.Transaction: Transaction object from database. + *model.Exception: Exception payload. +*/ +func (us *UserRepository) Get(ctx context.Context, flt *filter.UserFilter, tx *pg.Tx) (*model.User, error) { + wm := new(model.User) + wm.Id = flt.Id + + commit := false + if tx == nil { + commit = true + db := us.db.WithContext(ctx) + tx, _ := db.Begin() + defer tx.Rollback() + } + + qry := tx.Model(wm) + err := common.GenerateEmbed(qry, flt.Embed).WherePK().Select() + if err != nil { + return nil, err + } + + if commit { + tx.Commit() + } + + return wm, nil +} + +/* +Edit + +Updates row in transaction table by id. + + Args: + context.Context: Application context + *model.TransactionEdit: Object to edit + string: id to search + Returns: + *model.Transaction: Transaction object from database. + *model.Exception: Exception payload. +*/ +func (us *UserRepository) Edit(ctx context.Context, tm *model.User, tx *pg.Tx) (*model.User, error) { + commit := false + if tx == nil { + commit = true + db := us.db.WithContext(ctx) + tx, _ := db.Begin() + defer tx.Rollback() + } + + _, err := tx.Model(tm).WherePK().UpdateNotZero() + + if err != nil { + return nil, err + } + + err = tx.Model(tm).WherePK().Select() + if err != nil { + return nil, err + } + + if commit { + tx.Commit() + } + + return tm, nil +} + +/* +Check + +Inserts new row to users table. + + Args: + context.Context: Application context + *model.User: User object to create + Returns: + *model.User: User object from database + *model.Exception +*/ +func (us *UserRepository) Check(ctx context.Context, tx *pg.Tx, checkBody *model.User) (*model.User, error) { + check := new(model.User) + + commit := false + if tx == nil { + commit = true + db := us.db.WithContext(ctx) + tx, _ := db.Begin() + defer tx.Rollback() + } + + err := tx.Model(check).Where("? = ?", pg.Ident("username"), checkBody.Username).WhereOr("? = ?", pg.Ident("email"), checkBody.Email).Select() + if err != nil { + return nil, err + } + if commit { + tx.Commit() + } + return check, nil +} + /* Create @@ -36,38 +149,31 @@ Inserts new row to users table. *model.User: User object from database *model.Exception */ -func (us *UserRepository) Create(ctx context.Context, registerBody *model.User) (*model.User, *model.Exception) { - db := us.db.WithContext(ctx) - - check := new(model.User) - exceptionReturn := new(model.Exception) - - tx, _ := db.Begin() - defer tx.Rollback() - - tx.Model(check).Where("? = ?", pg.Ident("username"), registerBody.Username).WhereOr("? = ?", pg.Ident("email"), registerBody.Email).Select() - if check.Username != "" || check.Email != "" { - exceptionReturn.Message = "User already exists" - exceptionReturn.ErrorCode = "400101" - exceptionReturn.StatusCode = 400 - return check, exceptionReturn +func (us *UserRepository) Create(ctx context.Context, tx *pg.Tx, registerBody *model.User) (*model.User, error) { + commit := false + if tx == nil { + commit = true + db := us.db.WithContext(ctx) + tx, _ := db.Begin() + defer tx.Rollback() } - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(registerBody.Password), bcrypt.DefaultCost) - common.CheckError(err) - - registerBody.Password = string(hashedPassword) - _, err = tx.Model(registerBody).Insert() + _, err := tx.Model(registerBody).Insert() if err != nil { - exceptionReturn.Message = "Error creating user" - exceptionReturn.ErrorCode = "400102" - exceptionReturn.StatusCode = 400 + return nil, err } - tx.Commit() + if commit { + tx.Commit() + } - return registerBody, exceptionReturn + return registerBody, nil +} + +func (us *UserRepository) CreateTx(ctx context.Context) (*pg.Tx, error) { + db := us.db.WithContext(ctx) + return db.Begin() } /* diff --git a/pkg/repository/wallet.go b/pkg/repository/wallet.go index ea983ee..cf22d7c 100644 --- a/pkg/repository/wallet.go +++ b/pkg/repository/wallet.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "time" + "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/utl/common" @@ -34,20 +35,11 @@ Inserts row to wallets table. *model.Wallet: Wallet object from database. *model.Exception: Exception payload. */ -func (as *WalletRepository) New(ctx context.Context, am *model.NewWalletBody) (*model.Wallet, *model.Exception) { +func (as *WalletRepository) New(ctx context.Context, walletModel *model.Wallet) (*model.Wallet, error) { db := as.db.WithContext(ctx) - - exceptionReturn := new(model.Exception) - walletModel := new(model.Wallet) - walletModel.Init() - walletModel.UserID = am.UserID - walletModel.Name = am.Name _, err := db.Model(walletModel).Insert() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400126" - exceptionReturn.Message = fmt.Sprintf("Error inserting row in \"wallets\" table: %s", err) - return nil, exceptionReturn + return nil, err } return walletModel, nil } @@ -65,23 +57,15 @@ Updates row in wallets table by id. *model.Wallet: Wallet object from database. *model.Exception: Exception payload. */ -func (as *WalletRepository) Edit(ctx context.Context, body *model.WalletEdit, id string) (*model.Wallet, *model.Exception) { +func (as *WalletRepository) Edit(ctx context.Context, tm *model.Wallet) (*model.Wallet, error) { db := as.db.WithContext(ctx) - exceptionReturn := new(model.Exception) - tm := new(model.Wallet) - tm.Id = id - tm.Name = body.Name - tx, _ := db.Begin() defer tx.Rollback() _, err := tx.Model(tm).WherePK().UpdateNotZero() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400127" - exceptionReturn.Message = fmt.Sprintf("Error updating row in \"wallets\" table: %s", err) - return nil, exceptionReturn + return nil, err } tx.Commit() @@ -102,23 +86,19 @@ Gets row in wallets table by id. *model.Wallet: Wallet object from database *model.Exception: Exception payload. */ -func (as *WalletRepository) Get(ctx context.Context, id string, params *model.Params) (*model.Wallet, *model.Exception) { +func (as *WalletRepository) Get(ctx context.Context, flt *filter.WalletFilter) (*model.Wallet, error) { db := as.db.WithContext(ctx) - exceptionReturn := new(model.Exception) wm := new(model.Wallet) - wm.Id = id + wm.Id = flt.Id tx, _ := db.Begin() defer tx.Rollback() qry := tx.Model(wm) - err := common.GenerateEmbed(qry, params.Embed).WherePK().Select() + err := common.GenerateEmbed(qry, flt.Embed).WherePK().Select() if err != nil { - exceptionReturn.StatusCode = 400 - exceptionReturn.ErrorCode = "400128" - exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"wallets\" table: %s", err) - return nil, exceptionReturn + return nil, err } tx.Commit() @@ -138,20 +118,20 @@ Gets filtered rows from wallets table. Returns: *model.Exception: Exception payload. */ -func (as *WalletRepository) GetAll(ctx context.Context, am *model.Auth, filtered *model.FilteredResponse) *model.Exception { +func (as *WalletRepository) GetAll(ctx context.Context, flt *filter.WalletFilter) (*model.FilteredResponse, *model.Exception) { exceptionReturn := new(model.Exception) db := as.db.WithContext(ctx) wm := new([]model.Wallet) - query := db.Model(wm).Where("? = ?", pg.Ident("user_id"), am.Id) - err := FilteredResponse(query, wm, filtered) + query := db.Model(wm).Where("? = ?", pg.Ident("user_id"), flt.UserId) + filtered, err := FilteredResponse(query, wm, flt.Params) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400134" exceptionReturn.Message = fmt.Sprintf("Error selecting rows in \"wallets\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } - return nil + return filtered, nil } /* @@ -169,7 +149,7 @@ Calculates previous month, current and next month totals. *model.WalletHeader: generated wallet header object *model.Exception: Exception payload. */ -func (as *WalletRepository) GetHeader(ctx context.Context, am *model.Auth, walletId string) (*model.WalletHeader, *model.Exception) { +func (as *WalletRepository) GetHeader(ctx context.Context, flt *filter.WalletHeaderFilter) (*model.WalletHeader, *model.Exception) { db := as.db.WithContext(ctx) wm := new(model.WalletHeader) @@ -189,9 +169,9 @@ func (as *WalletRepository) GetHeader(ctx context.Context, am *model.Auth, walle exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transactionStatuses\" table: %s", err) return nil, exceptionReturn } - query2 := tx.Model(subscriptions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType").Relation("SubscriptionType") - if walletId != "" { - query2.Where("? = ?", pg.Ident("wallet_id"), walletId) + query2 := tx.Model(subscriptions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), flt.UserId).Relation("TransactionType").Relation("SubscriptionType") + if flt.WalletId != "" { + query2.Where("? = ?", pg.Ident("wallet_id"), flt.WalletId) } query2.Select() if err != nil { @@ -210,9 +190,9 @@ func (as *WalletRepository) GetHeader(ctx context.Context, am *model.Auth, walle firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation) firstOfMonthAfterNext := time.Date(currentYear, currentMonth+2, 1, 0, 0, 0, 0, currentLocation) - query := tx.Model(transactions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType") - if walletId != "" { - query.Where("? = ?", pg.Ident("wallet_id"), walletId) + query := tx.Model(transactions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), flt.UserId).Relation("TransactionType") + if flt.WalletId != "" { + query.Where("? = ?", pg.Ident("wallet_id"), flt.WalletId) } query = query.Where("? = ?", pg.Ident("transaction_status_id"), transactionStatus.Id) query.Select() @@ -287,11 +267,16 @@ func (as *WalletRepository) GetHeader(ctx context.Context, am *model.Auth, walle } wm.Currency = "USD" - wm.WalletId = walletId + wm.WalletId = flt.WalletId return wm, nil } +func (as *WalletRepository) CreateTx(ctx context.Context) (*pg.Tx, error) { + db := as.db.WithContext(ctx) + return db.Begin() +} + /* addWhere diff --git a/pkg/service/api.go b/pkg/service/api.go index 4aa8d96..fd2278d 100644 --- a/pkg/service/api.go +++ b/pkg/service/api.go @@ -12,7 +12,7 @@ type ApiService struct { func NewApiService(repository *repository.ApiRepository) *ApiService { return &ApiService{ - repository, + repository: repository, } } @@ -42,6 +42,6 @@ Starts database migration. *model.MessageResponse: Message response object. *model.Exception: Exception response object. */ -func (as ApiService) PostMigrate(ctx context.Context, version string) (*model.MessageResponse, *model.Exception) { +func (as ApiService) PostMigrate(ctx context.Context, version string) []error { return as.repository.PostMigrate(ctx, version) } diff --git a/pkg/service/service.go b/pkg/service/service.go index 5639788..7eaa3cc 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -1,8 +1,9 @@ package service import ( - "go.uber.org/dig" "wallet-api/pkg/repository" + + "go.uber.org/dig" ) /* diff --git a/pkg/service/subscription.go b/pkg/service/subscription.go index adf42e3..2f59401 100644 --- a/pkg/service/subscription.go +++ b/pkg/service/subscription.go @@ -3,7 +3,6 @@ package service import ( "context" "fmt" - "math" "time" "wallet-api/pkg/filter" "wallet-api/pkg/model" @@ -16,7 +15,7 @@ type SubscriptionService struct { func NewSubscriptionService(repository *repository.SubscriptionRepository) *SubscriptionService { return &SubscriptionService{ - repository, + repository: repository, } } @@ -32,28 +31,9 @@ Inserts new row to subscription table. *model.Subscription: Created Subscription row object from database. *model.Exception: Exception payload. */ -func (as *SubscriptionService) New(ctx context.Context, body *model.NewSubscriptionBody) (*model.Subscription, *model.Exception) { - tm := new(model.Subscription) +func (as *SubscriptionService) New(ctx context.Context, tm *model.Subscription) (*model.Subscription, *model.Exception) { exceptionReturn := new(model.Exception) - amount, _ := body.Amount.Float64() - customRange, _ := body.CustomRange.Int64() - - tm.Init() - tm.WalletID = body.WalletID - tm.TransactionTypeID = body.TransactionTypeID - tm.SubscriptionTypeID = body.SubscriptionTypeID - tm.CustomRange = int(customRange) - tm.Description = body.Description - tm.StartDate = body.StartDate - tm.HasEnd = body.HasEnd - tm.EndDate = body.EndDate - tm.Amount = float32(math.Round(amount*100) / 100) - - if body.StartDate.IsZero() { - tm.StartDate = time.Now() - } - response, err := as.repository.New(ctx, tm) if err != nil { @@ -79,11 +59,9 @@ Gets row from subscription table by id. *model.Subscription: Subscription row object from database. *model.Exception: Exception payload. */ -func (as *SubscriptionService) Get(ctx context.Context, am *model.Auth, flt filter.SubscriptionFilter) (*model.Subscription, *model.Exception) { +func (as *SubscriptionService) Get(ctx context.Context, flt filter.SubscriptionFilter) (*model.Subscription, *model.Exception) { exceptionReturn := new(model.Exception) - wm := new(model.Subscription) - wm.Id = flt.Id - response, err := as.repository.Get(ctx, wm, flt) + response, err := as.repository.Get(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400129" @@ -107,19 +85,18 @@ Gets filtered rows from subscription table. Returns: *model.Exception: Exception payload. */ -func (as *SubscriptionService) GetAll(ctx context.Context, flt *filter.SubscriptionFilter, filtered *model.FilteredResponse) *model.Exception { - wm := new([]model.Subscription) +func (as *SubscriptionService) GetAll(ctx context.Context, flt *filter.SubscriptionFilter) (*model.FilteredResponse, *model.Exception) { exceptionReturn := new(model.Exception) - err := as.repository.GetAll(ctx, wm, filtered, flt) + filtered, err := as.repository.GetAll(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400110" exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"subscription\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } - return nil + return filtered, nil } /* @@ -135,17 +112,9 @@ Updates row from subscription table by id. *model.Subscription: Edited Subscription row object from database. *model.Exception: Exception payload. */ -func (as *SubscriptionService) Edit(ctx context.Context, body *model.SubscriptionEdit, id string) (*model.Subscription, *model.Exception) { - amount, _ := body.Amount.Float64() - exceptionReturn := new(model.Exception) +func (as *SubscriptionService) Edit(ctx context.Context, tm *model.Subscription) (*model.Subscription, *model.Exception) { - tm := new(model.Subscription) - tm.Id = id - tm.EndDate = body.EndDate - tm.HasEnd = body.HasEnd - tm.Description = body.Description - tm.WalletID = body.WalletID - tm.Amount = float32(math.Round(amount*100) / 100) + exceptionReturn := new(model.Exception) response, err := as.repository.Edit(ctx, tm) if err != nil { diff --git a/pkg/service/subscriptionType.go b/pkg/service/subscriptionType.go index 87c8696..e1e27d8 100644 --- a/pkg/service/subscriptionType.go +++ b/pkg/service/subscriptionType.go @@ -14,7 +14,7 @@ type SubscriptionTypeService struct { func NewSubscriptionTypeService(repository *repository.SubscriptionTypeRepository) *SubscriptionTypeService { return &SubscriptionTypeService{ - repository, + repository: repository, } } @@ -30,14 +30,9 @@ Inserts new row to subscription type table. *model.SubscriptionType: Created row from database. *model.Exception: Exception payload. */ -func (as *SubscriptionTypeService) New(ctx context.Context, body *model.NewSubscriptionTypeBody) (*model.SubscriptionType, *model.Exception) { - tm := new(model.SubscriptionType) +func (as *SubscriptionTypeService) New(ctx context.Context, tm *model.SubscriptionType) (*model.SubscriptionType, *model.Exception) { exceptionReturn := new(model.Exception) - tm.Init() - tm.Name = body.Name - tm.Type = body.Type - response, err := as.repository.New(ctx, tm) if err != nil { exceptionReturn.StatusCode = 400 @@ -61,14 +56,10 @@ Gets all rows from subscription type table. *[]model.SubscriptionType: List of subscription type objects. *model.Exception: Exception payload. */ -func (as *SubscriptionTypeService) GetAll(ctx context.Context, embed string) (*[]model.SubscriptionType, *model.Exception) { - wm := new([]model.SubscriptionType) +func (as *SubscriptionTypeService) GetAll(ctx context.Context, flt *filter.SubscriptionTypeFilter) (*[]model.SubscriptionType, *model.Exception) { exceptionReturn := new(model.Exception) - flt := filter.NewSubscriptionTypeFilter(model.Params{ - Embed: embed, - }) - response, err := as.repository.GetAll(ctx, flt, wm) + response, err := as.repository.GetAll(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400135" diff --git a/pkg/service/transaction.go b/pkg/service/transaction.go index b4f02ac..1c27d12 100644 --- a/pkg/service/transaction.go +++ b/pkg/service/transaction.go @@ -3,24 +3,23 @@ package service import ( "context" "fmt" - "math" - "time" "wallet-api/pkg/filter" "wallet-api/pkg/model" "wallet-api/pkg/repository" + "wallet-api/pkg/utl/common" ) type TransactionService struct { - repository *repository.TransactionRepository - subscriptionRepository *repository.SubscriptionRepository - transactionStatusService *TransactionStatusService + repository *repository.TransactionRepository + subscriptionRepository *repository.SubscriptionRepository + transactionStatusRepository *repository.TransactionStatusRepository } -func NewTransactionService(repository *repository.TransactionRepository, sr *repository.SubscriptionRepository, tss *TransactionStatusService) *TransactionService { +func NewTransactionService(repository *repository.TransactionRepository, sr *repository.SubscriptionRepository, tsr *repository.TransactionStatusRepository) *TransactionService { return &TransactionService{ - repository: repository, - subscriptionRepository: sr, - transactionStatusService: tss, + repository: repository, + subscriptionRepository: sr, + transactionStatusRepository: tsr, } } @@ -36,39 +35,41 @@ Inserts *model.Transaction: Transaction object *model.Exception: Exception payload. */ -func (as *TransactionService) New(ctx context.Context, body *model.NewTransactionBody) (*model.Transaction, *model.Exception) { +func (as *TransactionService) New(ctx context.Context, tm *model.Transaction) (*model.Transaction, *model.Exception) { exceptionReturn := new(model.Exception) - tm := new(model.Transaction) - tsFlt := filter.NewTransactionStatusFilter(model.Params{}) - tsFlt.Status = "completed" - transactionStatus, exceptionReturn := as.transactionStatusService.Get(ctx, tsFlt) - - if exceptionReturn != nil { + tx, err := as.repository.CreateTx(ctx) + defer tx.Rollback() + if err != nil { + exceptionReturn.StatusCode = 400 + exceptionReturn.ErrorCode = "400136" + exceptionReturn.Message = fmt.Sprintf("Error beginning transaction: %s", err) return nil, exceptionReturn } - amount, _ := body.Amount.Float64() - - tm.Init() - tm.WalletID = body.WalletID - tm.TransactionTypeID = body.TransactionTypeID - tm.Description = body.Description - tm.TransactionDate = body.TransactionDate - tm.Amount = float32(math.Round(amount*100) / 100) - tm.TransactionStatusID = transactionStatus.Id - - if body.TransactionDate.IsZero() { - tm.TransactionDate = time.Now() + tsFlt := filter.NewTransactionStatusFilter(model.Params{}) + tsFlt.Status = "completed" + transactionStatuses, err := as.transactionStatusRepository.GetAll(ctx, tsFlt, tx) + if err != nil { + exceptionReturn.StatusCode = 400 + exceptionReturn.ErrorCode = "400138" + exceptionReturn.Message = fmt.Sprintf("Error fetching transactionStatus: %s", err) + return nil, exceptionReturn } - response, err := as.repository.New(ctx, tm) + var transactionStatus = common.Find[model.TransactionStatus](transactionStatuses, func(status *model.TransactionStatus) bool { + return status.Status == "completed" + }) + tm.TransactionStatusID = transactionStatus.Id + + response, err := as.repository.New(ctx, tm, tx) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400116" exceptionReturn.Message = fmt.Sprintf("Error inserting row in \"transaction\" table: %s", err) return nil, exceptionReturn } + tx.Commit() return response, nil } @@ -84,23 +85,23 @@ Gets all rows from subscription type table. *model.Exception: Exception payload. */ // Gets filtered rows from transaction table. -func (as *TransactionService) GetAll(ctx context.Context, filtered *model.FilteredResponse, flt *filter.TransactionFilter) *model.Exception { +func (as *TransactionService) GetAll(ctx context.Context, flt *filter.TransactionFilter) (*model.FilteredResponse, *model.Exception) { exceptionReturn := new(model.Exception) - err := as.repository.GetAll(ctx, filtered, flt) + filtered, err := as.repository.GetAll(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400118" exceptionReturn.Message = fmt.Sprintf("Error selecting row(s) in \"transaction\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } - return nil + return filtered, nil } /* Check -Checks subscriptions and create transacitons. +Checks subscriptions and create transactions. Args: context.Context: Application context string: Relations to embed @@ -108,18 +109,17 @@ Checks subscriptions and create transacitons. *model.Exception: Exception payload. */ // Gets filtered rows from transaction table. -func (as *TransactionService) Check(ctx context.Context, flt *filter.TransactionFilter) *model.Exception { +func (as *TransactionService) Check(ctx context.Context, flt *filter.TransactionFilter) (*model.FilteredResponse, *model.Exception) { exceptionReturn := new(model.Exception) - filtered := new(model.FilteredResponse) - err := as.repository.Check(ctx, filtered, flt) + filtered, err := as.repository.Check(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400120" exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transaction\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } - return nil + return filtered, nil } /* @@ -135,20 +135,9 @@ Updates row in transaction table by id. *model.Transaction: Transaction object from database. *model.Exception: Exception payload. */ -func (as *TransactionService) Edit(ctx context.Context, body *model.TransactionEdit, id string) (*model.Transaction, *model.Exception) { - amount, _ := body.Amount.Float64() - +func (as *TransactionService) Edit(ctx context.Context, tm *model.Transaction) (*model.Transaction, *model.Exception) { exceptionReturn := new(model.Exception) - tm := new(model.Transaction) - tm.Id = id - tm.Description = body.Description - tm.WalletID = body.WalletID - tm.TransactionTypeID = body.TransactionTypeID - tm.TransactionDate = body.TransactionDate - tm.TransactionStatusID = body.TransactionStatusID - tm.Amount = float32(math.Round(amount*100) / 100) - response, err := as.repository.Edit(ctx, tm) if err != nil { @@ -162,7 +151,7 @@ func (as *TransactionService) Edit(ctx context.Context, body *model.TransactionE } /* -Bulk Edit +BulkEdit Updates row in transaction table by id. @@ -174,25 +163,9 @@ Updates row in transaction table by id. *model.Transaction: Transaction object from database. *model.Exception: Exception payload. */ -func (as *TransactionService) BulkEdit(ctx context.Context, body *[]model.TransactionEdit) (*[]model.Transaction, *model.Exception) { - transactions := new([]model.Transaction) +func (as *TransactionService) BulkEdit(ctx context.Context, transactions *[]model.Transaction) (*[]model.Transaction, *model.Exception) { exceptionReturn := new(model.Exception) - for _, transaction := range *body { - - amount, _ := transaction.Amount.Float64() - - tm := new(model.Transaction) - tm.Id = transaction.Id - tm.Description = transaction.Description - tm.WalletID = transaction.WalletID - tm.TransactionTypeID = transaction.TransactionTypeID - tm.TransactionDate = transaction.TransactionDate - tm.Amount = float32(math.Round(amount*100) / 100) - - *transactions = append(*transactions, *tm) - } - response, err := as.repository.BulkEdit(ctx, transactions) if err != nil { exceptionReturn.StatusCode = 400 diff --git a/pkg/service/transactionStatus.go b/pkg/service/transactionStatus.go index f6fe470..e0606c8 100644 --- a/pkg/service/transactionStatus.go +++ b/pkg/service/transactionStatus.go @@ -5,18 +5,16 @@ import ( "fmt" "wallet-api/pkg/filter" "wallet-api/pkg/model" - "wallet-api/pkg/utl/common" - - "github.com/go-pg/pg/v10" + "wallet-api/pkg/repository" ) type TransactionStatusService struct { - db *pg.DB + repository *repository.TransactionStatusRepository } -func NewTransactionStatusService(db *pg.DB) *TransactionStatusService { +func NewTransactionStatusService(repository *repository.TransactionStatusRepository) *TransactionStatusService { return &TransactionStatusService{ - db: db, + repository: repository, } } @@ -32,17 +30,10 @@ Inserts new row to transaction status table. *model.TransactionType: Transaction Type object from database. *model.Exception: Exception payload. */ -func (as *TransactionStatusService) New(ctx context.Context, body *model.NewTransactionStatusBody) (*model.TransactionStatus, *model.Exception) { - db := as.db.WithContext(ctx) - - tm := new(model.TransactionStatus) +func (as *TransactionStatusService) New(ctx context.Context, tm *model.TransactionStatus) (*model.TransactionStatus, *model.Exception) { exceptionReturn := new(model.Exception) - tm.Init() - tm.Name = body.Name - tm.Status = body.Status - - _, err := db.Model(tm).Insert() + response, err := as.repository.New(ctx, tm) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400123" @@ -50,7 +41,7 @@ func (as *TransactionStatusService) New(ctx context.Context, body *model.NewTran return nil, exceptionReturn } - return tm, nil + return response, nil } /* @@ -65,14 +56,10 @@ Gets all rows from transaction status table. *[]model.TransactionStatus: List of Transaction status objects from database. *model.Exception: Exception payload. */ -func (as *TransactionStatusService) GetAll(ctx context.Context, embed string) (*[]model.TransactionStatus, *model.Exception) { - db := as.db.WithContext(ctx) - - wm := new([]model.TransactionStatus) +func (as *TransactionStatusService) GetAll(ctx context.Context, flt *filter.TransactionStatusFilter) (*[]model.TransactionStatus, *model.Exception) { exceptionReturn := new(model.Exception) - query := db.Model(wm) - err := common.GenerateEmbed(query, embed).Select() + response, err := as.repository.GetAll(ctx, flt, nil) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400124" @@ -80,7 +67,7 @@ func (as *TransactionStatusService) GetAll(ctx context.Context, embed string) (* return nil, exceptionReturn } - return wm, nil + return response, nil } func (as *TransactionStatusService) Get(ctx context.Context, flt *filter.TransactionStatusFilter) (*model.TransactionStatus, *model.Exception) { @@ -92,7 +79,7 @@ func (as *TransactionStatusService) Get(ctx context.Context, flt *filter.Transac if flt.Status != "" { transactionStatus.Status = flt.Status } - response, err := as.repository.Get(ctx, wm, flt) + response, err := as.repository.Get(ctx, flt, nil) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400129" diff --git a/pkg/service/transactionType.go b/pkg/service/transactionType.go index 3b6007b..447df56 100644 --- a/pkg/service/transactionType.go +++ b/pkg/service/transactionType.go @@ -3,19 +3,18 @@ package service import ( "context" "fmt" + "wallet-api/pkg/filter" "wallet-api/pkg/model" - "wallet-api/pkg/utl/common" - - "github.com/go-pg/pg/v10" + "wallet-api/pkg/repository" ) type TransactionTypeService struct { - db *pg.DB + repository *repository.TransactionTypeRepository } -func NewTransactionTypeService(db *pg.DB) *TransactionTypeService { +func NewTransactionTypeService(repository *repository.TransactionTypeRepository) *TransactionTypeService { return &TransactionTypeService{ - db: db, + repository: repository, } } @@ -31,17 +30,10 @@ Inserts new row to transaction type table. *model.TransactionType: Transaction Type object from database. *model.Exception: Exception payload. */ -func (as *TransactionTypeService) New(ctx context.Context, body *model.NewTransactionTypeBody) (*model.TransactionType, *model.Exception) { - db := as.db.WithContext(ctx) - - tm := new(model.TransactionType) +func (as *TransactionTypeService) New(ctx context.Context, tm *model.TransactionType) (*model.TransactionType, *model.Exception) { exceptionReturn := new(model.Exception) - tm.Init() - tm.Name = body.Name - tm.Type = body.Type - - _, err := db.Model(tm).Insert() + response, err := as.repository.New(ctx, tm) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400125" @@ -49,7 +41,7 @@ func (as *TransactionTypeService) New(ctx context.Context, body *model.NewTransa return nil, exceptionReturn } - return tm, nil + return response, nil } /* @@ -64,14 +56,10 @@ Gets all rows from transaction type table. *[]model.TransactionType: List of Transaction type objects from database. *model.Exception: Exception payload. */ -func (as *TransactionTypeService) GetAll(ctx context.Context, embed string) (*[]model.TransactionType, *model.Exception) { - db := as.db.WithContext(ctx) - - wm := new([]model.TransactionType) +func (as *TransactionTypeService) GetAll(ctx context.Context, flt *filter.TransactionTypeFilter) (*[]model.TransactionType, *model.Exception) { exceptionReturn := new(model.Exception) - query := db.Model(wm) - err := common.GenerateEmbed(query, embed).Select() + response, err := as.repository.GetAll(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400133" @@ -79,5 +67,5 @@ func (as *TransactionTypeService) GetAll(ctx context.Context, embed string) (*[] return nil, exceptionReturn } - return wm, nil + return response, nil } diff --git a/pkg/service/user.go b/pkg/service/user.go index 73a1283..e448451 100644 --- a/pkg/service/user.go +++ b/pkg/service/user.go @@ -4,23 +4,23 @@ import ( "context" "os" "time" + "wallet-api/pkg/filter" "wallet-api/pkg/model" + "wallet-api/pkg/repository" "wallet-api/pkg/utl/common" "wallet-api/pkg/utl/configs" jwt "github.com/dgrijalva/jwt-go" "golang.org/x/crypto/bcrypt" - - "github.com/go-pg/pg/v10" ) type UserService struct { - db *pg.DB + repository *repository.UserRepository } -func NewUserService(db *pg.DB) *UserService { +func NewUserService(repository *repository.UserRepository) *UserService { return &UserService{ - db: db, + repository: repository, } } @@ -37,37 +37,41 @@ Inserts new row to users table. *model.Exception */ func (us *UserService) Create(ctx context.Context, registerBody *model.User) (*model.User, *model.Exception) { - db := us.db.WithContext(ctx) - - check := new(model.User) exceptionReturn := new(model.Exception) - tx, _ := db.Begin() + tx, _ := us.repository.CreateTx(ctx) defer tx.Rollback() - tx.Model(check).Where("? = ?", pg.Ident("username"), registerBody.Username).WhereOr("? = ?", pg.Ident("email"), registerBody.Email).Select() + check, err := us.repository.Check(ctx, tx, registerBody) + if err != nil { + exceptionReturn.Message = "Error checking user" + exceptionReturn.ErrorCode = "400139" + exceptionReturn.StatusCode = 400 + return nil, exceptionReturn + } + if check.Username != "" || check.Email != "" { exceptionReturn.Message = "User already exists" exceptionReturn.ErrorCode = "400101" exceptionReturn.StatusCode = 400 - return check, exceptionReturn + return nil, exceptionReturn } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(registerBody.Password), bcrypt.DefaultCost) common.CheckError(err) registerBody.Password = string(hashedPassword) - _, err = tx.Model(registerBody).Insert() - + us.repository.Create(ctx, tx, registerBody) if err != nil { exceptionReturn.Message = "Error creating user" exceptionReturn.ErrorCode = "400102" exceptionReturn.StatusCode = 400 + return nil, exceptionReturn } tx.Commit() - return registerBody, exceptionReturn + return registerBody, nil } /* @@ -82,17 +86,24 @@ Gets row from users table by email and valid password. *model.Token: new session token *model.Exception */ -func (us *UserService) Login(ctx context.Context, loginBody *model.Login) (*model.Token, *model.Exception) { - db := us.db.WithContext(ctx) - - check := new(model.User) +func (us *UserService) Login(ctx context.Context, body *model.Login) (*model.Token, *model.Exception) { exceptionReturn := new(model.Exception) tokenPayload := new(model.Token) + loginBody := new(model.User) - tx, _ := db.Begin() + loginBody.Email = body.Email + loginBody.Username = body.Email + + tx, _ := us.repository.CreateTx(ctx) defer tx.Rollback() - tx.Model(check).Where("? = ?", pg.Ident("email"), loginBody.Email).Select() + check, err := us.repository.Check(ctx, tx, loginBody) + if err != nil { + exceptionReturn.Message = "Error checking user" + exceptionReturn.ErrorCode = "400139" + exceptionReturn.StatusCode = 400 + return nil, exceptionReturn + } if check.Email == "" { exceptionReturn.Message = "Email not found" @@ -108,20 +119,18 @@ func (us *UserService) Login(ctx context.Context, loginBody *model.Login) (*mode return tokenPayload, exceptionReturn } - if bcrypt.CompareHashAndPassword([]byte(check.Password), []byte(loginBody.Password)) != nil { + if bcrypt.CompareHashAndPassword([]byte(check.Password), []byte(body.Password)) != nil { exceptionReturn.Message = "Incorrect password" exceptionReturn.ErrorCode = "400104" exceptionReturn.StatusCode = 400 return tokenPayload, exceptionReturn } - token, err := CreateToken(check, loginBody.RememberMe) + token, err := CreateToken(check, body.RememberMe) common.CheckError(err) tokenPayload.Token = token - tx.Commit() - return tokenPayload, exceptionReturn } @@ -139,39 +148,35 @@ IsActive column is set to false *model.MessageResponse *model.Exception */ -func (us *UserService) Deactivate(ctx context.Context, auth *model.Auth) (*model.MessageResponse, *model.Exception) { - db := us.db.WithContext(ctx) - +func (us *UserService) Deactivate(ctx context.Context, flt *filter.UserFilter) (*model.MessageResponse, *model.Exception) { mm := new(model.MessageResponse) me := new(model.Exception) - um := new(model.User) - tx, _ := db.Begin() + tx, _ := us.repository.CreateTx(ctx) defer tx.Rollback() - err := tx.Model(um).Where("? = ?", pg.Ident("id"), auth.Id).Select() - + um, err := us.repository.Get(ctx, flt, tx) if err != nil { me.ErrorCode = "404101" me.Message = "User not found" me.StatusCode = 404 - return mm, me + return nil, me } - um.IsActive = false - _, err = tx.Model(um).Where("? = ?", pg.Ident("id"), auth.Id).Update() + um.IsActive = false + _, err = us.repository.Edit(ctx, um, tx) if err != nil { me.ErrorCode = "400105" me.Message = "Could not deactivate user" me.StatusCode = 400 - return mm, me + return nil, me } mm.Message = "User successfully deactivated." tx.Commit() - return mm, me + return mm, nil } /* diff --git a/pkg/service/wallet.go b/pkg/service/wallet.go index a87bb51..242d3ac 100644 --- a/pkg/service/wallet.go +++ b/pkg/service/wallet.go @@ -4,21 +4,24 @@ import ( "context" "fmt" "time" + "wallet-api/pkg/filter" "wallet-api/pkg/model" - "wallet-api/pkg/utl/common" - - "github.com/go-pg/pg/v10" + "wallet-api/pkg/repository" ) type WalletService struct { - db *pg.DB - subscriptionService *SubscriptionService + repository *repository.WalletRepository + subscriptionRepository *repository.SubscriptionRepository + transactionStatusRepository *repository.TransactionStatusRepository + transactionRepository *repository.TransactionRepository } -func NewWalletService(db *pg.DB, ss *SubscriptionService) *WalletService { +func NewWalletService(repository *repository.WalletRepository, subscriptionRepository *repository.SubscriptionRepository, transactionStatusRepository *repository.TransactionStatusRepository, transactionRepository *repository.TransactionRepository) *WalletService { return &WalletService{ - db: db, - subscriptionService: ss, + repository: repository, + subscriptionRepository: subscriptionRepository, + transactionStatusRepository: transactionStatusRepository, + transactionRepository: transactionRepository, } } @@ -35,21 +38,19 @@ Inserts row to wallets table. *model.Exception: Exception payload. */ func (as *WalletService) New(ctx context.Context, am *model.NewWalletBody) (*model.Wallet, *model.Exception) { - db := as.db.WithContext(ctx) - exceptionReturn := new(model.Exception) walletModel := new(model.Wallet) walletModel.Init() walletModel.UserID = am.UserID walletModel.Name = am.Name - _, err := db.Model(walletModel).Insert() + response, err := as.repository.New(ctx, walletModel) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400126" exceptionReturn.Message = fmt.Sprintf("Error inserting row in \"wallets\" table: %s", err) return nil, exceptionReturn } - return walletModel, nil + return response, nil } /* @@ -65,28 +66,17 @@ Updates row in wallets table by id. *model.Wallet: Wallet object from database. *model.Exception: Exception payload. */ -func (as *WalletService) Edit(ctx context.Context, body *model.WalletEdit, id string) (*model.Wallet, *model.Exception) { - db := as.db.WithContext(ctx) - +func (as *WalletService) Edit(ctx context.Context, tm *model.Wallet) (*model.Wallet, *model.Exception) { exceptionReturn := new(model.Exception) - tm := new(model.Wallet) - tm.Id = id - tm.Name = body.Name - tx, _ := db.Begin() - defer tx.Rollback() - - _, err := tx.Model(tm).WherePK().UpdateNotZero() + response, err := as.repository.Edit(ctx, tm) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400127" exceptionReturn.Message = fmt.Sprintf("Error updating row in \"wallets\" table: %s", err) return nil, exceptionReturn } - - tx.Commit() - - return tm, nil + return response, nil } /* @@ -102,18 +92,10 @@ Gets row in wallets table by id. *model.Wallet: Wallet object from database *model.Exception: Exception payload. */ -func (as *WalletService) Get(ctx context.Context, id string, params *model.Params) (*model.Wallet, *model.Exception) { - db := as.db.WithContext(ctx) +func (as *WalletService) Get(ctx context.Context, flt *filter.WalletFilter) (*model.Wallet, *model.Exception) { exceptionReturn := new(model.Exception) - wm := new(model.Wallet) - wm.Id = id - - tx, _ := db.Begin() - defer tx.Rollback() - - qry := tx.Model(wm) - err := common.GenerateEmbed(qry, params.Embed).WherePK().Select() + response, err := as.repository.Get(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400128" @@ -121,9 +103,7 @@ func (as *WalletService) Get(ctx context.Context, id string, params *model.Param return nil, exceptionReturn } - tx.Commit() - - return wm, nil + return response, nil } /* @@ -138,20 +118,17 @@ Gets filtered rows from wallets table. Returns: *model.Exception: Exception payload. */ -func (as *WalletService) GetAll(ctx context.Context, am *model.Auth, filtered *model.FilteredResponse) *model.Exception { +func (as *WalletService) GetAll(ctx context.Context, flt *filter.WalletFilter) (*model.FilteredResponse, *model.Exception) { exceptionReturn := new(model.Exception) - db := as.db.WithContext(ctx) - wm := new([]model.Wallet) - query := db.Model(wm).Where("? = ?", pg.Ident("user_id"), am.Id) - err := FilteredResponse(query, wm, filtered) + response, err := as.repository.GetAll(ctx, flt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400134" exceptionReturn.Message = fmt.Sprintf("Error selecting rows in \"wallets\" table: %s", err) - return exceptionReturn + return nil, exceptionReturn } - return nil + return response, nil } /* @@ -169,31 +146,30 @@ Calculates previous month, current and next month totals. *model.WalletHeader: generated wallet header object *model.Exception: Exception payload. */ -func (as *WalletService) GetHeader(ctx context.Context, am *model.Auth, walletId string) (*model.WalletHeader, *model.Exception) { - db := as.db.WithContext(ctx) - +func (as *WalletService) GetHeader(ctx context.Context, flt *filter.WalletHeaderFilter) (*model.WalletHeader, *model.Exception) { wm := new(model.WalletHeader) wallets := new([]model.WalletTransactions) transactions := new([]model.Transaction) subscriptions := new([]model.Subscription) - transactionStatus := new(model.TransactionStatus) exceptionReturn := new(model.Exception) - tx, _ := db.Begin() + tx, _ := as.repository.CreateTx(ctx) defer tx.Rollback() - err := tx.Model(transactionStatus).Where("? = ?", pg.Ident("status"), "completed").Select() + trStFlt := filter.NewTransactionStatusFilter(model.Params{}) + trStFlt.Status = "completed" + transactionStatuses, err := as.transactionStatusRepository.GetAll(ctx, trStFlt, tx) + transactionStatus := (*transactionStatuses)[0] if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400130" exceptionReturn.Message = fmt.Sprintf("Error selecting row in \"transactionStatuses\" table: %s", err) return nil, exceptionReturn } - query2 := tx.Model(subscriptions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType").Relation("SubscriptionType") - if walletId != "" { - query2.Where("? = ?", pg.Ident("wallet_id"), walletId) - } - query2.Select() + + subFlt := filter.NewSubscriptionFilter(model.Params{Embed: "TransactionType,SubscriptionType"}) + subFlt.WalletId = flt.WalletId + subscriptions, err = as.subscriptionRepository.GetAllTx(tx, subFlt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400131" @@ -210,12 +186,10 @@ func (as *WalletService) GetHeader(ctx context.Context, am *model.Auth, walletId firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation) firstOfMonthAfterNext := time.Date(currentYear, currentMonth+2, 1, 0, 0, 0, 0, currentLocation) - query := tx.Model(transactions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType") - if walletId != "" { - query.Where("? = ?", pg.Ident("wallet_id"), walletId) - } - query = query.Where("? = ?", pg.Ident("transaction_status_id"), transactionStatus.Id) - query.Select() + trFlt := filter.NewTransactionFilter(model.Params{Embed: "TransactionType,Wallet"}) + trFlt.WalletId = flt.WalletId + trFlt.TransactionStatusId = transactionStatus.Id + transactions, err = as.transactionRepository.GetAllTx(tx, trFlt) if err != nil { exceptionReturn.StatusCode = 400 exceptionReturn.ErrorCode = "400132" @@ -287,7 +261,7 @@ func (as *WalletService) GetHeader(ctx context.Context, am *model.Auth, walletId } wm.Currency = "USD" - wm.WalletId = walletId + wm.WalletId = flt.WalletId return wm, nil } diff --git a/pkg/utl/common/common.go b/pkg/utl/common/common.go index eee7cad..f7a0b0c 100644 --- a/pkg/utl/common/common.go +++ b/pkg/utl/common/common.go @@ -52,3 +52,12 @@ func GetIP() string { } return "" } + +func Find[T any](lst *[]T, callback func(item *T) bool) *T { + for _, item := range *lst { + if callback(&item) { + return &item + } + } + return nil +}