diff --git a/internal/contract/analytics_contract.go b/internal/contract/analytics_contract.go index c97edd4..8e32a64 100644 --- a/internal/contract/analytics_contract.go +++ b/internal/contract/analytics_contract.go @@ -101,18 +101,23 @@ type ProductAnalyticsResponse struct { Data []ProductAnalyticsData `json:"data"` } -// ProductAnalyticsData represents individual product analytics data type ProductAnalyticsData struct { - ProductID uuid.UUID `json:"product_id"` - ProductName string `json:"product_name"` - ProductSku string `json:"product_sku"` - CategoryID uuid.UUID `json:"category_id"` - CategoryName string `json:"category_name"` - CategoryOrder int `json:"category_order"` - QuantitySold int64 `json:"quantity_sold"` - Revenue float64 `json:"revenue"` - AveragePrice float64 `json:"average_price"` - OrderCount int64 `json:"order_count"` + ProductID uuid.UUID `json:"product_id"` + ProductName string `json:"product_name"` + ProductSku string `json:"product_sku"` + CategoryID uuid.UUID `json:"category_id"` + CategoryName string `json:"category_name"` + CategoryOrder int `json:"category_order"` + QuantitySold int64 `json:"quantity_sold"` + Revenue float64 `json:"revenue"` + AveragePrice float64 `json:"average_price"` + OrderCount int64 `json:"order_count"` + StandardHppPerUnit float64 `json:"standard_hpp_per_unit"` + StandardHppTotal float64 `json:"standard_hpp_total"` + FifoHppPerUnit float64 `json:"fifo_hpp_per_unit"` + FifoHppTotal float64 `json:"fifo_hpp_total"` + MovingAverageHppPerUnit float64 `json:"moving_average_hpp_per_unit"` + MovingAverageHppTotal float64 `json:"moving_average_hpp_total"` } // ProductAnalyticsPerCategoryRequest represents the request for product analytics per category @@ -125,21 +130,23 @@ type ProductAnalyticsPerCategoryRequest struct { // ProductAnalyticsPerCategoryResponse represents the response for product analytics per category type ProductAnalyticsPerCategoryResponse struct { - OrganizationID uuid.UUID `json:"organization_id"` - OutletID *uuid.UUID `json:"outlet_id,omitempty"` - DateFrom time.Time `json:"date_from"` - DateTo time.Time `json:"date_to"` - Data []ProductAnalyticsPerCategoryData `json:"data"` + OrganizationID uuid.UUID `json:"organization_id"` + OutletID *uuid.UUID `json:"outlet_id,omitempty"` + DateFrom time.Time `json:"date_from"` + DateTo time.Time `json:"date_to"` + Data []ProductAnalyticsPerCategoryData `json:"data"` } -// ProductAnalyticsPerCategoryData represents individual category analytics data type ProductAnalyticsPerCategoryData struct { - CategoryID uuid.UUID `json:"category_id"` - CategoryName string `json:"category_name"` - TotalRevenue float64 `json:"total_revenue"` - TotalQuantity int64 `json:"total_quantity"` - ProductCount int64 `json:"product_count"` - OrderCount int64 `json:"order_count"` + CategoryID uuid.UUID `json:"category_id"` + CategoryName string `json:"category_name"` + TotalRevenue float64 `json:"total_revenue"` + TotalQuantity int64 `json:"total_quantity"` + ProductCount int64 `json:"product_count"` + OrderCount int64 `json:"order_count"` + TotalStandardHpp float64 `json:"total_standard_hpp"` + TotalFifoHpp float64 `json:"total_fifo_hpp"` + TotalMovingAverageHpp float64 `json:"total_moving_average_hpp"` } // DashboardAnalyticsRequest represents the request for dashboard analytics diff --git a/internal/contract/order_contract.go b/internal/contract/order_contract.go index 59fa1ae..028dfc4 100644 --- a/internal/contract/order_contract.go +++ b/internal/contract/order_contract.go @@ -185,7 +185,7 @@ type CreatePaymentRequest struct { type CreatePaymentOrderItemRequest struct { OrderItemID uuid.UUID `json:"order_item_id" validate:"required"` - Amount float64 `json:"amount" validate:"required,min=0"` + Amount float64 `json:"amount" validate:"min=0"` } type PaymentResponse struct { diff --git a/internal/entities/analytics.go b/internal/entities/analytics.go index 10ae208..5fae6fe 100644 --- a/internal/entities/analytics.go +++ b/internal/entities/analytics.go @@ -27,28 +27,35 @@ type SalesAnalytics struct { NetSales float64 `json:"net_sales"` } -// ProductAnalytics represents product analytics data type ProductAnalytics struct { - ProductID uuid.UUID `json:"product_id"` - ProductName string `json:"product_name"` - ProductSku string `json:"product_sku"` - CategoryID uuid.UUID `json:"category_id"` - CategoryName string `json:"category_name"` - CategoryOrder int `json:"category_order"` - QuantitySold int64 `json:"quantity_sold"` - Revenue float64 `json:"revenue"` - AveragePrice float64 `json:"average_price"` - OrderCount int64 `json:"order_count"` + ProductID uuid.UUID `json:"product_id"` + ProductName string `json:"product_name"` + ProductSku string `json:"product_sku"` + CategoryID uuid.UUID `json:"category_id"` + CategoryName string `json:"category_name"` + CategoryOrder int `json:"category_order"` + QuantitySold int64 `json:"quantity_sold"` + Revenue float64 `json:"revenue"` + AveragePrice float64 `json:"average_price"` + OrderCount int64 `json:"order_count"` + StandardHppPerUnit float64 `json:"standard_hpp_per_unit"` + StandardHppTotal float64 `json:"standard_hpp_total"` + FifoHppPerUnit float64 `json:"fifo_hpp_per_unit"` + FifoHppTotal float64 `json:"fifo_hpp_total"` + MovingAverageHppPerUnit float64 `json:"moving_average_hpp_per_unit"` + MovingAverageHppTotal float64 `json:"moving_average_hpp_total"` } -// ProductAnalyticsPerCategory represents product analytics data grouped by category type ProductAnalyticsPerCategory struct { - CategoryID uuid.UUID `json:"category_id"` - CategoryName string `json:"category_name"` - TotalRevenue float64 `json:"total_revenue"` - TotalQuantity int64 `json:"total_quantity"` - ProductCount int64 `json:"product_count"` - OrderCount int64 `json:"order_count"` + CategoryID uuid.UUID `json:"category_id"` + CategoryName string `json:"category_name"` + TotalRevenue float64 `json:"total_revenue"` + TotalQuantity int64 `json:"total_quantity"` + ProductCount int64 `json:"product_count"` + OrderCount int64 `json:"order_count"` + TotalStandardHpp float64 `json:"total_standard_hpp"` + TotalFifoHpp float64 `json:"total_fifo_hpp"` + TotalMovingAverageHpp float64 `json:"total_moving_average_hpp"` } // DashboardOverview represents dashboard overview data diff --git a/internal/models/analytics.go b/internal/models/analytics.go index 1e41e4e..59b8445 100644 --- a/internal/models/analytics.go +++ b/internal/models/analytics.go @@ -105,18 +105,23 @@ type ProductAnalyticsResponse struct { Data []ProductAnalyticsData `json:"data"` } -// ProductAnalyticsData represents individual product analytics data type ProductAnalyticsData struct { - ProductID uuid.UUID `json:"product_id"` - ProductName string `json:"product_name"` - ProductSku string `json:"product_sku"` - CategoryID uuid.UUID `json:"category_id"` - CategoryName string `json:"category_name"` - CategoryOrder int `json:"category_order"` - QuantitySold int64 `json:"quantity_sold"` - Revenue float64 `json:"revenue"` - AveragePrice float64 `json:"average_price"` - OrderCount int64 `json:"order_count"` + ProductID uuid.UUID `json:"product_id"` + ProductName string `json:"product_name"` + ProductSku string `json:"product_sku"` + CategoryID uuid.UUID `json:"category_id"` + CategoryName string `json:"category_name"` + CategoryOrder int `json:"category_order"` + QuantitySold int64 `json:"quantity_sold"` + Revenue float64 `json:"revenue"` + AveragePrice float64 `json:"average_price"` + OrderCount int64 `json:"order_count"` + StandardHppPerUnit float64 `json:"standard_hpp_per_unit"` + StandardHppTotal float64 `json:"standard_hpp_total"` + FifoHppPerUnit float64 `json:"fifo_hpp_per_unit"` + FifoHppTotal float64 `json:"fifo_hpp_total"` + MovingAverageHppPerUnit float64 `json:"moving_average_hpp_per_unit"` + MovingAverageHppTotal float64 `json:"moving_average_hpp_total"` } // ProductAnalyticsPerCategoryRequest represents the request for product analytics per category @@ -129,21 +134,23 @@ type ProductAnalyticsPerCategoryRequest struct { // ProductAnalyticsPerCategoryResponse represents the response for product analytics per category type ProductAnalyticsPerCategoryResponse struct { - OrganizationID uuid.UUID `json:"organization_id"` - OutletID *uuid.UUID `json:"outlet_id,omitempty"` - DateFrom time.Time `json:"date_from"` - DateTo time.Time `json:"date_to"` - Data []ProductAnalyticsPerCategoryData `json:"data"` + OrganizationID uuid.UUID `json:"organization_id"` + OutletID *uuid.UUID `json:"outlet_id,omitempty"` + DateFrom time.Time `json:"date_from"` + DateTo time.Time `json:"date_to"` + Data []ProductAnalyticsPerCategoryData `json:"data"` } -// ProductAnalyticsPerCategoryData represents individual category analytics data type ProductAnalyticsPerCategoryData struct { - CategoryID uuid.UUID `json:"category_id"` - CategoryName string `json:"category_name"` - TotalRevenue float64 `json:"total_revenue"` - TotalQuantity int64 `json:"total_quantity"` - ProductCount int64 `json:"product_count"` - OrderCount int64 `json:"order_count"` + CategoryID uuid.UUID `json:"category_id"` + CategoryName string `json:"category_name"` + TotalRevenue float64 `json:"total_revenue"` + TotalQuantity int64 `json:"total_quantity"` + ProductCount int64 `json:"product_count"` + OrderCount int64 `json:"order_count"` + TotalStandardHpp float64 `json:"total_standard_hpp"` + TotalFifoHpp float64 `json:"total_fifo_hpp"` + TotalMovingAverageHpp float64 `json:"total_moving_average_hpp"` } // DashboardAnalyticsRequest represents the request for dashboard analytics diff --git a/internal/processor/analytics_processor.go b/internal/processor/analytics_processor.go index d35ac8d..bef2ca7 100644 --- a/internal/processor/analytics_processor.go +++ b/internal/processor/analytics_processor.go @@ -185,16 +185,22 @@ func (p *AnalyticsProcessorImpl) GetProductAnalytics(ctx context.Context, req *m var resultData []models.ProductAnalyticsData for _, data := range analyticsData { resultData = append(resultData, models.ProductAnalyticsData{ - ProductID: data.ProductID, - ProductName: data.ProductName, - ProductSku: data.ProductSku, - CategoryID: data.CategoryID, - CategoryName: data.CategoryName, - CategoryOrder: data.CategoryOrder, - QuantitySold: data.QuantitySold, - Revenue: data.Revenue, - AveragePrice: data.AveragePrice, - OrderCount: data.OrderCount, + ProductID: data.ProductID, + ProductName: data.ProductName, + ProductSku: data.ProductSku, + CategoryID: data.CategoryID, + CategoryName: data.CategoryName, + CategoryOrder: data.CategoryOrder, + QuantitySold: data.QuantitySold, + Revenue: data.Revenue, + AveragePrice: data.AveragePrice, + OrderCount: data.OrderCount, + StandardHppPerUnit: data.StandardHppPerUnit, + StandardHppTotal: data.StandardHppTotal, + FifoHppPerUnit: data.FifoHppPerUnit, + FifoHppTotal: data.FifoHppTotal, + MovingAverageHppPerUnit: data.MovingAverageHppPerUnit, + MovingAverageHppTotal: data.MovingAverageHppTotal, }) } @@ -223,12 +229,15 @@ func (p *AnalyticsProcessorImpl) GetProductAnalyticsPerCategory(ctx context.Cont var resultData []models.ProductAnalyticsPerCategoryData for _, data := range analyticsData { resultData = append(resultData, models.ProductAnalyticsPerCategoryData{ - CategoryID: data.CategoryID, - CategoryName: data.CategoryName, - TotalRevenue: data.TotalRevenue, - TotalQuantity: data.TotalQuantity, - ProductCount: data.ProductCount, - OrderCount: data.OrderCount, + CategoryID: data.CategoryID, + CategoryName: data.CategoryName, + TotalRevenue: data.TotalRevenue, + TotalQuantity: data.TotalQuantity, + ProductCount: data.ProductCount, + OrderCount: data.OrderCount, + TotalStandardHpp: data.TotalStandardHpp, + TotalFifoHpp: data.TotalFifoHpp, + TotalMovingAverageHpp: data.TotalMovingAverageHpp, }) } diff --git a/internal/repository/analytics_repository.go b/internal/repository/analytics_repository.go index 1d06549..0ee622e 100644 --- a/internal/repository/analytics_repository.go +++ b/internal/repository/analytics_repository.go @@ -124,11 +124,45 @@ func (r *AnalyticsRepositoryImpl) GetProductAnalytics(ctx context.Context, organ 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 + COUNT(DISTINCT oi.order_id) as order_count, + COALESCE(( + SELECT SUM(pr.quantity * (1 + COALESCE(pr.waste_percentage, 0)/100.0) * i.cost) + FROM product_recipes pr + JOIN ingredients i ON pr.ingredient_id = i.id + WHERE pr.product_id = p.id + ), p.cost, 0) as standard_hpp_per_unit, + COALESCE(( + SELECT SUM(pr.quantity * (1 + COALESCE(pr.waste_percentage, 0)/100.0) * i.cost) + FROM product_recipes pr + JOIN ingredients i ON pr.ingredient_id = i.id + WHERE pr.product_id = p.id + ), p.cost, 0) * COALESCE(SUM(oi.quantity), 0) as standard_hpp_total, + CASE + WHEN SUM(oi.quantity) > 0 THEN COALESCE(SUM(oi.total_cost), 0) / SUM(oi.quantity) + ELSE 0 + END as fifo_hpp_per_unit, + COALESCE(SUM(oi.total_cost), 0) as fifo_hpp_total, + COALESCE(mahpp.hpp_per_unit, p.cost, 0) as moving_average_hpp_per_unit, + COALESCE(mahpp.hpp_per_unit, p.cost, 0) * COALESCE(SUM(oi.quantity), 0) as moving_average_hpp_total `). 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"). + Joins("LEFT JOIN (?) mahpp ON mahpp.product_id = p.id", + r.db.Table("product_recipes pr2"). + Select("pr2.product_id, SUM(pr2.quantity * (1 + COALESCE(pr2.waste_percentage, 0)/100.0) * COALESCE(ma.moving_avg_cost, ing.cost)) as hpp_per_unit"). + Joins("JOIN ingredients ing ON pr2.ingredient_id = ing.id"). + Joins("LEFT JOIN (?) ma ON ma.ingredient_id = pr2.ingredient_id", + r.db.Table("inventory_movements im"). + Select("im.item_id as ingredient_id, CASE WHEN SUM(im.quantity) > 0 THEN SUM(im.total_cost) / SUM(im.quantity) ELSE 0 END as moving_avg_cost"). + Where("im.movement_type = ?", "purchase"). + Where("im.item_type = ?", "INGREDIENT"). + Where("im.organization_id = ?", organizationID). + Where("im.created_at <= ?", dateTo). + Group("im.item_id"), + ). + Group("pr2.product_id"), + ). Where("o.organization_id = ?", organizationID). Where("o.is_void = ?", false). Where("o.is_refund = ?", false). @@ -141,7 +175,7 @@ func (r *AnalyticsRepositoryImpl) GetProductAnalytics(ctx context.Context, organ } err := query. - Group("p.id, p.name, c.id, c.name, c.order"). + Group("p.id, p.name, p.cost, c.id, c.name, c.order, mahpp.hpp_per_unit"). Order("revenue DESC"). Limit(limit). Scan(&results).Error @@ -160,11 +194,30 @@ func (r *AnalyticsRepositoryImpl) GetProductAnalyticsPerCategory(ctx context.Con COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.total_price - COALESCE(oi.refund_amount, 0) ELSE 0 END), 0) as total_revenue, COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.quantity - COALESCE(oi.refund_quantity, 0) ELSE 0 END), 0) as total_quantity, COUNT(DISTINCT p.id) as product_count, - COUNT(DISTINCT oi.order_id) as order_count + COUNT(DISTINCT oi.order_id) as order_count, + COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN COALESCE(shpp.hpp_per_unit, p.cost, 0) * (oi.quantity - COALESCE(oi.refund_quantity, 0)) ELSE 0 END), 0) as total_standard_hpp, + COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN oi.total_cost * ((oi.quantity - COALESCE(oi.refund_quantity, 0))::float / NULLIF(oi.quantity, 0)) ELSE 0 END), 0) as total_fifo_hpp, + COALESCE(SUM(CASE WHEN oi.is_fully_refunded = false THEN COALESCE(mahpp.hpp_per_unit, p.cost, 0) * (oi.quantity - COALESCE(oi.refund_quantity, 0)) ELSE 0 END), 0) as total_moving_average_hpp `). 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"). + Joins("LEFT JOIN (SELECT pr.product_id, SUM(pr.quantity * (1 + COALESCE(pr.waste_percentage, 0)/100.0) * i.cost) as hpp_per_unit FROM product_recipes pr JOIN ingredients i ON pr.ingredient_id = i.id GROUP BY pr.product_id) shpp ON shpp.product_id = p.id"). + Joins("LEFT JOIN (?) mahpp ON mahpp.product_id = p.id", + r.db.Table("product_recipes pr2"). + Select("pr2.product_id, SUM(pr2.quantity * (1 + COALESCE(pr2.waste_percentage, 0)/100.0) * COALESCE(ma.moving_avg_cost, ing.cost)) as hpp_per_unit"). + Joins("JOIN ingredients ing ON pr2.ingredient_id = ing.id"). + Joins("LEFT JOIN (?) ma ON ma.ingredient_id = pr2.ingredient_id", + r.db.Table("inventory_movements im"). + Select("im.item_id as ingredient_id, CASE WHEN SUM(im.quantity) > 0 THEN SUM(im.total_cost) / SUM(im.quantity) ELSE 0 END as moving_avg_cost"). + Where("im.movement_type = ?", "purchase"). + Where("im.item_type = ?", "INGREDIENT"). + Where("im.organization_id = ?", organizationID). + Where("im.created_at <= ?", dateTo). + Group("im.item_id"), + ). + Group("pr2.product_id"), + ). Where("o.organization_id = ?", organizationID). Where("o.is_void = ?", false). Where("o.is_refund = ?", false). diff --git a/internal/router/router.go b/internal/router/router.go index 0f95c64..2fe6206 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -50,65 +50,7 @@ type Router struct { customerAuthMiddleware *middleware.CustomerAuthMiddleware } -func NewRouter(cfg *config.Config, - healthHandler *handler.HealthHandler, - authService service.AuthService, - authMiddleware *middleware.AuthMiddleware, - userService *service.UserServiceImpl, - userValidator *validator.UserValidatorImpl, - organizationService service.OrganizationService, - organizationValidator validator.OrganizationValidator, - outletService service.OutletService, - outletValidator validator.OutletValidator, - outletSettingService service.OutletSettingService, - categoryService service.CategoryService, - categoryValidator validator.CategoryValidator, - productService service.ProductService, - productValidator validator.ProductValidator, - productVariantService service.ProductVariantService, - productVariantValidator validator.ProductVariantValidator, - inventoryService service.InventoryService, - inventoryValidator validator.InventoryValidator, - orderService service.OrderService, - orderValidator validator.OrderValidator, - fileService service.FileService, - fileValidator validator.FileValidator, - customerService service.CustomerService, - customerValidator validator.CustomerValidator, - paymentMethodService service.PaymentMethodService, - paymentMethodValidator validator.PaymentMethodValidator, - analyticsService *service.AnalyticsServiceImpl, - reportService service.ReportService, - tableService *service.TableServiceImpl, - tableValidator *validator.TableValidator, - unitService handler.UnitService, - ingredientService handler.IngredientService, - productRecipeService service.ProductRecipeService, - vendorService service.VendorService, - vendorValidator validator.VendorValidator, - purchaseOrderService service.PurchaseOrderService, - purchaseOrderValidator validator.PurchaseOrderValidator, - unitConverterService service.IngredientUnitConverterService, - unitConverterValidator validator.IngredientUnitConverterValidator, - chartOfAccountTypeService service.ChartOfAccountTypeService, - chartOfAccountTypeValidator validator.ChartOfAccountTypeValidator, - chartOfAccountService service.ChartOfAccountService, - chartOfAccountValidator validator.ChartOfAccountValidator, - accountService service.AccountService, - accountValidator validator.AccountValidator, - orderIngredientTransactionService service.OrderIngredientTransactionService, - orderIngredientTransactionValidator validator.OrderIngredientTransactionValidator, - gamificationService service.GamificationService, - gamificationValidator validator.GamificationValidator, - rewardService service.RewardService, - rewardValidator validator.RewardValidator, - campaignService service.CampaignService, - campaignValidator validator.CampaignValidator, - customerAuthService service.CustomerAuthService, - customerAuthValidator validator.CustomerAuthValidator, - customerPointsService service.CustomerPointsService, - spinGameService service.SpinGameService, - customerAuthMiddleware *middleware.CustomerAuthMiddleware) *Router { +func NewRouter(cfg *config.Config, healthHandler *handler.HealthHandler, authService service.AuthService, authMiddleware *middleware.AuthMiddleware, userService *service.UserServiceImpl, userValidator *validator.UserValidatorImpl, organizationService service.OrganizationService, organizationValidator validator.OrganizationValidator, outletService service.OutletService, outletValidator validator.OutletValidator, outletSettingService service.OutletSettingService, categoryService service.CategoryService, categoryValidator validator.CategoryValidator, productService service.ProductService, productValidator validator.ProductValidator, productVariantService service.ProductVariantService, productVariantValidator validator.ProductVariantValidator, inventoryService service.InventoryService, inventoryValidator validator.InventoryValidator, orderService service.OrderService, orderValidator validator.OrderValidator, fileService service.FileService, fileValidator validator.FileValidator, customerService service.CustomerService, customerValidator validator.CustomerValidator, paymentMethodService service.PaymentMethodService, paymentMethodValidator validator.PaymentMethodValidator, analyticsService *service.AnalyticsServiceImpl, reportService service.ReportService, tableService *service.TableServiceImpl, tableValidator *validator.TableValidator, unitService handler.UnitService, ingredientService handler.IngredientService, productRecipeService service.ProductRecipeService, vendorService service.VendorService, vendorValidator validator.VendorValidator, purchaseOrderService service.PurchaseOrderService, purchaseOrderValidator validator.PurchaseOrderValidator, unitConverterService service.IngredientUnitConverterService, unitConverterValidator validator.IngredientUnitConverterValidator, chartOfAccountTypeService service.ChartOfAccountTypeService, chartOfAccountTypeValidator validator.ChartOfAccountTypeValidator, chartOfAccountService service.ChartOfAccountService, chartOfAccountValidator validator.ChartOfAccountValidator, accountService service.AccountService, accountValidator validator.AccountValidator, orderIngredientTransactionService service.OrderIngredientTransactionService, orderIngredientTransactionValidator validator.OrderIngredientTransactionValidator, gamificationService service.GamificationService, gamificationValidator validator.GamificationValidator, rewardService service.RewardService, rewardValidator validator.RewardValidator, campaignService service.CampaignService, campaignValidator validator.CampaignValidator, customerAuthService service.CustomerAuthService, customerAuthValidator validator.CustomerAuthValidator, customerPointsService service.CustomerPointsService, spinGameService service.SpinGameService, customerAuthMiddleware *middleware.CustomerAuthMiddleware) *Router { return &Router{ config: cfg, diff --git a/internal/transformer/analytics_transformer.go b/internal/transformer/analytics_transformer.go index 934da2a..e776d1b 100644 --- a/internal/transformer/analytics_transformer.go +++ b/internal/transformer/analytics_transformer.go @@ -155,16 +155,22 @@ func ProductAnalyticsModelToContract(resp *models.ProductAnalyticsResponse) *con var data []contract.ProductAnalyticsData for _, item := range resp.Data { data = append(data, contract.ProductAnalyticsData{ - ProductID: item.ProductID, - ProductName: item.ProductName, - ProductSku: item.ProductSku, - CategoryID: item.CategoryID, - CategoryName: item.CategoryName, - CategoryOrder: item.CategoryOrder, - QuantitySold: item.QuantitySold, - Revenue: item.Revenue, - AveragePrice: item.AveragePrice, - OrderCount: item.OrderCount, + ProductID: item.ProductID, + ProductName: item.ProductName, + ProductSku: item.ProductSku, + CategoryID: item.CategoryID, + CategoryName: item.CategoryName, + CategoryOrder: item.CategoryOrder, + QuantitySold: item.QuantitySold, + Revenue: item.Revenue, + AveragePrice: item.AveragePrice, + OrderCount: item.OrderCount, + StandardHppPerUnit: item.StandardHppPerUnit, + StandardHppTotal: item.StandardHppTotal, + FifoHppPerUnit: item.FifoHppPerUnit, + FifoHppTotal: item.FifoHppTotal, + MovingAverageHppPerUnit: item.MovingAverageHppPerUnit, + MovingAverageHppTotal: item.MovingAverageHppTotal, }) } @@ -208,12 +214,15 @@ func ProductAnalyticsPerCategoryModelToContract(resp *models.ProductAnalyticsPer var data []contract.ProductAnalyticsPerCategoryData for _, item := range resp.Data { data = append(data, contract.ProductAnalyticsPerCategoryData{ - CategoryID: item.CategoryID, - CategoryName: item.CategoryName, - TotalRevenue: item.TotalRevenue, - TotalQuantity: item.TotalQuantity, - ProductCount: item.ProductCount, - OrderCount: item.OrderCount, + CategoryID: item.CategoryID, + CategoryName: item.CategoryName, + TotalRevenue: item.TotalRevenue, + TotalQuantity: item.TotalQuantity, + ProductCount: item.ProductCount, + OrderCount: item.OrderCount, + TotalStandardHpp: item.TotalStandardHpp, + TotalFifoHpp: item.TotalFifoHpp, + TotalMovingAverageHpp: item.TotalMovingAverageHpp, }) } @@ -257,14 +266,20 @@ func DashboardAnalyticsModelToContract(resp *models.DashboardAnalyticsResponse) var topProducts []contract.ProductAnalyticsData for _, item := range resp.TopProducts { topProducts = append(topProducts, contract.ProductAnalyticsData{ - ProductID: item.ProductID, - ProductName: item.ProductName, - CategoryID: item.CategoryID, - CategoryName: item.CategoryName, - QuantitySold: item.QuantitySold, - Revenue: item.Revenue, - AveragePrice: item.AveragePrice, - OrderCount: item.OrderCount, + ProductID: item.ProductID, + ProductName: item.ProductName, + CategoryID: item.CategoryID, + CategoryName: item.CategoryName, + QuantitySold: item.QuantitySold, + Revenue: item.Revenue, + AveragePrice: item.AveragePrice, + OrderCount: item.OrderCount, + StandardHppPerUnit: item.StandardHppPerUnit, + StandardHppTotal: item.StandardHppTotal, + FifoHppPerUnit: item.FifoHppPerUnit, + FifoHppTotal: item.FifoHppTotal, + MovingAverageHppPerUnit: item.MovingAverageHppPerUnit, + MovingAverageHppTotal: item.MovingAverageHppTotal, }) }