From 0c331dce6a7e25086331e8940ec4d4f5439a5c98 Mon Sep 17 00:00:00 2001 From: efrilm Date: Tue, 25 Nov 2025 13:23:59 +0700 Subject: [PATCH] update product analytic if exiest order --- internal/repository/analytics_repository.go | 46 ++++++--------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/internal/repository/analytics_repository.go b/internal/repository/analytics_repository.go index e6403ea..6016aa8 100644 --- a/internal/repository/analytics_repository.go +++ b/internal/repository/analytics_repository.go @@ -110,56 +110,36 @@ func (r *AnalyticsRepositoryImpl) GetSalesAnalytics(ctx context.Context, organiz func (r *AnalyticsRepositoryImpl) GetProductAnalytics(ctx context.Context, organizationID uuid.UUID, outletID *uuid.UUID, dateFrom, dateTo time.Time, limit int) ([]*entities.ProductAnalytics, error) { var results []*entities.ProductAnalytics - // Subquery untuk menghitung analytics dari orders - salesSubquery := r.db.Table("order_items oi"). + query := r.db.WithContext(ctx). + Table("order_items oi"). Select(` p.id as product_id, - COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.quantity - COALESCE(oi.refund_quantity, 0) ELSE 0 END), 0) as quantity_sold, - COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.total_price - COALESCE(oi.refund_amount, 0) ELSE 0 END), 0) as revenue, + p.name as product_name, + c.id as category_id, + c.name as category_name, + c.order as category_order, + COALESCE(SUM(oi.quantity), 0) as quantity_sold, + COALESCE(SUM(oi.total_price), 0) as revenue, CASE - WHEN SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.quantity - COALESCE(oi.refund_quantity, 0) ELSE 0 END) > 0 - THEN COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.total_price - COALESCE(oi.refund_amount, 0) ELSE 0 END), 0) / SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.quantity - COALESCE(oi.refund_quantity, 0) ELSE 0 END) + WHEN SUM(oi.quantity) > 0 THEN COALESCE(SUM(oi.total_price), 0) / SUM(oi.quantity) ELSE 0 END as average_price, COUNT(DISTINCT oi.order_id) as order_count `). Joins("JOIN products p ON oi.product_id = p.id"). + Joins("JOIN categories c ON p.category_id = c.id"). Joins("JOIN orders o ON oi.order_id = o.id"). Where("o.organization_id = ?", organizationID). Where("o.is_void = ?", false). - Where("o.is_refund = ?", false). - Where("o.payment_status = ?", entities.PaymentStatusCompleted). - Where("oi.status != ?", entities.OrderItemStatusCancelled). Where("o.created_at >= ? AND o.created_at <= ?", dateFrom, dateTo) if outletID != nil { - salesSubquery = salesSubquery.Where("o.outlet_id = ?", *outletID) + query = query.Where("o.outlet_id = ?", *outletID) } - salesSubquery = salesSubquery.Group("p.id") - - // Main query: ambil semua products dan LEFT JOIN dengan sales subquery - query := r.db.WithContext(ctx). - Table("products p"). - Select(` - p.id as product_id, - p.name as product_name, - p.sku as product_sku, - c.id as category_id, - c.name as category_name, - c.order as category_order, - COALESCE(sales.quantity_sold, 0) as quantity_sold, - COALESCE(sales.revenue, 0) as revenue, - COALESCE(sales.average_price, 0) as average_price, - COALESCE(sales.order_count, 0) as order_count - `). - Joins("JOIN categories c ON p.category_id = c.id"). - Joins("LEFT JOIN (?) as sales ON sales.product_id = p.id", salesSubquery). - Where("p.organization_id = ?", organizationID) - err := query. - Group("p.id, p.name, p.sku, c.id, c.name, c.order, sales.quantity_sold, sales.revenue, sales.average_price, sales.order_count"). - Order("COALESCE(sales.revenue, 0) DESC, p.name ASC"). + Group("p.id, p.name, c.id, c.name, c.order"). + Order("revenue DESC"). Limit(limit). Scan(&results).Error