From 4e4d9d3a9082ff8d4c2ddadb6c9b01bbd3d59ee0 Mon Sep 17 00:00:00 2001 From: "aditya.siregar" Date: Fri, 2 Aug 2024 02:27:57 +0700 Subject: [PATCH] Add Daily sales --- internal/entity/order.go | 6 +++++ internal/handlers/http/order/order.go | 36 +++++++++++++++++++++++++++ internal/handlers/response/order.go | 6 +++++ internal/repository/orders/order.go | 29 +++++++++++++++++++++ internal/repository/repository.go | 1 + internal/services/order/order.go | 11 ++++++++ internal/services/service.go | 1 + 7 files changed, 90 insertions(+) diff --git a/internal/entity/order.go b/internal/entity/order.go index 6e20bf3..ff945d6 100644 --- a/internal/entity/order.go +++ b/internal/entity/order.go @@ -178,3 +178,9 @@ func (e *TicketSoldDB) ToTicketSold() *TicketSold { Count: e.Count, } } + +type ProductDailySales struct { + Day time.Time + ProductID int64 + TotalQuantity int +} diff --git a/internal/handlers/http/order/order.go b/internal/handlers/http/order/order.go index fe9255c..a29a25c 100644 --- a/internal/handlers/http/order/order.go +++ b/internal/handlers/http/order/order.go @@ -25,6 +25,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route.GET("/history", jwt, h.GetAllHistoryOrders) route.GET("/ticket-sold", jwt, h.CountSoldOfTicket) route.GET("/sum-amount", jwt, h.SumAmount) + route.GET("/daily-sales", jwt, h.GetDailySalesTicket) } func NewHandler(service services.Order) *Handler { @@ -240,6 +241,29 @@ func (h *Handler) CountSoldOfTicket(c *gin.Context) { }) } +func (h *Handler) GetDailySalesTicket(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.GetDailySales(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.toDailySales(resp), + }) +} + func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.OrderParam) response.HistoryOrderList { var orders []response.HistoryOrder for _, b := range resp { @@ -253,3 +277,15 @@ func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, r Offset: req.Offset, } } + +func (h *Handler) toDailySales(resp []entity.ProductDailySales) []response.ProductDailySales { + var dailySales []response.ProductDailySales + for _, b := range resp { + dailySales = append(dailySales, response.ProductDailySales{ + Day: b.Day, + ProductID: b.ProductID, + TotalQuantity: b.TotalQuantity, + }) + } + return dailySales +} diff --git a/internal/handlers/response/order.go b/internal/handlers/response/order.go index eb3ce98..b2520a6 100644 --- a/internal/handlers/response/order.go +++ b/internal/handlers/response/order.go @@ -111,3 +111,9 @@ type CreateOrderItemResponse struct { Price float64 `json:"price"` Name string `json:"name"` } + +type ProductDailySales struct { + Day time.Time + ProductID int64 + TotalQuantity int +} diff --git a/internal/repository/orders/order.go b/internal/repository/orders/order.go index ac48c9b..2c6c49c 100644 --- a/internal/repository/orders/order.go +++ b/internal/repository/orders/order.go @@ -199,3 +199,32 @@ func (r *OrderRepository) SumAmount(ctx mycontext.Context, req entity.OrderSearc return amount, nil } + +func (r *OrderRepository) GetDailySalesMetrics(ctx context.Context, req entity.OrderSearch) ([]entity.ProductDailySales, error) { + var sales []entity.ProductDailySales + + // Build the query with GORM + query := r.db.WithContext(ctx). + Table("orders o"). + Select(`DATE_TRUNC('day', o.created_at) AS day, oi.item_id, SUM(oi.qty) AS total_quantity`). + Joins("LEFT JOIN order_items oi ON o.id = oi.order_id"). + Where("o.status = ?", "PAID"). + Where("o.created_at >= ?", time.Now().AddDate(0, 0, -30)). // Last 30 days + Group("day, oi.item_id"). + Order("day") + + // Apply filters based on the presence of PartnerID and SiteID + if req.PartnerID != nil { + query = query.Where("o.partner_id = ?", *req.PartnerID) + } + if req.SiteID != nil { + query = query.Where("o.site_id = ?", *req.SiteID) + } + + // Execute the query and scan the results + if err := query.Find(&sales).Error; err != nil { + return nil, err + } + + return sales, nil +} diff --git a/internal/repository/repository.go b/internal/repository/repository.go index e5fcedd..6e20a07 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -144,6 +144,7 @@ type Order interface { 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) + GetDailySalesMetrics(ctx context.Context, req entity.OrderSearch) ([]entity.ProductDailySales, error) } type OSSRepository interface { diff --git a/internal/services/order/order.go b/internal/services/order/order.go index 3728f25..f5135da 100644 --- a/internal/services/order/order.go +++ b/internal/services/order/order.go @@ -324,6 +324,17 @@ func (s OrderService) CountSoldOfTicket(ctx mycontext.Context, req entity.OrderS return data, nil } +func (s OrderService) GetDailySales(ctx mycontext.Context, req entity.OrderSearch) ([]entity.ProductDailySales, error) { + dailySales, err := s.repo.GetDailySalesMetrics(ctx, req) + + if err != nil { + logger.ContextLogger(ctx).Error("error when get all history orders", zap.Error(err)) + return nil, err + } + + return dailySales, 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 c3ea03a..b1048b5 100644 --- a/internal/services/service.go +++ b/internal/services/service.go @@ -114,6 +114,7 @@ type Order interface { 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) + GetDailySales(ctx mycontext.Context, req entity.OrderSearch) ([]entity.ProductDailySales, error) } type OSSService interface {