From 3809a9506d116621f7f440e9cf3922d9133002a9 Mon Sep 17 00:00:00 2001 From: samuelIkoli Date: Sat, 1 Mar 2025 04:48:04 +0100 Subject: [PATCH 1/2] refactor: interfaced the category service --- pkg/controller/billing/billing.go | 15 +++-- services/billing/billing.go | 96 +++++++++++++++---------------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/pkg/controller/billing/billing.go b/pkg/controller/billing/billing.go index be2e5f9..5f96a41 100644 --- a/pkg/controller/billing/billing.go +++ b/pkg/controller/billing/billing.go @@ -50,7 +50,8 @@ func (base *Controller) CreateBilling(c *gin.Context) { userClaims := claims.(jwt.MapClaims) userId := userClaims["user_id"].(string) - respData, err := billing.CreateBilling(billingReq, base.Db.Postgresql.DB(), userId) + billingService := billing.NewBillingService(base.Db.Postgresql.DB()) + respData, err := billingService.CreateBilling(billingReq, userId) if err != nil { rd := utility.BuildErrorResponse(http.StatusBadRequest, "error", err.Error(), err, nil) @@ -84,7 +85,8 @@ func (base *Controller) DeleteBilling(c *gin.Context) { userClaims := claims.(jwt.MapClaims) userId := userClaims["user_id"].(string) - if err := billing.DeleteBilling(billingID, userId, base.Db.Postgresql.DB()); err != nil { + billingService := billing.NewBillingService(base.Db.Postgresql.DB()) + if err := billingService.DeleteBilling(billingID, userId); err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "billing not found", err.Error(), nil) c.JSON(http.StatusNotFound, rd) return @@ -97,7 +99,8 @@ func (base *Controller) DeleteBilling(c *gin.Context) { } func (base *Controller) GetBillings(c *gin.Context) { - billings_len, paginationResponse, err := billing.GetBillings(base.Db.Postgresql.DB(), c) + billingService := billing.NewBillingService(base.Db.Postgresql.DB()) + billings_len, paginationResponse, err := billingService.GetBillings(c) if err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "failed to fetch billings", err, nil) c.JSON(http.StatusNotFound, rd) @@ -125,7 +128,8 @@ func (base *Controller) GetBillingById(c *gin.Context) { return } - billing, err := billing.GetBillingById(billingID, base.Db.Postgresql.DB()) + billingService := billing.NewBillingService(base.Db.Postgresql.DB()) + billing, err := billingService.GetBillingById(billingID) if err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "billing not found", err.Error(), nil) @@ -167,7 +171,8 @@ func (base *Controller) UpdateBillingById(c *gin.Context) { } userId := userID.(string) - billing, err := billing.UpdateBillingById(billingID, userId, req, base.Db.Postgresql.DB()) + billingService := billing.NewBillingService(base.Db.Postgresql.DB()) + billing, err := billingService.UpdateBillingById(billingID, userId, req) if err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "billing not found", err.Error(), nil) diff --git a/services/billing/billing.go b/services/billing/billing.go index 81bacee..9edefcb 100644 --- a/services/billing/billing.go +++ b/services/billing/billing.go @@ -12,27 +12,43 @@ import ( "github.com/hngprojects/hng_boilerplate_golang_web/utility" ) -func CreateBilling(req models.CreateBillingRequest, db *gorm.DB, userId string) (models.BillingResponse, error) { - // instance of Postgresql db - pdb := inst.InitDB(db) +// BillingService defines the interface for billing operations. +type BillingService interface { + CreateBilling(req models.CreateBillingRequest, userId string) (models.BillingResponse, error) + DeleteBilling(BillingId string, userId string) error + GetBillings(c *gin.Context) (int, database.PaginationResponse, error) + GetBillingById(BillingId string) (models.Billing, error) + UpdateBillingById(BillingId string, userId string, req models.UpdateBillingRequest) (models.Billing, error) +} + +// BillingServiceImpl implements BillingService using GORM. +type BillingServiceImpl struct { + db database.DatabaseManager +} + +// NewBillingService creates a new instance of BillingService. +func NewBillingService(db *gorm.DB) BillingService { + return &BillingServiceImpl{db: inst.InitDB(db)} +} + +// CreateBilling creates a new billing record. +func (s *BillingServiceImpl) CreateBilling(req models.CreateBillingRequest, userId string) (models.BillingResponse, error) { var ( user models.User billingResp models.BillingResponse ) + Billing := models.Billing{ ID: utility.GenerateUUID(), Name: req.Name, Price: req.Price, } - err := Billing.Create(pdb) - - if err != nil { + if err := Billing.Create(s.db); err != nil { return billingResp, err } - user, err = user.GetUserByID(pdb, userId) - + user, err := user.GetUserByID(s.db, userId) if err != nil { return billingResp, err } @@ -42,75 +58,54 @@ func CreateBilling(req models.CreateBillingRequest, db *gorm.DB, userId string) Name: Billing.Name, Price: Billing.Price, CreatedAt: Billing.CreatedAt, - UpdatedAt: billingResp.UpdatedAt, + UpdatedAt: Billing.UpdatedAt, } return response, nil } -func DeleteBilling(BillingId string, userId string, db *gorm.DB) error { - // instance of Postgresql db - pdb := inst.InitDB(db) - +// DeleteBilling deletes a billing record by ID. +func (s *BillingServiceImpl) DeleteBilling(BillingId string, userId string) error { var Billing models.Billing - Billing, err := Billing.CheckBillingExists(BillingId, pdb) - + Billing, err := Billing.CheckBillingExists(BillingId, s.db) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return errors.New("Billing not found") + return errors.New("billing not found") } return err } - return Billing.Delete(pdb) + return Billing.Delete(s.db) } -func GetBillings(db *gorm.DB, c *gin.Context) (int, database.PaginationResponse, error) { - // instance of Postgresql db - pdb := inst.InitDB(db) - - var ( - Billing models.Billing - ) - Billings, paginationResponse, err := Billing.GetAllBillings(pdb, c) - +// GetBillings retrieves paginated billing records. +func (s *BillingServiceImpl) GetBillings(c *gin.Context) (int, database.PaginationResponse, error) { + var Billing models.Billing + Billings, paginationResponse, err := Billing.GetAllBillings(s.db, c) if err != nil { return 0, paginationResponse, err } - total_billings := len(Billings) - - return total_billings, paginationResponse, nil + totalBillings := len(Billings) + return totalBillings, paginationResponse, nil } -func GetBillingById(BillingId string, db *gorm.DB) (models.Billing, error) { - // instance of Postgresql db - pdb := inst.InitDB(db) - - var ( - resp models.Billing - ) - - resp, err := resp.GetBillingById(pdb, BillingId) - +// GetBillingById fetches a billing record by ID. +func (s *BillingServiceImpl) GetBillingById(BillingId string) (models.Billing, error) { + var resp models.Billing + resp, err := resp.GetBillingById(s.db, BillingId) if err != nil { return resp, err } - return resp, nil } -func UpdateBillingById(BillingId string, userId string, req models.UpdateBillingRequest, db *gorm.DB) (models.Billing, error) { - // instance of Postgresql db - pdb := inst.InitDB(db) - - var ( - resp models.Billing - ) - - resp, err := resp.CheckBillingExists(BillingId, pdb) +// UpdateBillingById updates a billing record by ID. +func (s *BillingServiceImpl) UpdateBillingById(BillingId string, userId string, req models.UpdateBillingRequest) (models.Billing, error) { + var resp models.Billing + resp, err := resp.CheckBillingExists(BillingId, s.db) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp, errors.New("billing not found") @@ -118,8 +113,7 @@ func UpdateBillingById(BillingId string, userId string, req models.UpdateBilling return resp, err } - _, err = resp.UpdateBillingById(pdb, req, BillingId) - + _, err = resp.UpdateBillingById(s.db, req, BillingId) if err != nil { return resp, err } From 807cfefe32d70cc8e22f6ed87434b968fddbcdf9 Mon Sep 17 00:00:00 2001 From: samuelIkoli Date: Sun, 2 Mar 2025 15:49:50 +0100 Subject: [PATCH 2/2] refactor: instantiated billing services in router and adjusted tests --- pkg/controller/billing/billing.go | 21 +++++++++++---------- pkg/router/billing.go | 4 +++- tests/test_billing/billing_test.go | 16 +++++++++++----- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/pkg/controller/billing/billing.go b/pkg/controller/billing/billing.go index 5f96a41..0befada 100644 --- a/pkg/controller/billing/billing.go +++ b/pkg/controller/billing/billing.go @@ -21,6 +21,7 @@ type Controller struct { Validator *validator.Validate Logger *utility.Logger ExtReq request.ExternalRequest + BillingService billing.BillingService } func (base *Controller) CreateBilling(c *gin.Context) { @@ -50,8 +51,8 @@ func (base *Controller) CreateBilling(c *gin.Context) { userClaims := claims.(jwt.MapClaims) userId := userClaims["user_id"].(string) - billingService := billing.NewBillingService(base.Db.Postgresql.DB()) - respData, err := billingService.CreateBilling(billingReq, userId) + + respData, err := base.BillingService.CreateBilling(billingReq, userId) if err != nil { rd := utility.BuildErrorResponse(http.StatusBadRequest, "error", err.Error(), err, nil) @@ -85,8 +86,8 @@ func (base *Controller) DeleteBilling(c *gin.Context) { userClaims := claims.(jwt.MapClaims) userId := userClaims["user_id"].(string) - billingService := billing.NewBillingService(base.Db.Postgresql.DB()) - if err := billingService.DeleteBilling(billingID, userId); err != nil { + + if err := base.BillingService.DeleteBilling(billingID, userId); err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "billing not found", err.Error(), nil) c.JSON(http.StatusNotFound, rd) return @@ -99,8 +100,8 @@ func (base *Controller) DeleteBilling(c *gin.Context) { } func (base *Controller) GetBillings(c *gin.Context) { - billingService := billing.NewBillingService(base.Db.Postgresql.DB()) - billings_len, paginationResponse, err := billingService.GetBillings(c) + + billings_len, paginationResponse, err := base.BillingService.GetBillings(c) if err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "failed to fetch billings", err, nil) c.JSON(http.StatusNotFound, rd) @@ -128,8 +129,8 @@ func (base *Controller) GetBillingById(c *gin.Context) { return } - billingService := billing.NewBillingService(base.Db.Postgresql.DB()) - billing, err := billingService.GetBillingById(billingID) + + billing, err := base.BillingService.GetBillingById(billingID) if err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "billing not found", err.Error(), nil) @@ -171,8 +172,8 @@ func (base *Controller) UpdateBillingById(c *gin.Context) { } userId := userID.(string) - billingService := billing.NewBillingService(base.Db.Postgresql.DB()) - billing, err := billingService.UpdateBillingById(billingID, userId, req) + + billing, err := base.BillingService.UpdateBillingById(billingID, userId, req) if err != nil { rd := utility.BuildErrorResponse(http.StatusNotFound, "error", "billing not found", err.Error(), nil) diff --git a/pkg/router/billing.go b/pkg/router/billing.go index 946e87d..7d687f8 100644 --- a/pkg/router/billing.go +++ b/pkg/router/billing.go @@ -9,12 +9,14 @@ import ( "github.com/hngprojects/hng_boilerplate_golang_web/external/request" "github.com/hngprojects/hng_boilerplate_golang_web/pkg/controller/billing" "github.com/hngprojects/hng_boilerplate_golang_web/pkg/repository/storage" + billingServices "github.com/hngprojects/hng_boilerplate_golang_web/services/billing" "github.com/hngprojects/hng_boilerplate_golang_web/utility" ) func Billing(r *gin.Engine, ApiVersion string, validator *validator.Validate, db *storage.Database, logger *utility.Logger) *gin.Engine { extReq := request.ExternalRequest{Logger: logger, Test: false} - billing := billing.Controller{Db: db, Validator: validator, Logger: logger, ExtReq: extReq} + billingService := billingServices.NewBillingService(db.Postgresql.DB()) + billing := billing.Controller{Db: db, Validator: validator, Logger: logger, ExtReq: extReq, BillingService: billingService} billingUrl := r.Group(fmt.Sprintf("%v", ApiVersion)) diff --git a/tests/test_billing/billing_test.go b/tests/test_billing/billing_test.go index 032561b..d3e310c 100644 --- a/tests/test_billing/billing_test.go +++ b/tests/test_billing/billing_test.go @@ -16,6 +16,7 @@ import ( "github.com/hngprojects/hng_boilerplate_golang_web/pkg/controller/billing" "github.com/hngprojects/hng_boilerplate_golang_web/pkg/middleware" "github.com/hngprojects/hng_boilerplate_golang_web/pkg/repository/storage" + billingServices "github.com/hngprojects/hng_boilerplate_golang_web/services/billing" tst "github.com/hngprojects/hng_boilerplate_golang_web/tests" "github.com/hngprojects/hng_boilerplate_golang_web/utility" ) @@ -28,7 +29,8 @@ func TestBillingCreate(t *testing.T) { db := storage.Connection() currUUID := utility.GenerateUUID() user := auth.Controller{Db: db, Validator: validatorRef, Logger: logger} - billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger} + billingService := billingServices.NewBillingService(db.Postgresql.DB()) + billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger, BillingService: billingService} r := gin.Default() _, token := Initialise(currUUID, t, r, db, user, billing, true) @@ -133,7 +135,8 @@ func TestBillingDelete(t *testing.T) { db := storage.Connection() currUUID := utility.GenerateUUID() user := auth.Controller{Db: db, Validator: validatorRef, Logger: logger} - billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger} + billingService := billingServices.NewBillingService(db.Postgresql.DB()) + billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger, BillingService: billingService } r := gin.Default() billingId, token := Initialise(currUUID, t, r, db, user, billing, true) @@ -242,7 +245,8 @@ func TestGetbillingById(t *testing.T) { db := storage.Connection() currUUID := utility.GenerateUUID() user := auth.Controller{Db: db, Validator: validatorRef, Logger: logger} - billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger} + billingService := billingServices.NewBillingService(db.Postgresql.DB()) + billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger, BillingService: billingService} r := gin.Default() billingId, _ := Initialise(currUUID, t, r, db, user, billing, true) @@ -333,7 +337,8 @@ func TestGetbillingplans(t *testing.T) { validatorRef := validator.New() db := storage.Connection() - billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger} + billingService := billingServices.NewBillingService(db.Postgresql.DB()) + billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger, BillingService: billingService} tests := []struct { Name string @@ -403,7 +408,8 @@ func TestEditbilling(t *testing.T) { db := storage.Connection() currUUID := utility.GenerateUUID() user := auth.Controller{Db: db, Validator: validatorRef, Logger: logger} - billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger} + billingService := billingServices.NewBillingService(db.Postgresql.DB()) + billing := billing.Controller{Db: db, Validator: validatorRef, Logger: logger, BillingService: billingService} r := gin.Default() billingId, token := Initialise(currUUID, t, r, db, user, billing, true)