From 6a1dffa75052dbc6a3fc1fdef7fcf3afd531e996 Mon Sep 17 00:00:00 2001 From: "aditya.siregar" Date: Fri, 2 Aug 2024 15:16:28 +0700 Subject: [PATCH] Add Daily Sales and Distributed Payment --- internal/entity/order.go | 5 +++ internal/handlers/http/order/order.go | 35 +++++++++++++++++++++ internal/handlers/response/order.go | 5 +++ internal/repository/orders/order.go | 44 ++++++++++++++++++++++++++- internal/repository/repository.go | 1 + internal/services/order/order.go | 11 +++++++ internal/services/service.go | 1 + 7 files changed, 101 insertions(+), 1 deletion(-) diff --git a/internal/entity/order.go b/internal/entity/order.go index fed75f4..6b14688 100644 --- a/internal/entity/order.go +++ b/internal/entity/order.go @@ -187,3 +187,8 @@ type ProductDailySales struct { PaymentType string Total float64 } + +type PaymentTypeDistribution struct { + PaymentType string + Count int +} diff --git a/internal/handlers/http/order/order.go b/internal/handlers/http/order/order.go index 51db59c..88549b3 100644 --- a/internal/handlers/http/order/order.go +++ b/internal/handlers/http/order/order.go @@ -26,6 +26,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route.GET("/ticket-sold", jwt, h.CountSoldOfTicket) route.GET("/sum-amount", jwt, h.SumAmount) route.GET("/daily-sales", jwt, h.GetDailySalesTicket) + route.GET("/payment-distribution", jwt, h.GetPaymentDistributionChart) } func NewHandler(service services.Order) *Handler { @@ -264,6 +265,29 @@ func (h *Handler) GetDailySalesTicket(c *gin.Context) { }) } +func (h *Handler) GetPaymentDistributionChart(c *gin.Context) { + var req request.OrderParam + if err := c.ShouldBindQuery(&req); err != nil { + response.ErrorWrapper(c, errors.ErrorBadRequest) + return + } + + ctx := request.GetMyContext(c) + + resp, err := h.service.GetPaymentDistribution(ctx, req.ToOrderEntity(ctx)) + + if err != nil { + response.ErrorWrapper(c, err) + return + } + + c.JSON(http.StatusOK, response.BaseResponse{ + Success: true, + Status: http.StatusOK, + Data: h.toPaymentDistributionChart(resp), + }) +} + func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.OrderParam) response.HistoryOrderList { var orders []response.HistoryOrder for _, b := range resp { @@ -291,3 +315,14 @@ func (h *Handler) toDailySales(resp []entity.ProductDailySales) []response.Produ } return dailySales } + +func (h *Handler) toPaymentDistributionChart(resp []entity.PaymentTypeDistribution) []response.PaymentDistribution { + var dailySales []response.PaymentDistribution + for _, b := range resp { + dailySales = append(dailySales, response.PaymentDistribution{ + PaymentType: b.PaymentType, + Count: b.Count, + }) + } + return dailySales +} diff --git a/internal/handlers/response/order.go b/internal/handlers/response/order.go index d4e558d..40b92f8 100644 --- a/internal/handlers/response/order.go +++ b/internal/handlers/response/order.go @@ -119,3 +119,8 @@ type ProductDailySales struct { PaymentType string `json:"payment_type"` Total float64 `json:"total"` } + +type PaymentDistribution struct { + PaymentType string `json:"payment_type"` + Count int `json:"count"` +} diff --git a/internal/repository/orders/order.go b/internal/repository/orders/order.go index 52765d2..70a1b21 100644 --- a/internal/repository/orders/order.go +++ b/internal/repository/orders/order.go @@ -227,7 +227,7 @@ func (r *OrderRepository) GetDailySalesMetrics(ctx context.Context, req entity.O // Build the query with GORM query := r.db.WithContext(ctx). Table("orders o"). - Select(`DATE_TRUNC(?, o.created_at) AS day, s.id AS site_id, s.name AS site_name, o.payment_type, SUM(oi.qty * oi.price) AS total_quantity`, dateTrunc). + Select(`DATE_TRUNC(?, o.created_at) AS day, s.id AS site_id, s.name AS site_name, o.payment_type, SUM(oi.qty * oi.price) AS total`, dateTrunc). Joins("JOIN order_items oi ON o.id = oi.order_id"). Joins("JOIN sites s ON o.site_id = s.id"). Where("o.status = ?", "PAID"). @@ -250,3 +250,45 @@ func (r *OrderRepository) GetDailySalesMetrics(ctx context.Context, req entity.O return sales, nil } + +func (r *OrderRepository) GetPaymentTypeDistribution(ctx context.Context, req entity.OrderSearch) ([]entity.PaymentTypeDistribution, error) { + var distribution []entity.PaymentTypeDistribution + + var periodFilter string + now := time.Now() + + switch req.Period { + case "1d": + periodFilter = now.Add(-24 * time.Hour).Format("2006-01-02 15:04:05") + case "7d": + periodFilter = now.Add(-7 * 24 * time.Hour).Format("2006-01-02 15:04:05") + case "1m": + periodFilter = now.AddDate(0, -1, 0).Format("2006-01-02 15:04:05") + case "1y": + periodFilter = now.AddDate(-1, 0, 0).Format("2006-01-02 15:04:05") + default: + periodFilter = now.AddDate(0, -1, 0).Format("2006-01-02 15:04:05") // Default to last month + } + + query := r.db.WithContext(ctx). + Table("orders o"). + Select("payment_type, COUNT(*) as count"). + Where("status = ?", "PAID"). + Where("o.created_at >= ?", periodFilter) + + if req.PartnerID != nil { + query = query.Where("o.partner_id = ?", *req.PartnerID) + } + + if req.SiteID != nil { + query = query.Where("o.site_id = ?", *req.SiteID) + } + + query = query.Group("payment_type") + + if err := query.Scan(&distribution).Error; err != nil { + return nil, err + } + + return distribution, nil +} diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 6e20a07..1d25a16 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -145,6 +145,7 @@ type Order interface { SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.OrderDB, error) CountSoldOfTicket(ctx mycontext.Context, req entity.OrderSearch) (*entity.TicketSoldDB, error) GetDailySalesMetrics(ctx context.Context, req entity.OrderSearch) ([]entity.ProductDailySales, error) + GetPaymentTypeDistribution(ctx context.Context, req entity.OrderSearch) ([]entity.PaymentTypeDistribution, error) } type OSSRepository interface { diff --git a/internal/services/order/order.go b/internal/services/order/order.go index f5135da..a5f03b4 100644 --- a/internal/services/order/order.go +++ b/internal/services/order/order.go @@ -335,6 +335,17 @@ func (s OrderService) GetDailySales(ctx mycontext.Context, req entity.OrderSearc return dailySales, nil } +func (s OrderService) GetPaymentDistribution(ctx mycontext.Context, req entity.OrderSearch) ([]entity.PaymentTypeDistribution, error) { + paymentDistribution, err := s.repo.GetPaymentTypeDistribution(ctx, req) + + if err != nil { + logger.ContextLogger(ctx).Error("error when get all history orders", zap.Error(err)) + return nil, err + } + + return paymentDistribution, nil +} + func (s OrderService) SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.Order, error) { amount, err := s.repo.SumAmount(ctx, req) diff --git a/internal/services/service.go b/internal/services/service.go index b1048b5..dea4fff 100644 --- a/internal/services/service.go +++ b/internal/services/service.go @@ -115,6 +115,7 @@ type Order interface { CountSoldOfTicket(ctx mycontext.Context, req entity.OrderSearch) (*entity.TicketSold, error) SumAmount(ctx mycontext.Context, req entity.OrderSearch) (*entity.Order, error) GetDailySales(ctx mycontext.Context, req entity.OrderSearch) ([]entity.ProductDailySales, error) + GetPaymentDistribution(ctx mycontext.Context, req entity.OrderSearch) ([]entity.PaymentTypeDistribution, error) } type OSSService interface {