Fix product performance grouped JSON build
This commit is contained in:
@@ -1978,7 +1978,7 @@ SalesAgg AS (
|
||||
MAX(last_ref_number) AS last_ref_number,
|
||||
COALESCE(SUM(sales_qty),0) AS sales_qty_total,
|
||||
COALESCE(SUM(sales_usd),0) AS sales_usd_total,
|
||||
COALESCE(COUNT(DISTINCT NULLIF(customer_code, '-')),0)::integer AS customer_count_total,
|
||||
COALESCE(COUNT(DISTINCT NULLIF(customer_code, '-')) FILTER (WHERE COALESCE(sales_usd,0) > 0),0)::integer AS customer_count_total,
|
||||
COALESCE(SUM(invoice_count),0)::integer AS invoice_count_total
|
||||
FROM mk_product_performance_sales_daily, Bounds
|
||||
WHERE sales_date BETWEEN Bounds.period_start AND Bounds.period_end
|
||||
@@ -2102,8 +2102,8 @@ Spread AS (
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
COUNT(DISTINCT NULLIF(market_key, 'STOK'))::integer AS market_count_total,
|
||||
COUNT(DISTINCT NULLIF(customer_code, '-'))::integer AS customer_count_total_all
|
||||
COUNT(DISTINCT NULLIF(market_key, 'STOK')) FILTER (WHERE COALESCE(sales_usd,0) > 0)::integer AS market_count_total,
|
||||
COUNT(DISTINCT NULLIF(customer_code, '-')) FILTER (WHERE COALESCE(sales_usd,0) > 0)::integer AS customer_count_total_all
|
||||
FROM mk_product_performance_sales_daily, Bounds
|
||||
WHERE sales_date BETWEEN Bounds.period_start AND Bounds.period_end
|
||||
AND upper(translate(btrim(COALESCE(urun_ilk_grubu,'')), U&'\0130\015E\011E\00DC\00D6\00C7\0131\015F\011F\00FC\00F6\00E7', 'ISGUOCisguoc')) NOT IN ('MALZEMELI FASON', 'MALZEMESIZ FASON', 'MAZLEMELI FASON', 'MAZEMESIZ FASON', 'DIGER')
|
||||
@@ -2140,8 +2140,8 @@ Scored AS (
|
||||
CASE WHEN b.sales_usd_total <= 0 THEN 0 ELSE (b.sales_usd_total - (b.sales_qty_total * COALESCE(pd.cost_price_usd,0))) / NULLIF(b.sales_usd_total,0) END AS gross_margin_total,
|
||||
CASE WHEN b.sales_qty_total <= 0 THEN 0 ELSE (b.sales_usd_total / NULLIF(b.sales_qty_total,0)) - COALESCE(pd.cost_price_usd,0) END AS unit_profit_cost_total,
|
||||
CASE WHEN b.sales_qty_total <= 0 THEN 0 ELSE (b.sales_usd_total / NULLIF(b.sales_qty_total,0)) - COALESCE(pd.base_price_usd,0) END AS unit_profit_base_total,
|
||||
COALESCE(sp.market_count_total,0) AS market_count_total,
|
||||
COALESCE(sp.customer_count_total_all, b.customer_count_total) AS customer_count_total,
|
||||
CASE WHEN b.market_key <> 'STOK' AND b.sales_usd_total > 0 THEN 1 ELSE 0 END AS market_count_total,
|
||||
b.customer_count_total AS customer_count_total,
|
||||
b.invoice_count_total,
|
||||
CASE
|
||||
WHEN AVG(b.sales_qty_total) OVER (PARTITION BY b.market_key, b.kategori, b.urun_ana_grubu) <= 0 THEN 0
|
||||
@@ -3174,7 +3174,7 @@ SELECT
|
||||
ELSE COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)
|
||||
/ NULLIF(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)
|
||||
END AS avg_price_usd_90d,
|
||||
COALESCE(SUM(customer_count) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)::integer AS customer_count_90d,
|
||||
COUNT(DISTINCT NULLIF(customer_code, '-')) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days' AND COALESCE(sales_usd,0) > 0)::integer AS customer_count_90d,
|
||||
COALESCE(SUM(invoice_count) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)::integer AS invoice_count_90d,
|
||||
COALESCE(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '364 days'),0) AS sales_qty_365d,
|
||||
COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '364 days'),0) AS sales_usd_365d
|
||||
@@ -3507,16 +3507,16 @@ Agg AS (
|
||||
COUNT(DISTINCT COALESCE(NULLIF(urun_ana_grubu,''), NULLIF(urun_alt_grubu,''), NULLIF(kategori,''), product_code)) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days')::integer AS product_group_count_180d,
|
||||
COUNT(DISTINCT COALESCE(NULLIF(urun_ana_grubu,''), NULLIF(urun_alt_grubu,''), NULLIF(kategori,''), product_code)) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days')::integer AS product_group_count_365d,
|
||||
COUNT(DISTINCT COALESCE(NULLIF(urun_ana_grubu,''), NULLIF(urun_alt_grubu,''), NULLIF(kategori,''), product_code)) FILTER (WHERE sales_date >= DATE '2022-01-01')::integer AS product_group_count_total,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days')::integer AS market_count_90d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days')::integer AS market_count_180d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days')::integer AS market_count_365d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= DATE '2022-01-01')::integer AS market_count_total,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days' AND COALESCE(sales_usd,0) > 0)::integer AS market_count_90d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days' AND COALESCE(sales_usd,0) > 0)::integer AS market_count_180d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days' AND COALESCE(sales_usd,0) > 0)::integer AS market_count_365d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE sales_date >= DATE '2022-01-01' AND COALESCE(sales_usd,0) > 0)::integer AS market_count_total,
|
||||
COALESCE(MAX(stock_qty),0) AS stock_qty,
|
||||
COALESCE(MAX(avg_stock_90d),0) AS avg_stock_90d,
|
||||
COALESCE(MAX(avg_stock_180d),0) AS avg_stock_180d,
|
||||
COALESCE(MAX(avg_stock_365d),0) AS avg_stock_365d,
|
||||
COALESCE(MAX(avg_stock_total),0) AS avg_stock_total,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days' AND COALESCE(customer_code,'') <> '')::integer AS customer_count_90d,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days' AND COALESCE(customer_code,'') <> '' AND COALESCE(sales_usd,0) > 0)::integer AS customer_count_90d,
|
||||
COALESCE(SUM(invoice_count) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)::integer AS invoice_count_90d,
|
||||
COALESCE(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0) AS sales_qty_90d,
|
||||
COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0) AS sales_usd_90d,
|
||||
@@ -3532,7 +3532,7 @@ Agg AS (
|
||||
ELSE COALESCE(SUM(sales_qty * cost_price_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)
|
||||
/ NULLIF(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '89 days'),0)
|
||||
END AS cost_price_usd_90d,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days' AND COALESCE(customer_code,'') <> '')::integer AS customer_count_180d,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days' AND COALESCE(customer_code,'') <> '' AND COALESCE(sales_usd,0) > 0)::integer AS customer_count_180d,
|
||||
COALESCE(SUM(invoice_count) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days'),0)::integer AS invoice_count_180d,
|
||||
COALESCE(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days'),0) AS sales_qty_180d,
|
||||
COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '179 days'),0) AS sales_usd_180d,
|
||||
@@ -3550,7 +3550,7 @@ Agg AS (
|
||||
END AS cost_price_usd_180d,
|
||||
COALESCE(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0) AS sales_qty_365d,
|
||||
COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0) AS sales_usd_365d,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days' AND COALESCE(customer_code,'') <> '')::integer AS customer_count_365d,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days' AND COALESCE(customer_code,'') <> '' AND COALESCE(sales_usd,0) > 0)::integer AS customer_count_365d,
|
||||
COALESCE(SUM(invoice_count) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0)::integer AS invoice_count_365d,
|
||||
CASE WHEN COALESCE(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0)=0 THEN 0
|
||||
ELSE COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0)
|
||||
@@ -3564,7 +3564,7 @@ Agg AS (
|
||||
ELSE COALESCE(SUM(sales_qty * cost_price_usd) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0)
|
||||
/ NULLIF(SUM(sales_qty) FILTER (WHERE sales_date >= current_date - INTERVAL '359 days'),0)
|
||||
END AS cost_price_usd_365d,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= DATE '2022-01-01' AND COALESCE(customer_code,'') <> '')::integer AS customer_count_total,
|
||||
COUNT(DISTINCT customer_code) FILTER (WHERE sales_date >= DATE '2022-01-01' AND COALESCE(customer_code,'') <> '' AND COALESCE(sales_usd,0) > 0)::integer AS customer_count_total,
|
||||
COALESCE(SUM(invoice_count) FILTER (WHERE sales_date >= DATE '2022-01-01'),0)::integer AS invoice_count_total,
|
||||
COALESCE(SUM(sales_qty) FILTER (WHERE sales_date >= DATE '2022-01-01'),0) AS sales_qty_total,
|
||||
COALESCE(SUM(sales_usd) FILTER (WHERE sales_date >= DATE '2022-01-01'),0) AS sales_usd_total,
|
||||
@@ -3710,49 +3710,45 @@ SELECT
|
||||
CASE WHEN avg_stock_total > 0 THEN sales_qty_total / NULLIF(avg_stock_total,0) ELSE 0 END AS stock_turnover_total,
|
||||
has_cost,
|
||||
sales_index_90d,
|
||||
CASE WHEN NOT has_cost THEN 0 ELSE
|
||||
CASE WHEN NOT has_cost THEN 0 WHEN sales_usd_90d <= 0 THEN 1 ELSE
|
||||
ROUND((
|
||||
LEAST(35, sales_usd_90d / 1000)
|
||||
+ LEAST(25, GREATEST(gross_margin_cost_90d,0) * 55)
|
||||
+ LEAST(20, invoice_count_90d * 2)
|
||||
+ LEAST(10, sales_qty_90d / 10)
|
||||
+ LEAST(10, product_count)
|
||||
LEAST(35, sales_usd_90d / 25000 * 35)
|
||||
+ LEAST(30, GREATEST(gross_margin_cost_90d,0) / 0.40 * 30)
|
||||
+ LEAST(20, product_group_count_90d / 8.0 * 20)
|
||||
+ LEAST(15, sales_qty_90d / 500 * 15)
|
||||
)::numeric, 4)
|
||||
END AS customer_score_90d,
|
||||
CASE WHEN NOT has_cost THEN 0 ELSE
|
||||
CASE WHEN NOT has_cost THEN 0 WHEN sales_usd_180d <= 0 THEN 1 ELSE
|
||||
ROUND((
|
||||
LEAST(35, sales_usd_180d / 1000)
|
||||
+ LEAST(25, GREATEST(gross_margin_cost_180d,0) * 55)
|
||||
+ LEAST(20, invoice_count_180d * 2)
|
||||
+ LEAST(10, sales_qty_180d / 10)
|
||||
+ LEAST(10, product_count)
|
||||
LEAST(35, sales_usd_180d / 50000 * 35)
|
||||
+ LEAST(30, GREATEST(gross_margin_cost_180d,0) / 0.40 * 30)
|
||||
+ LEAST(20, product_group_count_180d / 8.0 * 20)
|
||||
+ LEAST(15, sales_qty_180d / 1000 * 15)
|
||||
)::numeric, 4)
|
||||
END AS customer_score_180d,
|
||||
CASE WHEN NOT has_cost THEN 0 ELSE
|
||||
CASE WHEN NOT has_cost THEN 0 WHEN sales_usd_365d <= 0 THEN 1 ELSE
|
||||
ROUND((
|
||||
LEAST(35, sales_usd_365d / 1000)
|
||||
+ LEAST(25, GREATEST(gross_margin_cost_365d,0) * 55)
|
||||
+ LEAST(20, invoice_count_365d * 2)
|
||||
+ LEAST(10, sales_qty_365d / 10)
|
||||
+ LEAST(10, product_count)
|
||||
LEAST(35, sales_usd_365d / 100000 * 35)
|
||||
+ LEAST(30, GREATEST(gross_margin_cost_365d,0) / 0.40 * 30)
|
||||
+ LEAST(20, product_group_count_365d / 8.0 * 20)
|
||||
+ LEAST(15, sales_qty_365d / 2000 * 15)
|
||||
)::numeric, 4)
|
||||
END AS customer_score_365d,
|
||||
CASE WHEN NOT has_cost THEN 0 ELSE
|
||||
CASE WHEN NOT has_cost THEN 0 WHEN sales_usd_total <= 0 THEN 1 ELSE
|
||||
ROUND((
|
||||
LEAST(35, sales_usd_total / 1000)
|
||||
+ LEAST(25, GREATEST(gross_margin_cost_total,0) * 55)
|
||||
+ LEAST(20, invoice_count_total * 2)
|
||||
+ LEAST(10, sales_qty_total / 10)
|
||||
+ LEAST(10, product_count)
|
||||
LEAST(35, sales_usd_total / 300000 * 35)
|
||||
+ LEAST(30, GREATEST(gross_margin_cost_total,0) / 0.40 * 30)
|
||||
+ LEAST(20, product_group_count_total / 8.0 * 20)
|
||||
+ LEAST(15, sales_qty_total / 6000 * 15)
|
||||
)::numeric, 4)
|
||||
END AS customer_score_total,
|
||||
CASE WHEN NOT has_cost THEN 0 ELSE
|
||||
CASE WHEN NOT has_cost THEN 0 WHEN sales_usd_90d <= 0 THEN 1 ELSE
|
||||
ROUND(
|
||||
LEAST(35, sales_index_90d * 18)
|
||||
+ LEAST(30, GREATEST(gross_margin_cost_90d,0) * 60)
|
||||
+ LEAST(15, invoice_count_90d * 1.5)
|
||||
+ LEAST(10, sales_qty_90d / 10)
|
||||
+ LEAST(10, (CASE WHEN avg_stock_90d > 0 THEN sales_qty_90d / NULLIF(avg_stock_90d,0) ELSE 0 END) * 5),
|
||||
LEAST(30, GREATEST(gross_margin_cost_90d,0) / 0.40 * 30)
|
||||
+ LEAST(20, (CASE WHEN avg_stock_90d > 0 THEN sales_qty_90d / NULLIF(avg_stock_90d,0) ELSE 0 END) / 1.5 * 20)
|
||||
+ LEAST(20, sales_usd_90d / 10000 * 20)
|
||||
+ LEAST(15, market_count_90d / 8.0 * 15)
|
||||
+ LEAST(15, customer_count_90d / 25.0 * 15),
|
||||
4
|
||||
)
|
||||
END AS performance_score,
|
||||
@@ -4485,8 +4481,8 @@ FROM (
|
||||
CASE WHEN SUM(sales_qty_180d) > 0 THEN SUM(unit_profit_cost_180d * sales_qty_180d) / NULLIF(SUM(sales_qty_180d),0) ELSE 0 END AS unit_profit_cost_180d,
|
||||
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(unit_profit_base_90d * sales_qty_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS unit_profit_base_90d,
|
||||
CASE WHEN SUM(sales_qty_180d) > 0 THEN SUM(unit_profit_base_180d * sales_qty_180d) / NULLIF(SUM(sales_qty_180d),0) ELSE 0 END AS unit_profit_base_180d,
|
||||
COALESCE(SUM(market_count_90d),0)::integer AS market_count_90d,
|
||||
COALESCE(SUM(customer_count_90d),0)::integer AS customer_count_90d,
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key,'STOK'),'')) FILTER (WHERE COALESCE(sales_usd_90d,0) > 0)::integer AS market_count_90d,
|
||||
COALESCE(SUM(CASE WHEN COALESCE(sales_usd_90d,0) > 0 THEN customer_count_90d ELSE 0 END),0)::integer AS customer_count_90d,
|
||||
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(sales_index_90d * sales_qty_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS sales_index_90d,
|
||||
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(price_index_90d * sales_qty_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS price_index_90d,
|
||||
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(margin_index_90d * sales_qty_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS margin_index_90d,
|
||||
@@ -5296,13 +5292,13 @@ func (n *productPerformanceGroupedSnapshotNode) add(row map[string]any) {
|
||||
func (n *productPerformanceGroupedSnapshotNode) addDistinctSpread(row map[string]any) {
|
||||
market := displayProductPerformanceMarketName(stringFromMap(row, "market_key"))
|
||||
if market != "" && market != "STOK" {
|
||||
if floatFromMap(row, "sales_qty_90d") > 0 || floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if n.Market90Seen == nil {
|
||||
n.Market90Seen = map[string]bool{}
|
||||
}
|
||||
n.Market90Seen[market] = true
|
||||
}
|
||||
if floatFromMap(row, "sales_qty_total") > 0 || floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if n.MarketTotalSeen == nil {
|
||||
n.MarketTotalSeen = map[string]bool{}
|
||||
}
|
||||
@@ -5311,13 +5307,13 @@ func (n *productPerformanceGroupedSnapshotNode) addDistinctSpread(row map[string
|
||||
}
|
||||
customer := strings.TrimSpace(stringFromMap(row, "customer_code"))
|
||||
if customer != "" && customer != "-" {
|
||||
if floatFromMap(row, "sales_qty_90d") > 0 || floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if n.Customer90Seen == nil {
|
||||
n.Customer90Seen = map[string]bool{}
|
||||
}
|
||||
n.Customer90Seen[customer] = true
|
||||
}
|
||||
if floatFromMap(row, "sales_qty_total") > 0 || floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if n.CustomerTotalSeen == nil {
|
||||
n.CustomerTotalSeen = map[string]bool{}
|
||||
}
|
||||
@@ -5530,19 +5526,19 @@ func aggregateProductPerformanceRows(rows []map[string]any, groupField string) m
|
||||
func addProductPerformanceDistinctSpread(row map[string]any, market90Seen, marketTotalSeen, customer90Seen, customerTotalSeen map[string]bool) {
|
||||
market := displayProductPerformanceMarketName(stringFromMap(row, "market_key"))
|
||||
if market != "" && market != "STOK" {
|
||||
if floatFromMap(row, "sales_qty_90d") > 0 || floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
market90Seen[market] = true
|
||||
}
|
||||
if floatFromMap(row, "sales_qty_total") > 0 || floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if floatFromMap(row, "sales_usd_total") > 0 {
|
||||
marketTotalSeen[market] = true
|
||||
}
|
||||
}
|
||||
customer := strings.TrimSpace(stringFromMap(row, "customer_code"))
|
||||
if customer != "" && customer != "-" {
|
||||
if floatFromMap(row, "sales_qty_90d") > 0 || floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
customer90Seen[customer] = true
|
||||
}
|
||||
if floatFromMap(row, "sales_qty_total") > 0 || floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if floatFromMap(row, "sales_usd_total") > 0 {
|
||||
customerTotalSeen[customer] = true
|
||||
}
|
||||
}
|
||||
@@ -5561,7 +5557,7 @@ func applyProductPerformanceDistinctSpread(row map[string]any, market90Seen, mar
|
||||
if len(customerTotalSeen) > 0 {
|
||||
row["customer_count_total"] = len(customerTotalSeen)
|
||||
}
|
||||
if floatFromMap(row, "sales_qty_90d") > 0 || floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if floatFromMap(row, "sales_usd_90d") > 0 {
|
||||
if intFromMap(row, "market_count_90d") == 0 {
|
||||
row["market_count_90d"] = 1
|
||||
}
|
||||
@@ -5569,7 +5565,7 @@ func applyProductPerformanceDistinctSpread(row map[string]any, market90Seen, mar
|
||||
row["customer_count_90d"] = 1
|
||||
}
|
||||
}
|
||||
if floatFromMap(row, "sales_qty_total") > 0 || floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if floatFromMap(row, "sales_usd_total") > 0 {
|
||||
if intFromMap(row, "market_count_total") == 0 {
|
||||
row["market_count_total"] = maxInt(1, intFromMap(row, "market_count_90d"))
|
||||
}
|
||||
@@ -5860,6 +5856,9 @@ func productPerformanceCustomerSalesPeriodScore(row map[string]any) float64 {
|
||||
}
|
||||
|
||||
func productPerformanceProductScore(suffix string, salesUSD, salesIndex, margin, stockTurnover, marketCount, customerCount float64) float64 {
|
||||
if salesUSD <= 0 {
|
||||
return 1
|
||||
}
|
||||
revenueScore := productPerformanceRevenueScore(suffix, salesUSD, salesIndex, productPerformanceProductRevenueTarget(suffix))
|
||||
score := 0.30*productPerformanceMarginComponentScore(margin) +
|
||||
0.20*productPerformanceRatioScore(stockTurnover, 1.50) +
|
||||
@@ -5870,6 +5869,9 @@ func productPerformanceProductScore(suffix string, salesUSD, salesIndex, margin,
|
||||
}
|
||||
|
||||
func productPerformanceCustomerScore(suffix string, salesUSD, margin, productGroupCount, salesQty float64) float64 {
|
||||
if salesUSD <= 0 {
|
||||
return 1
|
||||
}
|
||||
score := 0.35*productPerformanceRatioScore(salesUSD, productPerformanceCustomerRevenueTarget(suffix)) +
|
||||
0.30*productPerformanceMarginComponentScore(margin) +
|
||||
0.20*productPerformanceRatioScore(productGroupCount, 8) +
|
||||
@@ -5878,9 +5880,6 @@ func productPerformanceCustomerScore(suffix string, salesUSD, margin, productGro
|
||||
}
|
||||
|
||||
func productPerformanceRevenueScore(suffix string, salesUSD, salesIndex, absoluteTarget float64) float64 {
|
||||
if salesIndex > 0 {
|
||||
return productPerformanceRatioScore(salesIndex, 2)
|
||||
}
|
||||
return productPerformanceRatioScore(salesUSD, absoluteTarget)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,16 +76,19 @@ func productPerformanceSalesSQL() string {
|
||||
), SPACE(0)))
|
||||
END,
|
||||
Qty1 = ISNULL(I.Qty1, 0),
|
||||
TLAmount = ISNULL(I.Doc_Amount, 0) * ISNULL(I.Loc_ExchangeRate, 0),
|
||||
USDAmount = (ISNULL(I.Doc_Amount, 0) * ISNULL(I.Loc_ExchangeRate, 0)) / ISNULL((
|
||||
SELECT TOP 1 Rate
|
||||
FROM AllExchangeRates WITH(NOLOCK)
|
||||
WHERE CurrencyCode = 'USD'
|
||||
AND RelationCurrencyCode = 'TRY'
|
||||
AND ExchangeTypeCode = 6
|
||||
AND Rate > 1
|
||||
ORDER BY ABS(DATEDIFF(DAY, AllExchangeRates.Date, I.InvoiceDate)) ASC
|
||||
), 1),
|
||||
TLAmount = CASE
|
||||
WHEN Amount.DocCurrencyCode = 'TRY' THEN Amount.DocNetAmount
|
||||
WHEN CurRate.Rate > 0 THEN Amount.DocNetAmount * CurRate.Rate
|
||||
WHEN ISNULL(I.Loc_ExchangeRate, 0) > 0 THEN Amount.DocNetAmount * I.Loc_ExchangeRate
|
||||
ELSE 0
|
||||
END,
|
||||
USDAmount = CASE
|
||||
WHEN Amount.DocCurrencyCode = 'USD' THEN Amount.DocNetAmount
|
||||
WHEN Amount.DocCurrencyCode = 'TRY' AND UsdRate.Rate > 0 THEN Amount.DocNetAmount / UsdRate.Rate
|
||||
WHEN CurRate.Rate > 0 AND UsdRate.Rate > 0 THEN (Amount.DocNetAmount * CurRate.Rate) / UsdRate.Rate
|
||||
WHEN ISNULL(I.Loc_ExchangeRate, 0) > 0 AND UsdRate.Rate > 0 THEN (Amount.DocNetAmount * I.Loc_ExchangeRate) / UsdRate.Rate
|
||||
ELSE 0
|
||||
END,
|
||||
RN = ROW_NUMBER() OVER (
|
||||
PARTITION BY I.InvoiceLineID
|
||||
ORDER BY I.InvoiceDate DESC, I.InvoiceNumber
|
||||
@@ -96,6 +99,39 @@ func productPerformanceSalesSQL() string {
|
||||
AND CAF.CurrAccCode = I.CurrAccCode
|
||||
LEFT OUTER JOIN ProductAttributesFilter PAF WITH(NOLOCK)
|
||||
ON PAF.ItemCode = I.ItemCode
|
||||
LEFT OUTER JOIN dbo.trInvoiceLineCurrency ILC WITH(NOLOCK)
|
||||
ON ILC.InvoiceLineID = I.InvoiceLineID
|
||||
AND UPPER(LTRIM(RTRIM(ILC.CurrencyCode))) = UPPER(LTRIM(RTRIM(ISNULL(NULLIF(LTRIM(RTRIM(I.Doc_CurrencyCode)), ''), 'TRY'))))
|
||||
OUTER APPLY (
|
||||
SELECT
|
||||
DocCurrencyCode = UPPER(LTRIM(RTRIM(ISNULL(NULLIF(LTRIM(RTRIM(I.Doc_CurrencyCode)), ''), ISNULL(NULLIF(LTRIM(RTRIM(ILC.CurrencyCode)), ''), 'TRY'))))),
|
||||
DocNetAmount = COALESCE(
|
||||
NULLIF(ISNULL(ILC.NetAmount, 0), 0),
|
||||
NULLIF(ISNULL(I.Doc_Amount, 0), 0),
|
||||
NULLIF(ISNULL(I.Doc_Price, 0) * ISNULL(I.Qty1, 0), 0),
|
||||
0
|
||||
)
|
||||
) Amount
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 Rate
|
||||
FROM AllExchangeRates WITH(NOLOCK)
|
||||
WHERE CurrencyCode = 'USD'
|
||||
AND RelationCurrencyCode = 'TRY'
|
||||
AND ExchangeTypeCode = 6
|
||||
AND Rate > 0
|
||||
AND Date <= CAST(I.InvoiceDate AS date)
|
||||
ORDER BY Date DESC
|
||||
) UsdRate
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 Rate
|
||||
FROM AllExchangeRates WITH(NOLOCK)
|
||||
WHERE CurrencyCode = Amount.DocCurrencyCode
|
||||
AND RelationCurrencyCode = 'TRY'
|
||||
AND ExchangeTypeCode = 6
|
||||
AND Rate > 0
|
||||
AND Date <= CAST(I.InvoiceDate AS date)
|
||||
ORDER BY Date DESC
|
||||
) CurRate
|
||||
WHERE I.InvoiceDate >= @p1
|
||||
AND I.InvoiceDate < DATEADD(DAY, 1, @p2)
|
||||
AND I.ItemTypeCode = 1
|
||||
@@ -449,7 +485,7 @@ SalesAgg AS (
|
||||
SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '179 days') AS sales_usd_180d,
|
||||
SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '359 days') AS sales_usd_365d,
|
||||
SUM(sales_usd) FILTER (WHERE sales_date >= DATE '2022-01-01') AS sales_usd_total,
|
||||
COUNT(DISTINCT NULLIF(customer_code, '-')) FILTER (WHERE sales_date >= $1::date - INTERVAL '89 days') AS customer_count_90d,
|
||||
COUNT(DISTINCT NULLIF(customer_code, '-')) FILTER (WHERE sales_date >= $1::date - INTERVAL '89 days' AND COALESCE(sales_usd, 0) > 0) AS customer_count_90d,
|
||||
MAX(sales_date) AS last_sale_date,
|
||||
MAX(last_ref_number) AS last_ref_number
|
||||
FROM mk_product_performance_sales_daily
|
||||
@@ -566,9 +602,9 @@ Spread AS (
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
COUNT(DISTINCT market_key) AS market_count_90d
|
||||
COUNT(DISTINCT NULLIF(NULLIF(market_key, 'STOK'), '')) AS market_count_90d
|
||||
FROM SalesAgg
|
||||
WHERE COALESCE(sales_qty_90d, 0) > 0
|
||||
WHERE COALESCE(sales_usd_90d, 0) > 0
|
||||
GROUP BY product_code, color_code, yaka_kodu
|
||||
),
|
||||
Market AS (
|
||||
@@ -622,13 +658,15 @@ SELECT
|
||||
COALESCE(gross_profit_usd_90d, 0), COALESCE(gross_profit_usd_180d, 0), COALESCE(gross_margin_90d, 0), COALESCE(gross_margin_180d, 0),
|
||||
COALESCE(unit_profit_cost_90d, 0), COALESCE(unit_profit_cost_180d, 0), COALESCE(unit_profit_base_90d, 0), COALESCE(unit_profit_base_180d, 0), COALESCE(market_count_90d, 0), COALESCE(customer_count_90d, 0),
|
||||
COALESCE(sales_index_90d, 0), COALESCE(price_index_90d, 0), COALESCE(margin_index_90d, 0),
|
||||
ROUND(
|
||||
LEAST(35, COALESCE(sales_index_90d, 0) * 18)
|
||||
+ LEAST(25, GREATEST(COALESCE(gross_margin_90d, 0), 0) * 50)
|
||||
+ LEAST(20, COALESCE(customer_count_90d, 0) * 2)
|
||||
+ LEAST(10, COALESCE(market_count_90d, 0) * 3)
|
||||
+ CASE WHEN COALESCE(stock_days_90d, 0) BETWEEN 10 AND 90 THEN 10 WHEN COALESCE(stock_days_90d, 0) > 180 THEN -10 ELSE 0 END
|
||||
, 4) AS performance_score,
|
||||
CASE WHEN COALESCE(sales_usd_90d, 0) <= 0 THEN 1 ELSE
|
||||
ROUND(
|
||||
LEAST(35, COALESCE(sales_index_90d, 0) * 18)
|
||||
+ LEAST(25, GREATEST(COALESCE(gross_margin_90d, 0), 0) * 50)
|
||||
+ LEAST(20, COALESCE(customer_count_90d, 0) * 2)
|
||||
+ LEAST(10, COALESCE(market_count_90d, 0) * 3)
|
||||
+ CASE WHEN COALESCE(stock_days_90d, 0) BETWEEN 10 AND 90 THEN 10 WHEN COALESCE(stock_days_90d, 0) > 180 THEN -10 ELSE 0 END
|
||||
, 4)
|
||||
END AS performance_score,
|
||||
CASE
|
||||
WHEN COALESCE(sales_index_90d,0) >= 1.25 AND COALESCE(gross_margin_90d,0) >= 0.25 THEN 'YILDIZ_URUN'
|
||||
WHEN COALESCE(stock_qty,0) <= 0 AND COALESCE(sales_qty_90d,0) > 0 THEN 'STOKSUZ_TALEP'
|
||||
|
||||
Reference in New Issue
Block a user