Merge branch 'develop'

This commit is contained in:
Fran Jurmanović
2021-12-12 19:19:56 +01:00
41 changed files with 1079 additions and 107 deletions

View File

@@ -5,6 +5,14 @@ import (
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
) )
/*
Init
Initializes Web API Routes.
Args:
*gin.Engine: Gin Engine.
*pg.DB: Postgres Database Client.
*/
func Init(s *gin.Engine, db *pg.DB) { func Init(s *gin.Engine, db *pg.DB) {
Routes(s, db) Routes(s, db)
} }

View File

@@ -10,6 +10,14 @@ import (
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
) )
/*
Routes
Initializes web api controllers and its corresponding routes.
Args:
*gin.Engine: Gin Engine
*pg.DB: Postgres database client
*/
func Routes(s *gin.Engine, db *pg.DB) { func Routes(s *gin.Engine, db *pg.DB) {
ver := s.Group(configs.Prefix) ver := s.Group(configs.Prefix)
@@ -21,6 +29,7 @@ func Routes(s *gin.Engine, db *pg.DB) {
transactionType := ver.Group("transaction-type", middleware.Auth) transactionType := ver.Group("transaction-type", middleware.Auth)
subscription := ver.Group("subscription", middleware.Auth) subscription := ver.Group("subscription", middleware.Auth)
subscriptionType := ver.Group("subscription-type", middleware.Auth) subscriptionType := ver.Group("subscription-type", middleware.Auth)
transactionStatus := ver.Group("transaction-status", middleware.Auth)
s.NoRoute(func(c *gin.Context) { s.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{"code": "PAGE_NOT_FOUND", "message": "Page not found"}) c.JSON(404, gin.H{"code": "PAGE_NOT_FOUND", "message": "Page not found"})
@@ -34,6 +43,7 @@ func Routes(s *gin.Engine, db *pg.DB) {
transactionTypeService := services.TransactionTypeService{Db: db} transactionTypeService := services.TransactionTypeService{Db: db}
subscriptionService := services.SubscriptionService{Db: db} subscriptionService := services.SubscriptionService{Db: db}
subscriptionTypeService := services.SubscriptionTypeService{Db: db} subscriptionTypeService := services.SubscriptionTypeService{Db: db}
transactionStatusService := services.TransactionStatusService{Db: db}
walletService.Ss = &subscriptionService walletService.Ss = &subscriptionService
transactionService.Ss = &subscriptionService transactionService.Ss = &subscriptionService
@@ -46,4 +56,5 @@ func Routes(s *gin.Engine, db *pg.DB) {
controllers.NewTransactionTypeController(&transactionTypeService, transactionType) controllers.NewTransactionTypeController(&transactionTypeService, transactionType)
controllers.NewSubscriptionController(&subscriptionService, subscription) controllers.NewSubscriptionController(&subscriptionService, subscription)
controllers.NewSubscriptionTypeController(&subscriptionTypeService, subscriptionType) controllers.NewSubscriptionTypeController(&subscriptionTypeService, subscriptionType)
controllers.NewTransactionStatusController(&transactionStatusService, transactionStatus)
} }

View File

@@ -11,7 +11,16 @@ type ApiController struct {
ApiService *services.ApiService ApiService *services.ApiService
} }
// Initializes ApiController. /*
NewApiController
Initializes ApiController.
Args:
*services.ApiService: API service
*gin.RouterGroup: Gin Router Group
Returns:
*ApiController: Controller for "api" interactions
*/
func NewApiController(as *services.ApiService, s *gin.RouterGroup) *ApiController { func NewApiController(as *services.ApiService, s *gin.RouterGroup) *ApiController {
ac := new(ApiController) ac := new(ApiController)
ac.ApiService = as ac.ApiService = as
@@ -22,15 +31,25 @@ func NewApiController(as *services.ApiService, s *gin.RouterGroup) *ApiControlle
return ac return ac
} }
/*
getFirst
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /api). // ROUTE (GET /api).
func (ac *ApiController) getFirst(c *gin.Context) { func (ac *ApiController) getFirst(c *gin.Context) {
apiModel := ac.ApiService.GetFirst(c) apiModel := ac.ApiService.GetFirst(c)
c.JSON(200, apiModel) c.JSON(200, apiModel)
} }
/*
postMigrate
Requires "SECRET_CODE", "VERSION" (optional) from body.
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /api/migrate). // ROUTE (POST /api/migrate).
//
// Requires "SECRET_CODE", "VERSION" (optional) from body.
func (ac *ApiController) postMigrate(c *gin.Context) { func (ac *ApiController) postMigrate(c *gin.Context) {
migrateModel := c.MustGet("migrate") migrateModel := c.MustGet("migrate")
version := migrateModel.(middleware.SecretCodeModel).Version version := migrateModel.(middleware.SecretCodeModel).Version

View File

@@ -13,7 +13,16 @@ type AuthController struct {
UsersService *services.UsersService UsersService *services.UsersService
} }
// Initializes AuthController. /*
NewAuthController
Initializes AuthController.
Args:
*services.UsersService: Users service
*gin.RouterGroup: Gin Router Group
Returns:
*AuthController: Controller for "auth" interactions
*/
func NewAuthController(rs *services.UsersService, s *gin.RouterGroup) *AuthController { func NewAuthController(rs *services.UsersService, s *gin.RouterGroup) *AuthController {
rc := new(AuthController) rc := new(AuthController)
rc.UsersService = rs rc.UsersService = rs
@@ -26,6 +35,11 @@ func NewAuthController(rs *services.UsersService, s *gin.RouterGroup) *AuthContr
return rc return rc
} }
/*
PostLogin
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /auth/login). // ROUTE (POST /auth/login).
func (rc *AuthController) PostLogin(c *gin.Context) { func (rc *AuthController) PostLogin(c *gin.Context) {
body := new(models.Login) body := new(models.Login)
@@ -42,6 +56,11 @@ func (rc *AuthController) PostLogin(c *gin.Context) {
} }
} }
/*
PostRegister
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /auth/register). // ROUTE (POST /auth/register).
func (rc *AuthController) PostRegister(c *gin.Context) { func (rc *AuthController) PostRegister(c *gin.Context) {
body := new(models.User) body := new(models.User)
@@ -60,6 +79,11 @@ func (rc *AuthController) PostRegister(c *gin.Context) {
} }
} }
/*
Delete
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (DELETE /auth/deactivate). // ROUTE (DELETE /auth/deactivate).
func (rc *AuthController) Delete(c *gin.Context) { func (rc *AuthController) Delete(c *gin.Context) {
auth := new(models.Auth) auth := new(models.Auth)
@@ -75,6 +99,11 @@ func (rc *AuthController) Delete(c *gin.Context) {
} }
} }
/*
CheckToken
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /auth/check-token). // ROUTE (GET /auth/check-token).
func (rc *AuthController) CheckToken(c *gin.Context) { func (rc *AuthController) CheckToken(c *gin.Context) {
token, _ := c.GetQuery("token") token, _ := c.GetQuery("token")

View File

@@ -10,7 +10,15 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// Gets query parameters and populates FilteredResponse model. /*
FilteredResponse
Gets query parameters and populates FilteredResponse model.
Args:
*gin.Context: Gin Application Context
Returns:
*models.FilteredResponse: Filtered response
*/
func FilteredResponse(c *gin.Context) *models.FilteredResponse { func FilteredResponse(c *gin.Context) *models.FilteredResponse {
filtered := new(models.FilteredResponse) filtered := new(models.FilteredResponse)
page, _ := c.GetQuery("page") page, _ := c.GetQuery("page")

View File

@@ -12,7 +12,16 @@ type SubscriptionTypeController struct {
SubscriptionTypeService *services.SubscriptionTypeService SubscriptionTypeService *services.SubscriptionTypeService
} }
// Initializes SubscriptionTypeController. /*
NewSubscriptionTypeController
Initializes SubscriptionTypeController.
Args:
*services.SubscriptionTypeService: Subscription type service
*gin.RouterGroup: Gin Router Group
Returns:
*SubscriptionTypeController: Controller for "subscription-types" route interactions
*/
func NewSubscriptionTypeController(as *services.SubscriptionTypeService, s *gin.RouterGroup) *SubscriptionTypeController { func NewSubscriptionTypeController(as *services.SubscriptionTypeService, s *gin.RouterGroup) *SubscriptionTypeController {
wc := new(SubscriptionTypeController) wc := new(SubscriptionTypeController)
wc.SubscriptionTypeService = as wc.SubscriptionTypeService = as
@@ -23,6 +32,11 @@ func NewSubscriptionTypeController(as *services.SubscriptionTypeService, s *gin.
return wc return wc
} }
/*
New
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /subscription-types) // ROUTE (POST /subscription-types)
func (wc *SubscriptionTypeController) New(c *gin.Context) { func (wc *SubscriptionTypeController) New(c *gin.Context) {
body := new(models.NewSubscriptionTypeBody) body := new(models.NewSubscriptionTypeBody)
@@ -35,6 +49,11 @@ func (wc *SubscriptionTypeController) New(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
GetAll
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /subscription-types) // ROUTE (GET /subscription-types)
func (wc *SubscriptionTypeController) GetAll(c *gin.Context) { func (wc *SubscriptionTypeController) GetAll(c *gin.Context) {
embed, _ := c.GetQuery("embed") embed, _ := c.GetQuery("embed")

View File

@@ -12,7 +12,16 @@ type SubscriptionController struct {
SubscriptionService *services.SubscriptionService SubscriptionService *services.SubscriptionService
} }
// Initializes SubscriptionController. /*
NewSubscriptionController
Initializes SubscriptionController.
Args:
*services.SubscriptionService: Subscription service
*gin.RouterGroup: Gin Router Group
Returns:
*SubscriptionController: Controller for "subscription" route interactions
*/
func NewSubscriptionController(as *services.SubscriptionService, s *gin.RouterGroup) *SubscriptionController { func NewSubscriptionController(as *services.SubscriptionService, s *gin.RouterGroup) *SubscriptionController {
wc := new(SubscriptionController) wc := new(SubscriptionController)
wc.SubscriptionService = as wc.SubscriptionService = as
@@ -30,6 +39,11 @@ func NewSubscriptionController(as *services.SubscriptionService, s *gin.RouterGr
return wc return wc
} }
/*
New
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /subscription) // ROUTE (POST /subscription)
func (wc *SubscriptionController) New(c *gin.Context) { func (wc *SubscriptionController) New(c *gin.Context) {
body := new(models.NewSubscriptionBody) body := new(models.NewSubscriptionBody)
@@ -42,6 +56,11 @@ func (wc *SubscriptionController) New(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
Edit
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (PUT /subscription/:id) // ROUTE (PUT /subscription/:id)
func (wc *SubscriptionController) Edit(c *gin.Context) { func (wc *SubscriptionController) Edit(c *gin.Context) {
body := new(models.SubscriptionEdit) body := new(models.SubscriptionEdit)
@@ -56,6 +75,11 @@ func (wc *SubscriptionController) Edit(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
Get
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /subscription/:id) // ROUTE (GET /subscription/:id)
func (wc *SubscriptionController) Get(c *gin.Context) { func (wc *SubscriptionController) Get(c *gin.Context) {
body := new(models.Auth) body := new(models.Auth)
@@ -94,6 +118,11 @@ func (wc *SubscriptionController) End(c *gin.Context) {
c.JSON(200, fr) c.JSON(200, fr)
} }
/*
GetAll
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /subscription) // ROUTE (GET /subscription)
func (wc *SubscriptionController) GetAll(c *gin.Context) { func (wc *SubscriptionController) GetAll(c *gin.Context) {
body := new(models.Auth) body := new(models.Auth)

View File

@@ -0,0 +1,64 @@
package controllers
import (
"net/http"
"wallet-api/pkg/models"
"wallet-api/pkg/services"
"github.com/gin-gonic/gin"
)
type TransactionStatusController struct {
TransactionStatusService *services.TransactionStatusService
}
/*
NewTransactionStatusController
Initializes TransactionStatusController.
Args:
*services.TransactionStatusService: Transaction Staus service
*gin.RouterGroup: Gin Router Group
Returns:
*TransactionStatusController: Controller for "transaction-status" route interactions
*/
func NewTransactionStatusController(as *services.TransactionStatusService, s *gin.RouterGroup) *TransactionStatusController {
wc := new(TransactionStatusController)
wc.TransactionStatusService = as
s.POST("", wc.New)
s.GET("", wc.GetAll)
return wc
}
/*
New
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /transaction-status)
func (wc *TransactionStatusController) New(c *gin.Context) {
body := new(models.NewTransactionStatusBody)
if err := c.ShouldBind(body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
wm := wc.TransactionStatusService.New(c, body)
c.JSON(200, wm)
}
/*
GetAll
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /transaction-status)
func (wc *TransactionStatusController) GetAll(c *gin.Context) {
embed, _ := c.GetQuery("embed")
wm := wc.TransactionStatusService.GetAll(c, embed)
c.JSON(200, wm)
}

View File

@@ -12,7 +12,16 @@ type TransactionTypeController struct {
TransactionTypeService *services.TransactionTypeService TransactionTypeService *services.TransactionTypeService
} }
// Initializes TransactionTypeController. /*
NewTransactionTypeController
Initializes TransactionTypeController.
Args:
*services.TransactionTypeService: Transaction Type service
*gin.RouterGroup: Gin Router Group
Returns:
*TransactionTypeController: Controller for "transaction-types" route interactions
*/
func NewTransactionTypeController(as *services.TransactionTypeService, s *gin.RouterGroup) *TransactionTypeController { func NewTransactionTypeController(as *services.TransactionTypeService, s *gin.RouterGroup) *TransactionTypeController {
wc := new(TransactionTypeController) wc := new(TransactionTypeController)
wc.TransactionTypeService = as wc.TransactionTypeService = as
@@ -23,6 +32,11 @@ func NewTransactionTypeController(as *services.TransactionTypeService, s *gin.Ro
return wc return wc
} }
/*
New
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /transaction-types) // ROUTE (POST /transaction-types)
func (wc *TransactionTypeController) New(c *gin.Context) { func (wc *TransactionTypeController) New(c *gin.Context) {
body := new(models.NewTransactionTypeBody) body := new(models.NewTransactionTypeBody)
@@ -35,6 +49,11 @@ func (wc *TransactionTypeController) New(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
GetAll
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /transaction-types) // ROUTE (GET /transaction-types)
func (wc *TransactionTypeController) GetAll(c *gin.Context) { func (wc *TransactionTypeController) GetAll(c *gin.Context) {
embed, _ := c.GetQuery("embed") embed, _ := c.GetQuery("embed")

View File

@@ -12,7 +12,16 @@ type TransactionController struct {
TransactionService *services.TransactionService TransactionService *services.TransactionService
} }
// Initializes TransactionController. /*
NewTransactionController
Initializes TransactionController.
Args:
*services.TransactionService: Transaction service
*gin.RouterGroup: Gin Router Group
Returns:
*TransactionController: Controller for "transaction" route interactions
*/
func NewTransactionController(as *services.TransactionService, s *gin.RouterGroup) *TransactionController { func NewTransactionController(as *services.TransactionService, s *gin.RouterGroup) *TransactionController {
wc := new(TransactionController) wc := new(TransactionController)
wc.TransactionService = as wc.TransactionService = as
@@ -21,10 +30,17 @@ func NewTransactionController(as *services.TransactionService, s *gin.RouterGrou
s.GET("", wc.GetAll) s.GET("", wc.GetAll)
s.PUT("/:id", wc.Edit) s.PUT("/:id", wc.Edit)
s.GET("/:id", wc.Get) s.GET("/:id", wc.Get)
s.GET("check", wc.Check)
s.PUT("/bulk", wc.BulkEdit)
return wc return wc
} }
/*
New
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /transactions) // ROUTE (POST /transactions)
func (wc *TransactionController) New(c *gin.Context) { func (wc *TransactionController) New(c *gin.Context) {
body := new(models.NewTransactionBody) body := new(models.NewTransactionBody)
@@ -37,6 +53,11 @@ func (wc *TransactionController) New(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
GetAll
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /transactions) // ROUTE (GET /transactions)
func (wc *TransactionController) GetAll(c *gin.Context) { func (wc *TransactionController) GetAll(c *gin.Context) {
body := new(models.Auth) body := new(models.Auth)
@@ -46,11 +67,38 @@ func (wc *TransactionController) GetAll(c *gin.Context) {
fr := FilteredResponse(c) fr := FilteredResponse(c)
wallet, _ := c.GetQuery("walletId") wallet, _ := c.GetQuery("walletId")
wc.TransactionService.GetAll(c, body, wallet, fr) noPendingQry, _ := c.GetQuery("noPending")
noPending := noPendingQry != ""
wc.TransactionService.GetAll(c, body, wallet, fr, noPending)
c.JSON(200, fr) c.JSON(200, fr)
} }
/*
Check
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /transactions)
func (wc *TransactionController) Check(c *gin.Context) {
body := new(models.Auth)
auth := c.MustGet("auth")
body.Id = auth.(*models.Auth).Id
fr := FilteredResponse(c)
wallet, _ := c.GetQuery("walletId")
wc.TransactionService.Check(c, body, wallet, fr)
c.JSON(200, fr)
}
/*
Edit
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (PUT /transactions/:id) // ROUTE (PUT /transactions/:id)
func (wc *TransactionController) Edit(c *gin.Context) { func (wc *TransactionController) Edit(c *gin.Context) {
body := new(models.TransactionEdit) body := new(models.TransactionEdit)
@@ -65,6 +113,28 @@ func (wc *TransactionController) Edit(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
BulkEdit
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (PUT /transactions/:id)
func (wc *TransactionController) BulkEdit(c *gin.Context) {
body := new([]models.TransactionEdit)
if err := c.ShouldBind(body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
wm := wc.TransactionService.BulkEdit(c, body)
c.JSON(200, wm)
}
/*
Get
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /transactions/:id) // ROUTE (GET /transactions/:id)
func (wc *TransactionController) Get(c *gin.Context) { func (wc *TransactionController) Get(c *gin.Context) {
body := new(models.Auth) body := new(models.Auth)

View File

@@ -11,7 +11,16 @@ type WalletsHeaderController struct {
WalletService *services.WalletService WalletService *services.WalletService
} }
// Initializes WalletsHeaderController. /*
NewWalletsHeaderController
Initializes WalletsHeaderController.
Args:
*services.WalletService: Wallet service
*gin.RouterGroup: Gin Router Group
Returns:
*WalletsHeaderController: Controller for "wallet/wallet-header" route interactions
*/
func NewWalletsHeaderController(as *services.WalletService, s *gin.RouterGroup) *WalletsHeaderController { func NewWalletsHeaderController(as *services.WalletService, s *gin.RouterGroup) *WalletsHeaderController {
wc := new(WalletsHeaderController) wc := new(WalletsHeaderController)
wc.WalletService = as wc.WalletService = as
@@ -21,6 +30,11 @@ func NewWalletsHeaderController(as *services.WalletService, s *gin.RouterGroup)
return wc return wc
} }
/*
Get
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /wallet/wallet-header) // ROUTE (GET /wallet/wallet-header)
func (wc *WalletsHeaderController) Get(c *gin.Context) { func (wc *WalletsHeaderController) Get(c *gin.Context) {
body := new(models.Auth) body := new(models.Auth)

View File

@@ -12,7 +12,16 @@ type WalletsController struct {
WalletService *services.WalletService WalletService *services.WalletService
} }
// Initializes WalletsController. /*
NewWalletsController
Initializes WalletsController.
Args:
*services.WalletService: Wallet service
*gin.RouterGroup: Gin Router Group
Returns:
*WalletsController: Controller for "wallet" route interactions
*/
func NewWalletsController(as *services.WalletService, s *gin.RouterGroup) *WalletsController { func NewWalletsController(as *services.WalletService, s *gin.RouterGroup) *WalletsController {
wc := new(WalletsController) wc := new(WalletsController)
wc.WalletService = as wc.WalletService = as
@@ -25,6 +34,11 @@ func NewWalletsController(as *services.WalletService, s *gin.RouterGroup) *Walle
return wc return wc
} }
/*
New
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (POST /wallet) // ROUTE (POST /wallet)
func (wc *WalletsController) New(c *gin.Context) { func (wc *WalletsController) New(c *gin.Context) {
body := new(models.NewWalletBody) body := new(models.NewWalletBody)
@@ -41,6 +55,11 @@ func (wc *WalletsController) New(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
GetAll
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /wallet) // ROUTE (GET /wallet)
func (wc *WalletsController) GetAll(c *gin.Context) { func (wc *WalletsController) GetAll(c *gin.Context) {
body := new(models.Auth) body := new(models.Auth)
@@ -54,6 +73,11 @@ func (wc *WalletsController) GetAll(c *gin.Context) {
c.JSON(200, fr) c.JSON(200, fr)
} }
/*
Edit
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (PUT /wallet/:id) // ROUTE (PUT /wallet/:id)
func (wc *WalletsController) Edit(c *gin.Context) { func (wc *WalletsController) Edit(c *gin.Context) {
body := new(models.WalletEdit) body := new(models.WalletEdit)
@@ -68,6 +92,11 @@ func (wc *WalletsController) Edit(c *gin.Context) {
c.JSON(200, wm) c.JSON(200, wm)
} }
/*
Get
Args:
*gin.Context: Gin Application Context
*/
// ROUTE (GET /wallet/:id) // ROUTE (GET /wallet/:id)
func (wc *WalletsController) Get(c *gin.Context) { func (wc *WalletsController) Get(c *gin.Context) {
params := new(models.Params) params := new(models.Params)

View File

@@ -12,9 +12,13 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// Auth Middleware. /*
// Auth
// Checks if token from header is valid and extracts the id.
Checks if token from header is valid and extracts the id.
Args:
*gin.Context: Gin Application Context.
*/
func Auth(c *gin.Context) { func Auth(c *gin.Context) {
exceptionReturn := new(models.Exception) exceptionReturn := new(models.Exception)
tokenString := ExtractToken(c) tokenString := ExtractToken(c)
@@ -37,7 +41,15 @@ func Auth(c *gin.Context) {
c.Next() c.Next()
} }
// Extracts token from header /*
ExtractToken
Extracts token from header
Args:
*gin.Context: Gin Application Context.
Returns:
string: Token extracted from context header
*/
func ExtractToken(c *gin.Context) string { func ExtractToken(c *gin.Context) string {
bearerToken := c.GetHeader("Authorization") bearerToken := c.GetHeader("Authorization")
tokenArr := strings.Split(bearerToken, " ") tokenArr := strings.Split(bearerToken, " ")
@@ -50,7 +62,16 @@ func ExtractToken(c *gin.Context) string {
return "" return ""
} }
// Checks if token is valid /*
CheckToken
Checks if token is valid
Args:
string: Token to check
Returns:
*jwt.Token: Parsed token
error: Returns if token is invalid or there was an error inside jwt.Parse function
*/
func CheckToken(tokenString string) (*jwt.Token, error) { func CheckToken(tokenString string) (*jwt.Token, error) {
secret := os.Getenv("ACCESS_SECRET") secret := os.Getenv("ACCESS_SECRET")
if secret == "" { if secret == "" {

View File

@@ -2,9 +2,13 @@ package middleware
import "github.com/gin-gonic/gin" import "github.com/gin-gonic/gin"
// CORS Middleware. /*
// CORSMiddleware
// Add needed headers to make cors functioning.
Add needed headers to make cors functioning.
Args:
*gin.Context: Gin Application Context.
*/
func CORSMiddleware() gin.HandlerFunc { func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Origin", "*")

View File

@@ -9,9 +9,13 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// Secret Code Middleware. /*
// SecretCode
// Checks if secret code from body is valid.
Checks if secret code from body is valid.
Args:
*gin.Context: Gin Application Context.
*/
func SecretCode(c *gin.Context) { func SecretCode(c *gin.Context) {
exceptionReturn := new(models.Exception) exceptionReturn := new(models.Exception)
secretCode := ExtractCode(c) secretCode := ExtractCode(c)
@@ -29,7 +33,13 @@ func SecretCode(c *gin.Context) {
c.Next() c.Next()
} }
// Extracts the secret code from body /*
ExtractCode
Extracts the secret code from body.
Args:
*gin.Context: Gin Application Context.
*/
func ExtractCode(c *gin.Context) SecretCodeModel { func ExtractCode(c *gin.Context) SecretCodeModel {
secret := new(SecretCodeModel) secret := new(SecretCodeModel)
if err := c.ShouldBindJSON(&secret); err != nil { if err := c.ShouldBindJSON(&secret); err != nil {

View File

@@ -0,0 +1,40 @@
package migrate
import (
"fmt"
"log"
"wallet-api/pkg/models"
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
)
/*
CreateTableTransactionStatus
Creates transaction_status table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableTransactionStatus(db pg.DB) error {
models := []interface{}{
(*models.TransactionStatus)(nil),
}
for _, model := range models {
err := db.Model(model).CreateTable(&orm.CreateTableOptions{
IfNotExists: false,
FKConstraints: true,
})
if err != nil {
log.Printf("Error creating table \"transaction_status\": %s", err)
return err
} else {
fmt.Println("Table \"transaction_status\" created successfully")
}
}
return nil
}

View File

@@ -0,0 +1,62 @@
package migrate
import (
"fmt"
"log"
"wallet-api/pkg/models"
"github.com/go-pg/pg/v10"
)
/*
PopulateTransactionStatus
Populates transaction_status table if it exists.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with populating table
*/
func PopulateTransactionStatus(db pg.DB) error {
completed := new(models.TransactionStatus)
pending := new(models.TransactionStatus)
deleted := new(models.TransactionStatus)
completed.Init()
completed.Name = "Completed"
completed.Status = "completed"
pending.Init()
pending.Name = "Pending"
pending.Status = "pending"
deleted.Init()
deleted.Name = "Deleted"
deleted.Status = "deleted"
_, err := db.Model(completed).Where("? = ?", pg.Ident("status"), completed.Status).SelectOrInsert()
if err != nil {
log.Printf("Error inserting row into \"transactionStatus\" table: %s", err)
return err
} else {
fmt.Println("Row inserted successfully into \"transactionStatus\" table.")
}
_, err = db.Model(pending).Where("? = ?", pg.Ident("status"), pending.Status).SelectOrInsert()
if err != nil {
log.Printf("Error inserting row into \"transactionStatus\" table: %s", err)
return err
} else {
fmt.Println("Row inserted successfully into \"transactionStatus\" table.")
}
_, err = db.Model(deleted).Where("? = ?", pg.Ident("status"), pending.Status).SelectOrInsert()
if err != nil {
log.Printf("Error inserting row into \"transactionStatus\" table: %s", err)
return err
} else {
fmt.Println("Row inserted successfully into \"transactionStatus\" table.")
}
return err
}

View File

@@ -10,7 +10,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates api table if it does not exist. /*
CreateTableApi
Creates api table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableApi(db pg.DB) error { func CreateTableApi(db pg.DB) error {
models := []interface{}{ models := []interface{}{

View File

@@ -10,7 +10,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates api users if it does not exist. /*
CreateTableUsers
Creates users table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableUsers(db pg.DB) error { func CreateTableUsers(db pg.DB) error {
models := []interface{}{ models := []interface{}{
(*models.User)(nil), (*models.User)(nil),

View File

@@ -10,7 +10,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates wallets table if it does not exist. /*
CreateTableWallets
Creates wallets table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableWallets(db pg.DB) error { func CreateTableWallets(db pg.DB) error {
models := []interface{}{ models := []interface{}{
(*models.Wallet)(nil), (*models.Wallet)(nil),

View File

@@ -10,7 +10,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates transactionTypes table if it does not exist. /*
CreateTableTransactionTypes
Creates transaction_types table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableTransactionTypes(db pg.DB) error { func CreateTableTransactionTypes(db pg.DB) error {
models := []interface{}{ models := []interface{}{
(*models.TransactionType)(nil), (*models.TransactionType)(nil),

View File

@@ -10,7 +10,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates api transactions if it does not exist. /*
CreateTableTransactions
Creates transactions table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableTransactions(db pg.DB) error { func CreateTableTransactions(db pg.DB) error {
models := []interface{}{ models := []interface{}{
(*models.Transaction)(nil), (*models.Transaction)(nil),

View File

@@ -10,7 +10,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates subscriptionTypes table if it does not exist. /*
CreateTableSubscriptionTypes
Creates subscription_types table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableSubscriptionTypes(db pg.DB) error { func CreateTableSubscriptionTypes(db pg.DB) error {
models := []interface{}{ models := []interface{}{
(*models.SubscriptionType)(nil), (*models.SubscriptionType)(nil),

View File

@@ -9,7 +9,15 @@ import (
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
) )
// Creates subscriptions table if it does not exist. /*
CreateTableSubscriptions
Creates subscriptions table if it does not exist.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with table creation
*/
func CreateTableSubscriptions(db pg.DB) error { func CreateTableSubscriptions(db pg.DB) error {
models := []interface{}{ models := []interface{}{
(*models.Subscription)(nil), (*models.Subscription)(nil),

View File

@@ -8,7 +8,15 @@ import (
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
) )
// Populates subscriptionTypes table if it does not exist. /*
PopulateSubscriptionTypes
Populates subscription_types table if it exists.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with populating table
*/
func PopulateSubscriptionTypes(db pg.DB) error { func PopulateSubscriptionTypes(db pg.DB) error {
daily := new(models.SubscriptionType) daily := new(models.SubscriptionType)
weekly := new(models.SubscriptionType) weekly := new(models.SubscriptionType)

View File

@@ -8,7 +8,15 @@ import (
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
) )
// Populates transactionTypes table if it does not exist. /*
PopulateTransactionTypes
Populates transaction_types table if it exists.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with populating table
*/
func PopulateTransactionTypes(db pg.DB) error { func PopulateTransactionTypes(db pg.DB) error {
gain := new(models.TransactionType) gain := new(models.TransactionType)
expense := new(models.TransactionType) expense := new(models.TransactionType)

View File

@@ -4,7 +4,15 @@ import (
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
) )
// Starts database migration. /*
Start
Starts database migration.
Args:
*pg.DB: Postgres database client
Returns:
error: Returns if there is an error with populating table
*/
func Start(conn *pg.DB, version string) { func Start(conn *pg.DB, version string) {
migration001 := Migration{ migration001 := Migration{
Version: "001", Version: "001",
@@ -25,10 +33,24 @@ func Start(conn *pg.DB, version string) {
PopulateTransactionTypes, PopulateTransactionTypes,
}, },
} }
migration003 := Migration{
Version: "003",
Migrations: []interface{}{
CreateTableTransactionStatus,
},
}
migration004 := Migration{
Version: "004",
Migrations: []interface{}{
PopulateTransactionStatus,
},
}
migrationsMap := []Migration{ migrationsMap := []Migration{
migration001, migration001,
migration002, migration002,
migration003,
migration004,
} }
for _, migrationCol := range migrationsMap { for _, migrationCol := range migrationsMap {

View File

@@ -12,6 +12,11 @@ type BaseModel struct {
DateUpdated time.Time `json:"dateUpdated" pg:"date_updated"` DateUpdated time.Time `json:"dateUpdated" pg:"date_updated"`
} }
/*
Init
Initializes base model with DateCreated, DateUpdated, and Id values.
*/
func (cm *BaseModel) Init() { func (cm *BaseModel) Init() {
date := time.Now() date := time.Now()
cm.Id = uuid.NewString() cm.Id = uuid.NewString()

View File

@@ -16,6 +16,13 @@ type UserReturnInfo struct {
Email string `json:"email"` Email string `json:"email"`
} }
/*
Payload
Maps User object to UserReturnInfo object.
Returns:
*UserReturnInfo: mapped UserReturnInfo object
*/
func (um *User) Payload() *UserReturnInfo { func (um *User) Payload() *UserReturnInfo {
payload := new(UserReturnInfo) payload := new(UserReturnInfo)
payload.BaseModel = um.BaseModel payload.BaseModel = um.BaseModel

View File

@@ -49,6 +49,13 @@ type SubscriptionEnd struct {
Id string `json:"id" form:"id"` Id string `json:"id" form:"id"`
} }
/*
ToTrans
Maps Subscription object to Transaction object.
Returns:
*Transaction: mapped Transaction object
*/
func (cm *Subscription) ToTrans() *Transaction { func (cm *Subscription) ToTrans() *Transaction {
trans := new(Transaction) trans := new(Transaction)
trans.Init() trans.Init()
@@ -63,6 +70,13 @@ func (cm *Subscription) ToTrans() *Transaction {
return trans return trans
} }
/*
HasNew
Checks if Subscription reached new transaction interval.
Returns:
bool: Is new transaction interval reached
*/
func (cm *Subscription) HasNew() bool { func (cm *Subscription) HasNew() bool {
trans := cm.TransactionType trans := cm.TransactionType
if trans != nil { if trans != nil {

View File

@@ -0,0 +1,13 @@
package models
type TransactionStatus struct {
tableName struct{} `pg:"transactionStatus,alias:transactionStatus"`
BaseModel
Name string `json:"name" pg:"name"`
Status string `json:"status" pg:"status,notnull"`
}
type NewTransactionStatusBody struct {
Name string `json:"name" form:"name"`
Status string `json:"status" form:"status"`
}

View File

@@ -8,15 +8,17 @@ import (
type Transaction struct { type Transaction struct {
tableName struct{} `pg:"transactions,alias:transactions"` tableName struct{} `pg:"transactions,alias:transactions"`
BaseModel BaseModel
Description string `json:"description" pg:"description"` Description string `json:"description" pg:"description"`
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"` TransactionStatusID string `json:"transactionStatusId", pg:"transaction_status_id"`
Amount float32 `json:"amount", pg:"amount,default:0"` TransactionStatus *TransactionStatus `json:"transactionStatus", pg:"rel:has-one, fk:transaction_status_id"`
Wallet *Wallet `json:"wallet" pg:"rel:has-one, fk:wallet_id"` WalletID string `json:"walletId", pg:"wallet_id"`
TransactionDate time.Time `json:"transactionDate" pg:"transaction_date, type:timestamptz"` Amount float32 `json:"amount", pg:"amount,default:0"`
SubscriptionID string `json:"subscriptionId", pg:"subscription_id"` Wallet *Wallet `json:"wallet" pg:"rel:has-one, fk:wallet_id"`
Subscription *Subscription `json:"subscription", pg:"rel:has-one, fk:subscription_id"` TransactionDate time.Time `json:"transactionDate" pg:"transaction_date, type:timestamptz"`
SubscriptionID string `json:"subscriptionId", pg:"subscription_id"`
Subscription *Subscription `json:"subscription", pg:"rel:has-one, fk:subscription_id"`
} }
type NewTransactionBody struct { type NewTransactionBody struct {
@@ -28,10 +30,11 @@ type NewTransactionBody struct {
} }
type TransactionEdit struct { type TransactionEdit struct {
Id string `json:"id" form:"id"` Id string `json:"id" form:"id"`
WalletID string `json:"walletId" form:"walletId"` WalletID string `json:"walletId" form:"walletId"`
TransactionTypeID string `json:"transactionTypeId" form:"transactionTypeId"` TransactionTypeID string `json:"transactionTypeId" form:"transactionTypeId"`
TransactionDate time.Time `json:"transactionDate" form:"transactionDate"` TransactionDate time.Time `json:"transactionDate" form:"transactionDate"`
Description string `json:"description" form:"description"` TransactionStatusID string `json:"transactionStatusId" form:"transactionStatusId"`
Amount json.Number `json:"amount" form:"amount"` Description string `json:"description" form:"description"`
Amount json.Number `json:"amount" form:"amount"`
} }

View File

@@ -12,7 +12,15 @@ type ApiService struct {
Db *pg.DB Db *pg.DB
} }
// Gets first row from API table. /*
GetFirst
Gets first row from API table.
Args:
context.Context: Application context
Returns:
models.ApiModel: Api object from database.
*/
func (as *ApiService) GetFirst(ctx context.Context) models.ApiModel { func (as *ApiService) GetFirst(ctx context.Context) models.ApiModel {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -21,9 +29,17 @@ func (as *ApiService) GetFirst(ctx context.Context) models.ApiModel {
return apiModel return apiModel
} }
// Starts database migration. /*
// PostMigrate
// Takes migration version.
Starts database migration.
Args:
context.Context: Application context
string: Migration version
Returns:
*models.MessageResponse: Message response object.
*models.Exception: Exception response object.
*/
func (as *ApiService) PostMigrate(ctx context.Context, version string) (*models.MessageResponse, *models.Exception) { func (as *ApiService) PostMigrate(ctx context.Context, version string) (*models.MessageResponse, *models.Exception) {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)

View File

@@ -7,7 +7,15 @@ import (
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
) )
// Adds filters to query and executes it. /*
FilteredResponse
Adds filters to query and executes it.
Args:
*pg.Query: postgres query
interface{}: model to be mapped from query execution.
*models.FilteredResponse: filter options.
*/
func FilteredResponse(qry *pg.Query, mdl interface{}, filtered *models.FilteredResponse) { func FilteredResponse(qry *pg.Query, mdl interface{}, filtered *models.FilteredResponse) {
if filtered.Page == 0 { if filtered.Page == 0 {
filtered.Page = 1 filtered.Page = 1

View File

@@ -12,7 +12,16 @@ type SubscriptionTypeService struct {
Db *pg.DB Db *pg.DB
} }
// Inserts new row to subscription type table. /*
New
Inserts new row to subscription type table.
Args:
context.Context: Application context
*models.NewSubscriptionTypeBody: Values to create new row
Returns:
*models.SubscriptionType: Created row from database.
*/
func (as *SubscriptionTypeService) New(ctx context.Context, body *models.NewSubscriptionTypeBody) *models.SubscriptionType { func (as *SubscriptionTypeService) New(ctx context.Context, body *models.NewSubscriptionTypeBody) *models.SubscriptionType {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -27,7 +36,16 @@ func (as *SubscriptionTypeService) New(ctx context.Context, body *models.NewSubs
return tm return tm
} }
// Gets all rows from subscription type table. /*
GetAll
Gets all rows from subscription type table.
Args:
context.Context: Application context
string: Relations to embed
Returns:
*[]models.SubscriptionType: List of subscription type objects.
*/
func (as *SubscriptionTypeService) GetAll(ctx context.Context, embed string) *[]models.SubscriptionType { func (as *SubscriptionTypeService) GetAll(ctx context.Context, embed string) *[]models.SubscriptionType {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)

View File

@@ -14,7 +14,16 @@ type SubscriptionService struct {
Db *pg.DB Db *pg.DB
} }
// Inserts new row to subscription table. /*
New
Inserts new row to subscription table.
Args:
context.Context: Application context
*models.NewSubscriptionBody: Request body
Returns:
*models.Subscription: Created Subscription row object from database.
*/
func (as *SubscriptionService) New(ctx context.Context, body *models.NewSubscriptionBody) *models.Subscription { func (as *SubscriptionService) New(ctx context.Context, body *models.NewSubscriptionBody) *models.Subscription {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -42,14 +51,23 @@ func (as *SubscriptionService) New(ctx context.Context, body *models.NewSubscrip
defer tx.Rollback() defer tx.Rollback()
tx.Model(tm).Insert() tx.Model(tm).Insert()
as.SubToTrans(tm, tx)
tx.Commit() tx.Commit()
return tm return tm
} }
// Gets row from subscription table by id. /*
Get
Gets row from subscription table by id.
Args:
context.Context: Application context
*models.Auth: Authentication model
string: subscription id to search
params: *models.Params
Returns:
*models.Subscription: Subscription row object from database.
*/
func (as *SubscriptionService) Get(ctx context.Context, am *models.Auth, id string, params *models.Params) *models.Subscription { func (as *SubscriptionService) Get(ctx context.Context, am *models.Auth, id string, params *models.Params) *models.Subscription {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -62,16 +80,21 @@ func (as *SubscriptionService) Get(ctx context.Context, am *models.Auth, id stri
qry := tx.Model(wm) qry := tx.Model(wm)
common.GenerateEmbed(qry, params.Embed).WherePK().Select() common.GenerateEmbed(qry, params.Embed).WherePK().Select()
if (*wm).HasNew() {
as.SubToTrans(wm, tx)
}
tx.Commit() tx.Commit()
return wm return wm
} }
// Gets filtered rows from subscription table. /*
GetAll
Gets filtered rows from subscription table.
Args:
context.Context: Application context
*models.Auth: Authentication object
string: Wallet id to search
*models.FilteredResponse: filter options
*/
func (as *SubscriptionService) GetAll(ctx context.Context, am *models.Auth, walletId string, filtered *models.FilteredResponse) { func (as *SubscriptionService) GetAll(ctx context.Context, am *models.Auth, walletId string, filtered *models.FilteredResponse) {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -85,16 +108,21 @@ func (as *SubscriptionService) GetAll(ctx context.Context, am *models.Auth, wall
query = query.Where("? = ?", pg.Ident("wallet_id"), walletId) query = query.Where("? = ?", pg.Ident("wallet_id"), walletId)
} }
for _, sub := range *wm {
if sub.HasNew() {
as.SubToTrans(&sub, tx)
}
}
FilteredResponse(query, wm, filtered) FilteredResponse(query, wm, filtered)
tx.Commit() tx.Commit()
} }
// Updates row from subscription table by id. /*
Edit
Updates row from subscription table by id.
Args:
context.Context: Application context
*models.SubscriptionEdit: Values to edit
string: id to search
Returns:
*models.Subscription: Edited Subscription row object from database.
*/
func (as *SubscriptionService) Edit(ctx context.Context, body *models.SubscriptionEdit, id string) *models.Subscription { func (as *SubscriptionService) Edit(ctx context.Context, body *models.SubscriptionEdit, id string) *models.Subscription {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -118,9 +146,18 @@ func (as *SubscriptionService) Edit(ctx context.Context, body *models.Subscripti
return tm return tm
} }
// Updates row in subscription table by id. /*
// End
// Ends subscription with current date.
Updates row in subscription table by id.
Ends subscription with current date.
Args:
context.Context: Application context
string: id to search
Returns:
*models.Subscription: Created Subscription row object from database.
*/
func (as *SubscriptionService) End(ctx context.Context, id string) *models.Subscription { func (as *SubscriptionService) End(ctx context.Context, id string) *models.Subscription {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -139,7 +176,14 @@ func (as *SubscriptionService) End(ctx context.Context, id string) *models.Subsc
return tm return tm
} }
// Generates and Inserts new Transaction rows from the subscription model. /*
SubToTrans
Generates and Inserts new Transaction rows from the subscription model.
Args:
*models.Subscription: Subscription model to generate new transactions from
*pg.Tx: Postgres query context
*/
func (as *SubscriptionService) SubToTrans(subModel *models.Subscription, tx *pg.Tx) { func (as *SubscriptionService) SubToTrans(subModel *models.Subscription, tx *pg.Tx) {
now := time.Now() now := time.Now()
@@ -147,7 +191,9 @@ func (as *SubscriptionService) SubToTrans(subModel *models.Subscription, tx *pg.
currentYear, currentMonth, _ := now.Date() currentYear, currentMonth, _ := now.Date()
currentLocation := now.Location() currentLocation := now.Location()
transactionStatus := new(models.TransactionStatus)
firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation) 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()) //tzFirstOfNextMonth := firstOfNextMonth.In(subModel.StartDate.Location())
startDate := subModel.StartDate startDate := subModel.StartDate
@@ -167,6 +213,7 @@ func (as *SubscriptionService) SubToTrans(subModel *models.Subscription, tx *pg.
for startDate.Before(stopDate) { for startDate.Before(stopDate) {
trans := subModel.ToTrans() trans := subModel.ToTrans()
trans.TransactionDate = startDate trans.TransactionDate = startDate
trans.TransactionStatusID = transactionStatus.Id
if startDate.After(subModel.LastTransactionDate) && (startDate.Before(now) || startDate.Equal(now)) { if startDate.After(subModel.LastTransactionDate) && (startDate.Before(now) || startDate.Equal(now)) {
*transactions = append(*transactions, *trans) *transactions = append(*transactions, *trans)
} }

View File

@@ -0,0 +1,58 @@
package services
import (
"context"
"wallet-api/pkg/models"
"wallet-api/pkg/utl/common"
"github.com/go-pg/pg/v10"
)
type TransactionStatusService struct {
Db *pg.DB
}
/*
New
Inserts new row to transaction status table.
Args:
context.Context: Application context
*models.NewTransactionStatusBody: object to create
Returns:
*models.TransactionType: Transaction Type object from database.
*/
func (as *TransactionStatusService) New(ctx context.Context, body *models.NewTransactionStatusBody) *models.TransactionStatus {
db := as.Db.WithContext(ctx)
tm := new(models.TransactionStatus)
tm.Init()
tm.Name = body.Name
tm.Status = body.Status
db.Model(tm).Insert()
return tm
}
/*
GetAll
Gets all rows from transaction status table.
Args:
context.Context: Application context
string: Relations to embed
Returns:
*[]models.TransactionStatus: List of Transaction status objects from database.
*/
func (as *TransactionStatusService) GetAll(ctx context.Context, embed string) *[]models.TransactionStatus {
db := as.Db.WithContext(ctx)
wm := new([]models.TransactionStatus)
query := db.Model(wm)
common.GenerateEmbed(query, embed).Select()
return wm
}

View File

@@ -12,7 +12,16 @@ type TransactionTypeService struct {
Db *pg.DB Db *pg.DB
} }
// Inserts new row to transaction type table. /*
New
Inserts new row to transaction type table.
Args:
context.Context: Application context
*models.NewTransactionTypeBody: object to create
Returns:
*models.TransactionType: Transaction Type object from database.
*/
func (as *TransactionTypeService) New(ctx context.Context, body *models.NewTransactionTypeBody) *models.TransactionType { func (as *TransactionTypeService) New(ctx context.Context, body *models.NewTransactionTypeBody) *models.TransactionType {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -27,7 +36,16 @@ func (as *TransactionTypeService) New(ctx context.Context, body *models.NewTrans
return tm return tm
} }
// Gets all rows from transaction type table. /*
GetAll
Gets all rows from transaction type table.
Args:
context.Context: Application context
string: Relations to embed
Returns:
*[]models.TransactionType: List of Transaction type objects from database.
*/
func (as *TransactionTypeService) GetAll(ctx context.Context, embed string) *[]models.TransactionType { func (as *TransactionTypeService) GetAll(ctx context.Context, embed string) *[]models.TransactionType {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)

View File

@@ -15,15 +15,27 @@ type TransactionService struct {
Ss *SubscriptionService Ss *SubscriptionService
} }
// Inserts new row to transaction table. /*
New new row into transaction table
Inserts
Args:
context.Context: Application context
*models.NewTransactionBody: Transaction body object
Returns:
*models.Transaction: Transaction object
*/
func (as *TransactionService) New(ctx context.Context, body *models.NewTransactionBody) *models.Transaction { func (as *TransactionService) New(ctx context.Context, body *models.NewTransactionBody) *models.Transaction {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
tm := new(models.Transaction) tm := new(models.Transaction)
transactionStatus := new(models.TransactionStatus)
tx, _ := db.Begin() tx, _ := db.Begin()
defer tx.Rollback() defer tx.Rollback()
tx.Model(transactionStatus).Where("? = ?", pg.Ident("status"), "completed").Select()
amount, _ := body.Amount.Float64() amount, _ := body.Amount.Float64()
tm.Init() tm.Init()
@@ -32,6 +44,7 @@ func (as *TransactionService) New(ctx context.Context, body *models.NewTransacti
tm.Description = body.Description tm.Description = body.Description
tm.TransactionDate = body.TransactionDate tm.TransactionDate = body.TransactionDate
tm.Amount = float32(math.Round(amount*100) / 100) tm.Amount = float32(math.Round(amount*100) / 100)
tm.TransactionStatusID = transactionStatus.Id
if body.TransactionDate.IsZero() { if body.TransactionDate.IsZero() {
tm.TransactionDate = time.Now() tm.TransactionDate = time.Now()
@@ -43,16 +56,63 @@ func (as *TransactionService) New(ctx context.Context, body *models.NewTransacti
return tm return tm
} }
/*
GetAll
Gets all rows from subscription type table.
Args:
context.Context: Application context
string: Relations to embed
Returns:
*[]models.SubscriptionType: List of subscription type objects.
*/
// Gets filtered rows from transaction table. // Gets filtered rows from transaction table.
func (as *TransactionService) GetAll(ctx context.Context, am *models.Auth, walletId string, filtered *models.FilteredResponse) { func (as *TransactionService) GetAll(ctx context.Context, am *models.Auth, walletId string, filtered *models.FilteredResponse, noPending bool) {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
wm := new([]models.Transaction) wm := new([]models.Transaction)
sm := new([]models.Subscription) transactionStatus := new(models.TransactionStatus)
tx, _ := db.Begin() tx, _ := db.Begin()
defer tx.Rollback() defer tx.Rollback()
tx.Model(transactionStatus).Where("? = ?", pg.Ident("status"), "completed").Select()
query := tx.Model(wm).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id)
if walletId != "" {
query = query.Where("? = ?", pg.Ident("wallet_id"), walletId)
}
if noPending {
query = query.Where("? = ?", pg.Ident("transaction_status_id"), transactionStatus.Id)
}
FilteredResponse(query, wm, filtered)
tx.Commit()
}
/*
Check
Checks subscriptions and create transacitons.
Args:
context.Context: Application context
string: Relations to embed
Returns:
*[]models.SubscriptionType: List of subscription type objects.
*/
// Gets filtered rows from transaction table.
func (as *TransactionService) Check(ctx context.Context, am *models.Auth, walletId string, filtered *models.FilteredResponse) {
db := as.Db.WithContext(ctx)
wm := new([]models.Transaction)
sm := new([]models.Subscription)
transactionStatus := new(models.TransactionStatus)
tx, _ := db.Begin()
defer tx.Rollback()
tx.Model(transactionStatus).Where("? = ?", pg.Ident("status"), "pending").Select()
query2 := tx.Model(sm).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id) query2 := tx.Model(sm).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id)
if walletId != "" { if walletId != "" {
query2 = query2.Where("? = ?", pg.Ident("wallet_id"), walletId) query2 = query2.Where("? = ?", pg.Ident("wallet_id"), walletId)
@@ -69,13 +129,24 @@ func (as *TransactionService) GetAll(ctx context.Context, am *models.Auth, walle
if walletId != "" { if walletId != "" {
query = query.Where("? = ?", pg.Ident("wallet_id"), walletId) query = query.Where("? = ?", pg.Ident("wallet_id"), walletId)
} }
query = query.Where("? = ?", pg.Ident("transaction_status_id"), transactionStatus.Id)
FilteredResponse(query, wm, filtered) FilteredResponse(query, wm, filtered)
tx.Commit() tx.Commit()
} }
// Updates row in transaction table by id. /*
Edit
Updates row in transaction table by id.
Args:
context.Context: Application context
*models.TransactionEdit: Object to edit
string: id to search
Returns:
*models.Transaction: Transaction object from database.
*/
func (as *TransactionService) Edit(ctx context.Context, body *models.TransactionEdit, id string) *models.Transaction { func (as *TransactionService) Edit(ctx context.Context, body *models.TransactionEdit, id string) *models.Transaction {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -87,6 +158,7 @@ func (as *TransactionService) Edit(ctx context.Context, body *models.Transaction
tm.WalletID = body.WalletID tm.WalletID = body.WalletID
tm.TransactionTypeID = body.TransactionTypeID tm.TransactionTypeID = body.TransactionTypeID
tm.TransactionDate = body.TransactionDate tm.TransactionDate = body.TransactionDate
tm.TransactionStatusID = body.TransactionStatusID
tm.Amount = float32(math.Round(amount*100) / 100) tm.Amount = float32(math.Round(amount*100) / 100)
tx, _ := db.Begin() tx, _ := db.Begin()
@@ -99,7 +171,57 @@ func (as *TransactionService) Edit(ctx context.Context, body *models.Transaction
return tm return tm
} }
// Gets row from transaction table by id. /*
Bulk Edit
Updates row in transaction table by id.
Args:
context.Context: Application context
?[]models.Transaction Bulk Edit: Object to edit
string: id to search
Returns:
*models.Transaction: Transaction object from database.
*/
func (as *TransactionService) BulkEdit(ctx context.Context, body *[]models.TransactionEdit) *[]models.Transaction {
db := as.Db.WithContext(ctx)
tx, _ := db.Begin()
defer tx.Rollback()
transactions := new([]models.Transaction)
for _, transaction := range *body {
amount, _ := transaction.Amount.Float64()
tm := new(models.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)
tx.Model(tm).WherePK().UpdateNotZero()
*transactions = append(*transactions, *tm)
}
tx.Commit()
return transactions
}
/*
Get
Gets row from transaction table by id.
Args:
context.Context: Application context
*models.Auth: Authentication object
string: id to search
*model.Params: url query parameters
Returns:
*models.Transaction: Transaction object from database.
*/
func (as *TransactionService) Get(ctx context.Context, am *models.Auth, id string, params *models.Params) *models.Transaction { func (as *TransactionService) Get(ctx context.Context, am *models.Auth, id string, params *models.Params) *models.Transaction {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)

View File

@@ -18,7 +18,18 @@ type UsersService struct {
Db *pg.DB Db *pg.DB
} }
// Inserts new row to users table.
/*
Create
Inserts new row to users table.
Args:
context.Context: Application context
*models.User: User object to create
Returns:
*models.User: User object from database
*models.Exception
*/
func (us *UsersService) Create(ctx context.Context, registerBody *models.User) (*models.User, *models.Exception) { func (us *UsersService) Create(ctx context.Context, registerBody *models.User) (*models.User, *models.Exception) {
db := us.Db.WithContext(ctx) db := us.Db.WithContext(ctx)
@@ -53,7 +64,17 @@ func (us *UsersService) Create(ctx context.Context, registerBody *models.User) (
return registerBody, exceptionReturn return registerBody, exceptionReturn
} }
// Gets row from users table by email and valid password. /*
Login
Gets row from users table by email and valid password.
Args:
context.Context: Application context
*models.Login: object to search
Returns:
*models.Token: new session token
*models.Exception
*/
func (us *UsersService) Login(ctx context.Context, loginBody *models.Login) (*models.Token, *models.Exception) { func (us *UsersService) Login(ctx context.Context, loginBody *models.Login) (*models.Token, *models.Exception) {
db := us.Db.WithContext(ctx) db := us.Db.WithContext(ctx)
@@ -91,9 +112,19 @@ func (us *UsersService) Login(ctx context.Context, loginBody *models.Login) (*mo
return tokenPayload, exceptionReturn return tokenPayload, exceptionReturn
} }
// Updates row in users table. /*
// Deactivate
// IsActive column is set to false
Updates row in users table.
IsActive column is set to false
Args:
context.Context: Application context
*models.Auth: Authentication object
Returns:
*models.MessageResponse
*models.Exception
*/
func (us *UsersService) Deactivate(ctx context.Context, auth *models.Auth) (*models.MessageResponse, *models.Exception) { func (us *UsersService) Deactivate(ctx context.Context, auth *models.Auth) (*models.MessageResponse, *models.Exception) {
db := us.Db.WithContext(ctx) db := us.Db.WithContext(ctx)
@@ -129,9 +160,19 @@ func (us *UsersService) Deactivate(ctx context.Context, auth *models.Auth) (*mod
return mm, me return mm, me
} }
// Generates new jwt token. /*
// CreateToken
// It encodes the user id. Based on rememberMe it is valid through 48hours or 2hours.
Generates new jwt token.
It encodes the user id. Based on rememberMe it is valid through 48hours or 2hours.
Args:
*models.User: User object to encode
bool: Should function generate longer lasting token (48hrs)
Returns:
string: Generated token
error: Error that occured in the process
*/
func CreateToken(user *models.User, rememberMe bool) (string, error) { func CreateToken(user *models.User, rememberMe bool) (string, error) {
atClaims := jwt.MapClaims{} atClaims := jwt.MapClaims{}
atClaims["authorized"] = true atClaims["authorized"] = true

View File

@@ -14,7 +14,16 @@ type WalletService struct {
Ss *SubscriptionService Ss *SubscriptionService
} }
// Inserts row to wallets table. /*
New
Inserts row to wallets table.
Args:
context.Context: Application context
*models.NewWalletBody: Object to be inserted
Returns:
*models.Wallet: Wallet object from database.
*/
func (as *WalletService) New(ctx context.Context, am *models.NewWalletBody) *models.Wallet { func (as *WalletService) New(ctx context.Context, am *models.NewWalletBody) *models.Wallet {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -26,7 +35,17 @@ func (as *WalletService) New(ctx context.Context, am *models.NewWalletBody) *mod
return walletModel return walletModel
} }
// Updates row in wallets table by id. /*
Edit
Updates row in wallets table by id.
Args:
context.Context: Application context
*models.WalletEdit: Object to be edited
string: id to search
Returns:
*models.Wallet: Wallet object from database.
*/
func (as *WalletService) Edit(ctx context.Context, body *models.WalletEdit, id string) *models.Wallet { func (as *WalletService) Edit(ctx context.Context, body *models.WalletEdit, id string) *models.Wallet {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -44,7 +63,17 @@ func (as *WalletService) Edit(ctx context.Context, body *models.WalletEdit, id s
return tm return tm
} }
// Gets row in wallets table by id. /*
Get
Gets row in wallets table by id.
Args:
context.Context: Application context
string: id to search
*models.Params: url query parameters
Returns:
*models.Wallet: Wallet object from database
*/
func (as *WalletService) Get(ctx context.Context, id string, params *models.Params) *models.Wallet { func (as *WalletService) Get(ctx context.Context, id string, params *models.Params) *models.Wallet {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -62,7 +91,15 @@ func (as *WalletService) Get(ctx context.Context, id string, params *models.Para
return wm return wm
} }
// Gets filtered rows from wallets table. /*
GetAll
Gets filtered rows from wallets table.
Args:
context.Context: Application context
*models.Auth: Authentication object
*models.FilteredResponse: filter options
*/
func (as *WalletService) GetAll(ctx context.Context, am *models.Auth, filtered *models.FilteredResponse) { func (as *WalletService) GetAll(ctx context.Context, am *models.Auth, filtered *models.FilteredResponse) {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
wm := new([]models.Wallet) wm := new([]models.Wallet)
@@ -71,9 +108,19 @@ func (as *WalletService) GetAll(ctx context.Context, am *models.Auth, filtered *
FilteredResponse(query, wm, filtered) FilteredResponse(query, wm, filtered)
} }
// Gets row from wallets table. /*
// GetHeader
// Calculates previous month, current and next month totals.
Gets row from wallets table.
Calculates previous month, current and next month totals.
Args:
context.Context: Application context
*models.Auth: Authentication object
string: wallet id to search
Returns:
*models.WalletHeader: generated wallet header object
*/
func (as *WalletService) GetHeader(ctx context.Context, am *models.Auth, walletId string) *models.WalletHeader { func (as *WalletService) GetHeader(ctx context.Context, am *models.Auth, walletId string) *models.WalletHeader {
db := as.Db.WithContext(ctx) db := as.Db.WithContext(ctx)
@@ -81,10 +128,12 @@ func (as *WalletService) GetHeader(ctx context.Context, am *models.Auth, walletI
wallets := new([]models.WalletTransactions) wallets := new([]models.WalletTransactions)
transactions := new([]models.Transaction) transactions := new([]models.Transaction)
subscriptions := new([]models.Subscription) subscriptions := new([]models.Subscription)
transactionStatus := new(models.TransactionStatus)
tx, _ := db.Begin() tx, _ := db.Begin()
defer tx.Rollback() defer tx.Rollback()
tx.Model(transactionStatus).Where("? = ?", pg.Ident("status"), "completed").Select()
query2 := tx.Model(subscriptions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType").Relation("SubscriptionType") query2 := tx.Model(subscriptions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType").Relation("SubscriptionType")
if walletId != "" { if walletId != "" {
query2.Where("? = ?", pg.Ident("wallet_id"), walletId) query2.Where("? = ?", pg.Ident("wallet_id"), walletId)
@@ -100,16 +149,11 @@ func (as *WalletService) GetHeader(ctx context.Context, am *models.Auth, walletI
firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation) firstOfNextMonth := time.Date(currentYear, currentMonth+1, 1, 0, 0, 0, 0, currentLocation)
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 _, sub := range *subscriptions {
if sub.HasNew() {
as.Ss.SubToTrans(&sub, tx)
}
}
query := tx.Model(transactions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType") query := tx.Model(transactions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType")
if walletId != "" { if walletId != "" {
query.Where("? = ?", pg.Ident("wallet_id"), walletId) query.Where("? = ?", pg.Ident("wallet_id"), walletId)
} }
query = query.Where("? = ?", pg.Ident("transaction_status_id"), transactionStatus.Id)
query.Select() query.Select()
tx.Commit() tx.Commit()
@@ -181,9 +225,17 @@ func (as *WalletService) GetHeader(ctx context.Context, am *models.Auth, walletI
return wm return wm
} }
// Appends Transaction to the belonging walletId /*
// addWhere
// If missing, it creates the item list.
Appends Transaction to the belonging walletId.
If missing, it creates the item list.
Args:
*[]models.WalletTransactions: list to append to
string: wallet id to check
models.Transaction: Transaction to append
*/
func addWhere(s *[]models.WalletTransactions, walletId string, e models.Transaction) { func addWhere(s *[]models.WalletTransactions, walletId string, e models.Transaction) {
var exists bool var exists bool
for a := range *s { for a := range *s {