From 4013b12ac9ad1352552976bdb21412c671f7cab1 Mon Sep 17 00:00:00 2001 From: ferdiansyah783 Date: Sat, 27 Jul 2024 15:26:00 +0700 Subject: [PATCH 1/2] feat: site count --- internal/entity/sites.go | 30 +++++++++++++++++++++++---- internal/handlers/http/sites/sites.go | 28 ++++++++++++++++++++++++- internal/handlers/request/site.go | 5 ++++- internal/handlers/response/site.go | 4 ++++ internal/repository/repository.go | 3 +++ internal/repository/sites/sites.go | 19 +++++++++++++++++ internal/services/service.go | 1 + internal/services/sites/sites.go | 10 +++++++++ 8 files changed, 94 insertions(+), 6 deletions(-) diff --git a/internal/entity/sites.go b/internal/entity/sites.go index f45941f..a2bbd52 100644 --- a/internal/entity/sites.go +++ b/internal/entity/sites.go @@ -28,10 +28,12 @@ type Site struct { } type SiteSearch struct { - Search string - Name string - Limit int - Offset int + PartnerID *int64 + IsAdmin bool + Search string + Name string + Limit int + Offset int } type SiteList []*SiteDB @@ -143,3 +145,23 @@ func (o *SiteDB) SetDeleted(updatedBy int64) { o.DeletedAt = ¤tTime o.UpdatedBy = updatedBy } + +type SiteCount struct { + Count int `gorm:"type:int;column:count"` +} + +type SiteCountDB struct { + SiteCount +} + +func (b *SiteCount) ToSiteCountDB() *SiteCountDB { + return &SiteCountDB{ + SiteCount: *b, + } +} + +func (e *SiteCountDB) ToSiteCount() *SiteCount { + return &SiteCount{ + Count: e.Count, + } +} diff --git a/internal/handlers/http/sites/sites.go b/internal/handlers/http/sites/sites.go index 10fcb46..5326dc5 100644 --- a/internal/handlers/http/sites/sites.go +++ b/internal/handlers/http/sites/sites.go @@ -26,6 +26,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route.PUT("/:id", jwt, h.Update) route.GET("/:id", jwt, h.GetByID) route.DELETE("/:id", jwt, h.Delete) + route.GET("/count", jwt, h.Count) } func NewHandler(service services.Site) *Handler { @@ -148,7 +149,8 @@ func (h *Handler) GetAll(c *gin.Context) { return } - Sites, total, err := h.service.GetAll(c.Request.Context(), req.ToEntity()) + ctx := request.GetMyContext(c) + Sites, total, err := h.service.GetAll(c.Request.Context(), req.ToEntity(ctx)) if err != nil { response.ErrorWrapper(c, err) return @@ -242,6 +244,30 @@ func (h *Handler) GetByID(c *gin.Context) { }) } +func (h *Handler) Count(c *gin.Context) { + var req request.SiteParam + if err := c.ShouldBindQuery(&req); err != nil { + response.ErrorWrapper(c, errors.ErrorBadRequest) + return + } + + ctx := request.GetMyContext(c) + res, err := h.service.Count(ctx, req.ToEntity(ctx)) + + if err != nil { + response.ErrorWrapper(c, err) + return + } + + c.JSON(http.StatusOK, response.BaseResponse{ + Success: true, + Status: http.StatusOK, + Data: response.SiteCount{ + Count: res.Count, + }, + }) +} + func (h *Handler) toSiteResponse(resp *entity.Site) response.Site { return response.Site{ ID: &resp.ID, diff --git a/internal/handlers/request/site.go b/internal/handlers/request/site.go index 10b11ff..557cd1a 100644 --- a/internal/handlers/request/site.go +++ b/internal/handlers/request/site.go @@ -1,6 +1,7 @@ package request import ( + "furtuna-be/internal/common/mycontext" "furtuna-be/internal/entity" ) @@ -65,8 +66,10 @@ type SiteParam struct { Offset int `form:"offset,default=0"` } -func (r *SiteParam) ToEntity() entity.SiteSearch { +func (r *SiteParam) ToEntity(ctx mycontext.Context) entity.SiteSearch { return entity.SiteSearch{ + PartnerID: ctx.GetPartnerID(), + IsAdmin: ctx.IsAdmin(), Search: r.Search, Name: r.Name, Limit: r.Limit, diff --git a/internal/handlers/response/site.go b/internal/handlers/response/site.go index 88a5284..aac6816 100644 --- a/internal/handlers/response/site.go +++ b/internal/handlers/response/site.go @@ -24,6 +24,10 @@ type SiteName struct { Name string `json:"name"` } +type SiteCount struct { + Count int `json:"count"` +} + type SiteList struct { Sites []Site `json:"sites"` Total int64 `json:"total"` diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 18ce638..85831b9 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -3,6 +3,7 @@ package repository import ( "context" "database/sql" + "furtuna-be/internal/common/mycontext" "furtuna-be/internal/repository/branches" "furtuna-be/internal/repository/brevo" mdtrns "furtuna-be/internal/repository/midtrans" @@ -16,6 +17,7 @@ import ( "furtuna-be/internal/repository/trx" "furtuna-be/internal/repository/users" repository "furtuna-be/internal/repository/wallet" + "github.com/golang-jwt/jwt" "gorm.io/gorm" @@ -154,6 +156,7 @@ type SiteRepository interface { GetByID(ctx context.Context, id int64) (*entity.SiteDB, error) GetAll(ctx context.Context, req entity.SiteSearch) (entity.SiteList, int, error) Delete(ctx context.Context, id int64) error + Count(ctx mycontext.Context, req entity.SiteSearch) (*entity.SiteCountDB, error) } type TransactionManager interface { diff --git a/internal/repository/sites/sites.go b/internal/repository/sites/sites.go index 83da564..c02b725 100644 --- a/internal/repository/sites/sites.go +++ b/internal/repository/sites/sites.go @@ -3,6 +3,7 @@ package sites import ( "context" "furtuna-be/internal/common/logger" + "furtuna-be/internal/common/mycontext" "furtuna-be/internal/entity" "go.uber.org/zap" @@ -129,3 +130,21 @@ func (r *SiteRepository) Delete(ctx context.Context, id int64) error { } return nil } + +func (r *SiteRepository) Count(ctx mycontext.Context, req entity.SiteSearch) (*entity.SiteCountDB, error) { + count := new(entity.SiteCountDB) + + query := r.db.Table("sites"). + Select("count(*) as count") + + if !req.IsAdmin { + query = query.Where("partner_id = ?", req.PartnerID) + } + + if err := query.Scan(&count).Error; err != nil { + logger.ContextLogger(ctx).Error("error when get count sites", zap.Error(err)) + return nil, err + } + + return count, nil +} diff --git a/internal/services/service.go b/internal/services/service.go index 539f519..0613010 100644 --- a/internal/services/service.go +++ b/internal/services/service.go @@ -122,4 +122,5 @@ type Site interface { GetByID(ctx context.Context, id int64) (*entity.Site, error) GetAll(ctx context.Context, search entity.SiteSearch) ([]*entity.Site, int, error) Delete(ctx mycontext.Context, id int64) error + Count(ctx mycontext.Context, req entity.SiteSearch) (*entity.SiteCount, error) } diff --git a/internal/services/sites/sites.go b/internal/services/sites/sites.go index e0d5f67..ca62133 100644 --- a/internal/services/sites/sites.go +++ b/internal/services/sites/sites.go @@ -87,3 +87,13 @@ func (s *SiteService) Delete(ctx mycontext.Context, id int64) error { return nil } + +func (s *SiteService) Count(ctx mycontext.Context, req entity.SiteSearch) (*entity.SiteCount, error) { + count, err := s.repo.Count(ctx, req) + if err != nil { + logger.ContextLogger(ctx).Error("error when getting all sites", zap.Error(err)) + return nil, err + } + + return count.ToSiteCount(), nil +} \ No newline at end of file From 30aa206d801b297a4428682a4aa206039884fa8f Mon Sep 17 00:00:00 2001 From: ferdiansyah783 Date: Sat, 27 Jul 2024 16:47:33 +0700 Subject: [PATCH 2/2] feat: amount transaction and count of item --- internal/entity/order.go | 47 +++++++++++++++++++--- internal/handlers/http/order/order.go | 58 +++++++++++++++++++++++++-- internal/handlers/http/sites/sites.go | 2 +- internal/handlers/request/order.go | 12 +++--- internal/handlers/response/order.go | 8 ++++ internal/repository/orders/order.go | 48 +++++++++++++++++++++- internal/repository/repository.go | 4 +- internal/services/order/order.go | 28 ++++++++++++- internal/services/service.go | 4 +- 9 files changed, 192 insertions(+), 19 deletions(-) diff --git a/internal/entity/order.go b/internal/entity/order.go index 462929f..b92112a 100644 --- a/internal/entity/order.go +++ b/internal/entity/order.go @@ -18,6 +18,22 @@ type Order struct { OrderItems []OrderItem `gorm:"foreignKey:OrderID;constraint:OnDelete:CASCADE;"` } +type OrderDB struct { + Order +} + +func (b *Order) ToOrderDB() *OrderDB { + return &OrderDB{ + Order: *b, + } +} + +func (e *OrderDB) ToSumAmount() *Order { + return &Order{ + Amount: e.Amount, + } +} + type OrderResponse struct { Order *Order Token string @@ -99,11 +115,12 @@ type HistoryOrderDB struct { HistoryOrder } -type HistoryOrderSearch struct { - PartnerID *int64 - IsAdmin bool - Limit int - Offset int +type OrderSearch struct { + PartnerID *int64 + IsAdmin bool + PaymentType string + Limit int + Offset int } type HistoryOrderList []*HistoryOrderDB @@ -136,3 +153,23 @@ func (b *HistoryOrderList) ToHistoryOrderList() []*HistoryOrder { } return HistoryOrders } + +type TicketSold struct { + Count int64 `gorm:"type:int;column:count"` +} + +type TicketSoldDB struct { + TicketSold +} + +func (b *TicketSold) ToTicketSoldDB() *TicketSoldDB { + return &TicketSoldDB{ + TicketSold: *b, + } +} + +func (e *TicketSoldDB) ToTicketSold() *TicketSold { + return &TicketSold{ + Count: e.Count, + } +} diff --git a/internal/handlers/http/order/order.go b/internal/handlers/http/order/order.go index 63c4f51..fe9255c 100644 --- a/internal/handlers/http/order/order.go +++ b/internal/handlers/http/order/order.go @@ -23,6 +23,8 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route.POST("/inquiry", jwt, h.Inquiry) route.POST("/execute", jwt, h.Execute) route.GET("/history", jwt, h.GetAllHistoryOrders) + route.GET("/ticket-sold", jwt, h.CountSoldOfTicket) + route.GET("/sum-amount", jwt, h.SumAmount) } func NewHandler(service services.Order) *Handler { @@ -169,15 +171,38 @@ func (h *Handler) toHistoryOrderResponse(resp *entity.HistoryOrder) response.His } } -func (h *Handler) GetAllHistoryOrders(c *gin.Context) { - var req request.HistoryOrderParam +func (h *Handler) SumAmount(c *gin.Context) { + var req request.OrderParam if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } ctx := request.GetMyContext(c) - orders, total, err := h.service.GetAllHistoryOrders(ctx, req.ToEntity(ctx)) + order, err := h.service.SumAmount(ctx, req.ToOrderEntity(ctx)) + if err != nil { + response.ErrorWrapper(c, err) + return + } + + c.JSON(http.StatusOK, response.BaseResponse{ + Success: true, + Status: http.StatusOK, + Data: response.OrderAmount{ + Amount: order.Amount, + }, + }) +} + +func (h *Handler) GetAllHistoryOrders(c *gin.Context) { + var req request.OrderParam + if err := c.ShouldBindQuery(&req); err != nil { + response.ErrorWrapper(c, errors.ErrorBadRequest) + return + } + + ctx := request.GetMyContext(c) + orders, total, err := h.service.GetAllHistoryOrders(ctx, req.ToOrderEntity(ctx)) if err != nil { response.ErrorWrapper(c, err) return @@ -190,7 +215,32 @@ func (h *Handler) GetAllHistoryOrders(c *gin.Context) { }) } -func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.HistoryOrderParam) response.HistoryOrderList { +func (h *Handler) CountSoldOfTicket(c *gin.Context) { + var req request.OrderParam + if err := c.ShouldBindQuery(&req); err != nil { + response.ErrorWrapper(c, errors.ErrorBadRequest) + return + } + + ctx := request.GetMyContext(c) + + res, err := h.service.CountSoldOfTicket(ctx, req.ToOrderEntity(ctx)) + + if err != nil { + response.ErrorWrapper(c, err) + return + } + + c.JSON(http.StatusOK, response.BaseResponse{ + Success: true, + Status: http.StatusOK, + Data: response.TicketSold{ + Count: res.Count, + }, + }) +} + +func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.OrderParam) response.HistoryOrderList { var orders []response.HistoryOrder for _, b := range resp { orders = append(orders, h.toHistoryOrderResponse(b)) diff --git a/internal/handlers/http/sites/sites.go b/internal/handlers/http/sites/sites.go index 5326dc5..d23a70c 100644 --- a/internal/handlers/http/sites/sites.go +++ b/internal/handlers/http/sites/sites.go @@ -261,7 +261,7 @@ func (h *Handler) Count(c *gin.Context) { c.JSON(http.StatusOK, response.BaseResponse{ Success: true, - Status: http.StatusOK, + Status: http.StatusOK, Data: response.SiteCount{ Count: res.Count, }, diff --git a/internal/handlers/request/order.go b/internal/handlers/request/order.go index 0183119..326d521 100644 --- a/internal/handlers/request/order.go +++ b/internal/handlers/request/order.go @@ -12,15 +12,17 @@ type Order struct { OrderItems []OrderItem `json:"order_items" validate:"required"` } -type HistoryOrderParam struct { - Limit int `form:"limit" json:"limit" example:"10"` - Offset int `form:"offset" json:"offset" example:"0"` +type OrderParam struct { + PaymentType string `form:"payment_type" json:"payment_type" example:"CASH"` + Limit int `form:"limit" json:"limit" example:"10"` + Offset int `form:"offset" json:"offset" example:"0"` } -func (o *HistoryOrderParam) ToEntity(ctx mycontext.Context) entity.HistoryOrderSearch { - return entity.HistoryOrderSearch{ +func (o *OrderParam) ToOrderEntity(ctx mycontext.Context) entity.OrderSearch { + return entity.OrderSearch{ PartnerID: ctx.GetPartnerID(), IsAdmin: ctx.IsAdmin(), + PaymentType: o.PaymentType, Limit: o.Limit, Offset: o.Offset, } diff --git a/internal/handlers/response/order.go b/internal/handlers/response/order.go index 940bd7d..eb3ce98 100644 --- a/internal/handlers/response/order.go +++ b/internal/handlers/response/order.go @@ -21,6 +21,10 @@ type Order struct { UpdatedAt string `json:"updated_at"` } +type OrderAmount struct { + Amount float64 `json:"amount"` +} + type HistoryOrder struct { ID int64 `json:"id"` Employee string `json:"employee"` @@ -58,6 +62,10 @@ type HistoryOrderList struct { Offset int `json:"offset"` } +type TicketSold struct { + Count int64 `json:"count"` +} + type OrderMonthlyRevenue struct { TotalRevenue float64 `json:"total_revenue"` TotalTransaction int64 `json:"total_transaction"` diff --git a/internal/repository/orders/order.go b/internal/repository/orders/order.go index d58c206..ce92f00 100644 --- a/internal/repository/orders/order.go +++ b/internal/repository/orders/order.go @@ -3,8 +3,10 @@ package orders import ( "context" "furtuna-be/internal/common/logger" + "furtuna-be/internal/common/mycontext" "furtuna-be/internal/entity" "strings" + "time" "go.uber.org/zap" "gorm.io/gorm" @@ -83,7 +85,7 @@ func (r *OrderRepository) Update(ctx context.Context, order *entity.Order) (*ent return order, nil } -func (b *OrderRepository) GetAllHystoryOrders(ctx context.Context, req entity.HistoryOrderSearch) (entity.HistoryOrderList, int, error) { +func (b *OrderRepository) GetAllHystoryOrders(ctx context.Context, req entity.OrderSearch) (entity.HistoryOrderList, int, error) { var orders []*entity.HistoryOrderDB var total int64 @@ -128,3 +130,47 @@ func (b *OrderRepository) GetAllHystoryOrders(ctx context.Context, req entity.Hi return orders, int(total), nil } + +func (r *OrderRepository) CountSoldOfTicket(ctx mycontext.Context, req entity.OrderSearch) (*entity.TicketSoldDB, error) { + today := time.Now().Format("2006-01-02") + ticketCount := new(entity.TicketSoldDB) + + query := r.db.Table("orders"). + Select("sum(items.qty) as count"). + Joins("left join order_items items on orders.id = items.order_id"). + Where("orders.status = ?", "PAID"). + Where("orders.created_at = ?", today) + + if !req.IsAdmin { + query = query.Where("orders.partner_id = ?", req.PartnerID) + } + + if err := query.Scan(&ticketCount).Error; err != nil { + logger.ContextLogger(ctx).Error("error when get count ticket", zap.Error(err)) + return nil, err + } + + return ticketCount, nil +} + +func (r *OrderRepository) SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.OrderDB, error) { + amount := new(entity.OrderDB) + today := time.Now().Format("2006-01-02") + + query := r.db.Table("orders"). + Select("sum(amount) as amount"). + Where("payment_type = ?", req.PaymentType). + Where("date(created_at) = ?", today). + Where("status = ?", "PAID") + + if !req.IsAdmin { + query = query.Where("orders.partner_id = ?", req.PartnerID) + } + + if err := query.Scan(&amount).Error; err != nil { + logger.ContextLogger(ctx).Error("error when get cash amount", zap.Error(err)) + return nil, err + } + + return amount, nil +} diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 85831b9..5797aea 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -132,7 +132,9 @@ type Order interface { FindByID(ctx context.Context, id int64) (*entity.Order, error) Update(ctx context.Context, order *entity.Order) (*entity.Order, error) SetOrderStatus(ctx context.Context, db *gorm.DB, orderID int64, status string) error - GetAllHystoryOrders(ctx context.Context, req entity.HistoryOrderSearch) (entity.HistoryOrderList, int, error) + GetAllHystoryOrders(ctx context.Context, req entity.OrderSearch) (entity.HistoryOrderList, int, error) + SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.OrderDB, error) + CountSoldOfTicket(ctx mycontext.Context, req entity.OrderSearch) (*entity.TicketSoldDB, error) } type OSSRepository interface { diff --git a/internal/services/order/order.go b/internal/services/order/order.go index 1ca88d8..c85f440 100644 --- a/internal/services/order/order.go +++ b/internal/services/order/order.go @@ -298,7 +298,7 @@ func (s *OrderService) updateWalletBalance(ctx context.Context, tx *gorm.DB, par return err } -func (s *OrderService) GetAllHistoryOrders(ctx mycontext.Context, req entity.HistoryOrderSearch) ([]*entity.HistoryOrder, int, error) { +func (s *OrderService) GetAllHistoryOrders(ctx mycontext.Context, req entity.OrderSearch) ([]*entity.HistoryOrder, int, error) { historyOrders, total, err := s.repo.GetAllHystoryOrders(ctx, req) if err != nil { logger.ContextLogger(ctx).Error("error when get all history orders", zap.Error(err)) @@ -309,3 +309,29 @@ func (s *OrderService) GetAllHistoryOrders(ctx mycontext.Context, req entity.His return data, total, nil } + +func (s OrderService) CountSoldOfTicket(ctx mycontext.Context, req entity.OrderSearch) (*entity.TicketSold, error) { + ticket, err := s.repo.CountSoldOfTicket(ctx, req) + + if err != nil { + logger.ContextLogger(ctx).Error("error when get all history orders", zap.Error(err)) + return nil, err + } + + data := ticket.ToTicketSold() + + return data, nil +} + +func (s OrderService) SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.Order, error) { + amount, err := s.repo.SumAmount(ctx, req) + + if err != nil { + logger.ContextLogger(ctx).Error("error when get amount cash orders", zap.Error(err)) + return nil, err + } + + data := amount.ToSumAmount() + + return data, nil +} \ No newline at end of file diff --git a/internal/services/service.go b/internal/services/service.go index 0613010..1dc54e7 100644 --- a/internal/services/service.go +++ b/internal/services/service.go @@ -101,7 +101,9 @@ type Order interface { CreateOrder(ctx context.Context, req *entity.OrderRequest) (*entity.OrderResponse, error) Execute(ctx context.Context, req *entity.OrderExecuteRequest) (*entity.ExecuteOrderResponse, error) ProcessCallback(ctx context.Context, req *entity.CallbackRequest) error - GetAllHistoryOrders(ctx mycontext.Context, req entity.HistoryOrderSearch) ([]*entity.HistoryOrder, int, error) + GetAllHistoryOrders(ctx mycontext.Context, req entity.OrderSearch) ([]*entity.HistoryOrder, int, error) + CountSoldOfTicket(ctx mycontext.Context, req entity.OrderSearch) (*entity.TicketSold, error) + SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.Order, error) } type OSSService interface {