Fix product performance grouped JSON build
This commit is contained in:
@@ -447,7 +447,8 @@ func productPerformanceExcelPeriodColumns(label, suffix string, values func(*pro
|
||||
}),
|
||||
numberExcelColumn(label+" Ürün Skor", "number", func(v *productPerformanceExcelVariant) any {
|
||||
qty, usd, markets, customers := values(v)
|
||||
return productPerformanceExcelProductScore(suffix, usd, productPerformanceExcelStockTurnover(qty, productPerformanceExcelAvgStock(v, suffix), productPerformanceExcelPeriodDays(v, suffix)), float64(markets), float64(customers), productPerformanceExcelMargin(usd, qty, v.CostPriceUSD))
|
||||
days := productPerformanceExcelPeriodDays(v, suffix)
|
||||
return productPerformanceExcelProductScore(suffix, usd, productPerformanceExcelStockTurnover(qty, productPerformanceExcelAvgStock(v, suffix), days), float64(markets), float64(customers), productPerformanceExcelMargin(usd, qty, v.CostPriceUSD), days)
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -685,9 +686,11 @@ func productPerformanceExcelSortNumber(row *productPerformanceExcelVariant, sort
|
||||
case "customer_count_total":
|
||||
return float64(row.CustomerCountTotal)
|
||||
case "performance_score", "performance_score_90d":
|
||||
return productPerformanceExcelProductScore("90d", row.SalesUSD90, productPerformanceExcelStockTurnover(row.SalesQty90, productPerformanceExcelAvgStock(row, "90d"), productPerformanceExcelPeriodDays(row, "90d")), float64(row.marketCount90()), float64(row.CustomerCount90), productPerformanceExcelMargin(row.SalesUSD90, row.SalesQty90, row.CostPriceUSD))
|
||||
days := productPerformanceExcelPeriodDays(row, "90d")
|
||||
return productPerformanceExcelProductScore("90d", row.SalesUSD90, productPerformanceExcelStockTurnover(row.SalesQty90, productPerformanceExcelAvgStock(row, "90d"), days), float64(row.marketCount90()), float64(row.CustomerCount90), productPerformanceExcelMargin(row.SalesUSD90, row.SalesQty90, row.CostPriceUSD), days)
|
||||
case "performance_score_total":
|
||||
return productPerformanceExcelProductScore("total", row.totalUSD(), productPerformanceExcelStockTurnover(row.totalQty(), productPerformanceExcelAvgStock(row, "total"), productPerformanceExcelPeriodDays(row, "total")), float64(row.marketCountTotal()), float64(row.CustomerCountTotal), productPerformanceExcelMargin(row.totalUSD(), row.totalQty(), row.CostPriceUSD))
|
||||
days := productPerformanceExcelPeriodDays(row, "total")
|
||||
return productPerformanceExcelProductScore("total", row.totalUSD(), productPerformanceExcelStockTurnover(row.totalQty(), productPerformanceExcelAvgStock(row, "total"), days), float64(row.marketCountTotal()), float64(row.CustomerCountTotal), productPerformanceExcelMargin(row.totalUSD(), row.totalQty(), row.CostPriceUSD), days)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
@@ -803,7 +806,7 @@ func productPerformanceExcelStatus(row *productPerformanceExcelVariant) string {
|
||||
return "Stok Riski"
|
||||
case productPerformanceExcelMargin(row.totalUSD(), row.totalQty(), row.CostPriceUSD) < 0:
|
||||
return "Fiyat Baskısı"
|
||||
case productPerformanceExcelProductScore("total", row.totalUSD(), productPerformanceExcelStockTurnover(row.totalQty(), productPerformanceExcelAvgStock(row, "total"), productPerformanceExcelPeriodDays(row, "total")), float64(row.marketCountTotal()), float64(row.CustomerCountTotal), productPerformanceExcelMargin(row.totalUSD(), row.totalQty(), row.CostPriceUSD)) >= 70:
|
||||
case productPerformanceExcelProductScore("total", row.totalUSD(), productPerformanceExcelStockTurnover(row.totalQty(), productPerformanceExcelAvgStock(row, "total"), productPerformanceExcelPeriodDays(row, "total")), float64(row.marketCountTotal()), float64(row.CustomerCountTotal), productPerformanceExcelMargin(row.totalUSD(), row.totalQty(), row.CostPriceUSD), productPerformanceExcelPeriodDays(row, "total")) >= 70:
|
||||
return "Yıldız Ürün"
|
||||
default:
|
||||
return productPerformanceExcelBucketLabel(row.PerformanceBucket)
|
||||
@@ -954,16 +957,17 @@ func productPerformanceExcelMargin(salesUSD, qty, unitCost float64) float64 {
|
||||
return productPerformanceExcelGrossProfit(salesUSD, qty, unitCost) / salesUSD
|
||||
}
|
||||
|
||||
func productPerformanceExcelProductScore(suffix string, salesUSD, stockTurnover, marketCount, customerCount, margin float64) float64 {
|
||||
func productPerformanceExcelProductScore(suffix string, salesUSD, stockTurnover, marketCount, customerCount, margin float64, periodDays ...float64) float64 {
|
||||
if salesUSD <= 0 {
|
||||
return 1
|
||||
}
|
||||
revenueScore := productPerformanceExcelRatioScore(salesUSD, productPerformanceExcelProductRevenueTarget(suffix))
|
||||
days := productPerformanceExcelScorePeriodDays(suffix, periodDays...)
|
||||
revenueScore := productPerformanceExcelRatioScore(salesUSD, productPerformanceExcelProductRevenueTargetForDays(suffix, days))
|
||||
score := 0.30*productPerformanceExcelMarginScore(margin) +
|
||||
0.20*productPerformanceExcelRatioScore(stockTurnover, 4) +
|
||||
0.20*revenueScore +
|
||||
0.05*productPerformanceExcelRatioScore(marketCount, productPerformanceExcelMarketSpreadTarget(suffix)) +
|
||||
0.25*productPerformanceExcelRatioScore(customerCount, productPerformanceExcelCustomerSpreadTarget(suffix))
|
||||
0.25*productPerformanceExcelRatioScore(customerCount, productPerformanceExcelCustomerSpreadTargetForDays(suffix, days))
|
||||
return productPerformanceExcelRoundScore(score)
|
||||
}
|
||||
|
||||
@@ -981,6 +985,10 @@ func productPerformanceExcelMarketSpreadTarget(suffix string) float64 {
|
||||
}
|
||||
|
||||
func productPerformanceExcelCustomerSpreadTarget(suffix string) float64 {
|
||||
return productPerformanceExcelCustomerSpreadTargetForDays(suffix, productPerformanceExcelScorePeriodDays(suffix))
|
||||
}
|
||||
|
||||
func productPerformanceExcelCustomerSpreadTargetForDays(suffix string, periodDays float64) float64 {
|
||||
switch suffix {
|
||||
case "90d":
|
||||
return 8
|
||||
@@ -989,28 +997,62 @@ func productPerformanceExcelCustomerSpreadTarget(suffix string) float64 {
|
||||
case "365d":
|
||||
return 50
|
||||
default:
|
||||
return 50
|
||||
return 20 * productPerformanceExcelTotalPeriodMultiplier(periodDays)
|
||||
}
|
||||
}
|
||||
|
||||
func productPerformanceExcelProductRevenueTarget(suffix string) float64 {
|
||||
return productPerformanceExcelProductRevenueTargetForDays(suffix, productPerformanceExcelScorePeriodDays(suffix))
|
||||
}
|
||||
|
||||
func productPerformanceExcelProductRevenueTargetForDays(suffix string, periodDays float64) float64 {
|
||||
switch suffix {
|
||||
case "180d":
|
||||
return 20000
|
||||
return 50000
|
||||
case "365d":
|
||||
return 40000
|
||||
return 100000
|
||||
case "total":
|
||||
return 120000
|
||||
return 50000 * productPerformanceExcelTotalPeriodMultiplier(periodDays)
|
||||
default:
|
||||
return 10000
|
||||
return 25000
|
||||
}
|
||||
}
|
||||
|
||||
func productPerformanceExcelScorePeriodDays(suffix string, periodDays ...float64) float64 {
|
||||
if len(periodDays) > 0 && periodDays[0] > 0 {
|
||||
return periodDays[0]
|
||||
}
|
||||
switch suffix {
|
||||
case "90d":
|
||||
return 90
|
||||
case "180d":
|
||||
return 180
|
||||
case "365d":
|
||||
return 360
|
||||
case "total":
|
||||
start := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
now := time.Now()
|
||||
if now.Before(start) {
|
||||
return 0
|
||||
}
|
||||
return now.Sub(start).Hours()/24 + 1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func productPerformanceExcelTotalPeriodMultiplier(periodDays float64) float64 {
|
||||
if periodDays <= 0 {
|
||||
periodDays = 180
|
||||
}
|
||||
return math.Max(1, periodDays/180.0)
|
||||
}
|
||||
|
||||
func productPerformanceExcelMarginScore(margin float64) float64 {
|
||||
if margin < 0 {
|
||||
margin = 0
|
||||
}
|
||||
return productPerformanceExcelRatioScore(margin, 0.40)
|
||||
return productPerformanceExcelRatioScore(margin, 0.45)
|
||||
}
|
||||
|
||||
func productPerformanceExcelRatioScore(value, target float64) float64 {
|
||||
|
||||
Reference in New Issue
Block a user