This commit is contained in:
2026-04-24 17:56:38 +07:00
parent 9b606b4c8b
commit ba970229a9
15 changed files with 206 additions and 1065 deletions
+25 -16
View File
@@ -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,
})
}
-179
View File
@@ -1,179 +0,0 @@
package processor
import (
"context"
"fmt"
"apskel-pos-be/internal/entities"
"apskel-pos-be/internal/models"
"apskel-pos-be/internal/repository"
"github.com/google/uuid"
)
type HPPProcessor interface {
GetStandardHPP(ctx context.Context, req *models.StandardHPPRequest) (*models.StandardHPPResponse, error)
GetRealHPP(ctx context.Context, req *models.RealHPPRequest) (*models.RealHPPResponse, error)
}
type HPPProcessorImpl struct {
hppRepo repository.HPPRepository
}
func NewHPPProcessorImpl(hppRepo repository.HPPRepository) *HPPProcessorImpl {
return &HPPProcessorImpl{
hppRepo: hppRepo,
}
}
func (p *HPPProcessorImpl) GetStandardHPP(ctx context.Context, req *models.StandardHPPRequest) (*models.StandardHPPResponse, error) {
products, err := p.hppRepo.GetStandardHPP(ctx, req.OrganizationID, req.ProductID, req.CategoryID)
if err != nil {
return nil, fmt.Errorf("failed to get standard HPP: %w", err)
}
productIDs := make([]uuid.UUID, 0)
for _, pp := range products {
if pp.HasRecipe {
productIDs = append(productIDs, pp.ProductID)
}
}
ingredients, err := p.hppRepo.GetStandardHPPIngredients(ctx, req.OrganizationID, productIDs)
if err != nil {
return nil, fmt.Errorf("failed to get standard HPP ingredients: %w", err)
}
productData := make([]models.StandardHPPProduct, 0, len(products))
var totalHPP float64
var hppCount int64
for _, pp := range products {
productData = append(productData, models.StandardHPPProduct{
ProductID: pp.ProductID,
ProductName: pp.ProductName,
ProductSku: pp.ProductSku,
CategoryID: pp.CategoryID,
CategoryName: pp.CategoryName,
SellingPrice: pp.SellingPrice,
ProductCost: pp.ProductCost,
StandardCost: pp.StandardCost,
StandardHPPPercentage: pp.StandardHPPPercentage,
HasRecipe: pp.HasRecipe,
})
if pp.HasRecipe {
totalHPP += pp.StandardHPPPercentage
hppCount++
}
}
ingredientData := make([]models.StandardHPPIngredient, 0, len(ingredients))
for _, ing := range ingredients {
ingredientData = append(ingredientData, models.StandardHPPIngredient{
ProductID: ing.ProductID,
IngredientID: ing.IngredientID,
IngredientName: ing.IngredientName,
Quantity: ing.Quantity,
UnitName: ing.UnitName,
CostPerUnit: ing.CostPerUnit,
WastePercentage: ing.WastePercentage,
TotalCost: ing.TotalCost,
})
}
var avgHPP float64
if hppCount > 0 {
avgHPP = totalHPP / float64(hppCount)
}
return &models.StandardHPPResponse{
OrganizationID: req.OrganizationID,
Summary: models.HPPSummary{
AverageStandardHPP: avgHPP,
AverageRealHPP: 0,
HPPVariance: 0,
TotalProducts: int64(len(products)),
},
Products: productData,
Ingredients: ingredientData,
}, nil
}
func (p *HPPProcessorImpl) GetRealHPP(ctx context.Context, req *models.RealHPPRequest) (*models.RealHPPResponse, error) {
if req.DateFrom.After(req.DateTo) {
return nil, fmt.Errorf("date_from cannot be after date_to")
}
if req.GroupBy == "" {
req.GroupBy = "day"
}
products, err := p.hppRepo.GetRealHPP(ctx, req.OrganizationID, req.OutletID, req.ProductID, req.CategoryID, req.DateFrom, req.DateTo)
if err != nil {
return nil, fmt.Errorf("failed to get real HPP: %w", err)
}
var timeSeries []*entities.RealHPPTimeSeries
if req.GroupBy != "" {
timeSeries, err = p.hppRepo.GetRealHPPTimeSeries(ctx, req.OrganizationID, req.OutletID, req.ProductID, req.CategoryID, req.DateFrom, req.DateTo, req.GroupBy)
if err != nil {
return nil, fmt.Errorf("failed to get real HPP time series: %w", err)
}
}
productData := make([]models.RealHPPProduct, 0, len(products))
var totalHPP float64
var totalRevenue float64
var hppCount int64
for _, pp := range products {
productData = append(productData, models.RealHPPProduct{
ProductID: pp.ProductID,
ProductName: pp.ProductName,
ProductSku: pp.ProductSku,
CategoryID: pp.CategoryID,
CategoryName: pp.CategoryName,
SellingPrice: pp.SellingPrice,
RealTotalCost: pp.RealTotalCost,
RealTotalRevenue: pp.RealTotalRevenue,
RealHPPPercentage: pp.RealHPPPercentage,
TotalQuantitySold: pp.TotalQuantitySold,
TotalOrders: pp.TotalOrders,
})
if pp.RealTotalRevenue > 0 {
totalHPP += pp.RealHPPPercentage
totalRevenue += pp.RealTotalRevenue
hppCount++
}
}
var avgHPP float64
if hppCount > 0 {
avgHPP = totalHPP / float64(hppCount)
}
tsData := make([]models.RealHPPTimeSeries, 0, len(timeSeries))
for _, ts := range timeSeries {
tsData = append(tsData, models.RealHPPTimeSeries{
Date: ts.Date,
RealTotalCost: ts.RealTotalCost,
RealTotalRevenue: ts.RealTotalRevenue,
RealHPPPercentage: ts.RealHPPPercentage,
TotalOrders: ts.TotalOrders,
})
}
return &models.RealHPPResponse{
OrganizationID: req.OrganizationID,
OutletID: req.OutletID,
DateFrom: req.DateFrom,
DateTo: req.DateTo,
GroupBy: req.GroupBy,
Summary: models.HPPSummary{
AverageRealHPP: avgHPP,
TotalProducts: int64(len(products)),
},
Products: productData,
TimeSeries: tsData,
}, nil
}