ui: add B2B olmayan stok (orphans) page
This commit is contained in:
@@ -422,12 +422,14 @@ SalesAgg AS (
|
||||
MAX(urun_alt_grubu) AS urun_alt_grubu,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '29 days') AS sales_qty_30d,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '89 days') AS sales_qty_90d,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '179 days') AS sales_qty_180d,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '364 days') AS sales_qty_365d,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '729 days') AS sales_qty_730d,
|
||||
SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '29 days') AS sales_usd_30d,
|
||||
SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '89 days') AS sales_usd_90d,
|
||||
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 '364 days') AS sales_usd_365d,
|
||||
SUM(customer_count) 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') 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
|
||||
@@ -439,8 +441,8 @@ Scope AS (
|
||||
SELECT
|
||||
product_code, color_code, yaka_kodu, market_key,
|
||||
item_description, kategori, seri, yas_grubu, askili_yan, urun_ilk_grubu, urun_ana_grubu, urun_alt_grubu,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_365d, sales_qty_730d,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_365d,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_180d, sales_qty_365d, sales_qty_730d,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_180d, sales_usd_365d,
|
||||
customer_count_90d, last_sale_date, last_ref_number
|
||||
FROM SalesAgg
|
||||
UNION ALL
|
||||
@@ -459,10 +461,12 @@ Scope AS (
|
||||
'' AS urun_alt_grubu,
|
||||
0 AS sales_qty_30d,
|
||||
0 AS sales_qty_90d,
|
||||
0 AS sales_qty_180d,
|
||||
0 AS sales_qty_365d,
|
||||
0 AS sales_qty_730d,
|
||||
0 AS sales_usd_30d,
|
||||
0 AS sales_usd_90d,
|
||||
0 AS sales_usd_180d,
|
||||
0 AS sales_usd_365d,
|
||||
0 AS customer_count_90d,
|
||||
NULL::date AS last_sale_date,
|
||||
@@ -485,15 +489,35 @@ Base AS (
|
||||
COALESCE(pd.base_price_usd, 0) AS base_price_usd,
|
||||
COALESCE(pd.base_price_try, 0) AS base_price_try,
|
||||
COALESCE(s.sales_qty_90d, 0) / 90.0 AS avg_daily_sales_90d,
|
||||
COALESCE(s.sales_qty_180d, 0) / 180.0 AS avg_daily_sales_180d,
|
||||
CASE WHEN COALESCE(s.sales_qty_90d, 0) = 0 THEN 0 ELSE COALESCE(s.sales_usd_90d, 0) / NULLIF(s.sales_qty_90d, 0) END AS avg_price_usd_90d,
|
||||
CASE WHEN COALESCE(s.sales_qty_180d, 0) = 0 THEN 0 ELSE COALESCE(s.sales_usd_180d, 0) / NULLIF(s.sales_qty_180d, 0) END AS avg_price_usd_180d,
|
||||
COALESCE(s.sales_usd_90d, 0) - (COALESCE(s.sales_qty_90d, 0) * COALESCE(pd.cost_price_usd, 0)) AS gross_profit_usd_90d,
|
||||
COALESCE(s.sales_usd_180d, 0) - (COALESCE(s.sales_qty_180d, 0) * COALESCE(pd.cost_price_usd, 0)) AS gross_profit_usd_180d,
|
||||
CASE WHEN COALESCE(s.sales_usd_90d, 0) = 0 THEN 0
|
||||
ELSE (COALESCE(s.sales_usd_90d, 0) - (COALESCE(s.sales_qty_90d, 0) * COALESCE(pd.cost_price_usd, 0))) / NULLIF(s.sales_usd_90d, 0)
|
||||
END AS gross_margin_90d
|
||||
END AS gross_margin_90d,
|
||||
CASE WHEN COALESCE(s.sales_usd_180d, 0) = 0 THEN 0
|
||||
ELSE (COALESCE(s.sales_usd_180d, 0) - (COALESCE(s.sales_qty_180d, 0) * COALESCE(pd.cost_price_usd, 0))) / NULLIF(s.sales_usd_180d, 0)
|
||||
END AS gross_margin_180d,
|
||||
CASE WHEN COALESCE(s.sales_qty_90d, 0) = 0 THEN 0 ELSE (COALESCE(s.sales_usd_90d, 0) / NULLIF(s.sales_qty_90d, 0)) - COALESCE(pd.cost_price_usd, 0) END AS unit_profit_cost_90d,
|
||||
CASE WHEN COALESCE(s.sales_qty_180d, 0) = 0 THEN 0 ELSE (COALESCE(s.sales_usd_180d, 0) / NULLIF(s.sales_qty_180d, 0)) - COALESCE(pd.cost_price_usd, 0) END AS unit_profit_cost_180d,
|
||||
CASE WHEN COALESCE(s.sales_qty_90d, 0) = 0 THEN 0 ELSE (COALESCE(s.sales_usd_90d, 0) / NULLIF(s.sales_qty_90d, 0)) - COALESCE(pd.base_price_usd, 0) END AS unit_profit_base_90d,
|
||||
CASE WHEN COALESCE(s.sales_qty_180d, 0) = 0 THEN 0 ELSE (COALESCE(s.sales_usd_180d, 0) / NULLIF(s.sales_qty_180d, 0)) - COALESCE(pd.base_price_usd, 0) END AS unit_profit_base_180d
|
||||
FROM Scope s
|
||||
LEFT JOIN LatestStock ls ON ls.product_code=s.product_code AND ls.color_code=s.color_code AND ls.yaka_kodu=s.yaka_kodu
|
||||
LEFT JOIN mk_product_performance_price_dim pd ON pd.product_code=s.product_code
|
||||
),
|
||||
Spread AS (
|
||||
SELECT
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
COUNT(DISTINCT market_key) AS market_count_90d
|
||||
FROM SalesAgg
|
||||
WHERE COALESCE(sales_qty_90d, 0) > 0
|
||||
GROUP BY product_code, color_code, yaka_kodu
|
||||
),
|
||||
Market AS (
|
||||
SELECT
|
||||
market_key,
|
||||
@@ -506,20 +530,24 @@ Market AS (
|
||||
Scored AS (
|
||||
SELECT
|
||||
b.*,
|
||||
COALESCE(sp.market_count_90d, 0) AS market_count_90d,
|
||||
CASE WHEN b.avg_daily_sales_90d = 0 THEN 0 ELSE b.stock_qty / NULLIF(b.avg_daily_sales_90d, 0) END AS stock_days_90d,
|
||||
CASE WHEN b.avg_daily_sales_180d = 0 THEN 0 ELSE b.stock_qty / NULLIF(b.avg_daily_sales_180d, 0) END AS stock_days_180d,
|
||||
CASE WHEN COALESCE(m.market_avg_sales_qty_90d, 0) = 0 THEN 0 ELSE b.sales_qty_90d / NULLIF(m.market_avg_sales_qty_90d, 0) END AS sales_index_90d,
|
||||
CASE WHEN COALESCE(m.market_avg_price_usd_90d, 0) = 0 THEN 0 ELSE b.avg_price_usd_90d / NULLIF(m.market_avg_price_usd_90d, 0) END AS price_index_90d,
|
||||
CASE WHEN COALESCE(m.market_avg_margin_90d, 0) = 0 THEN 0 ELSE b.gross_margin_90d / NULLIF(m.market_avg_margin_90d, 0) END AS margin_index_90d
|
||||
FROM Base b
|
||||
LEFT JOIN Market m ON m.market_key=b.market_key
|
||||
LEFT JOIN Spread sp ON sp.product_code=b.product_code AND sp.color_code=b.color_code AND sp.yaka_kodu=b.yaka_kodu
|
||||
)
|
||||
INSERT INTO mk_product_performance_kpi_daily (
|
||||
kpi_date, product_code, color_code, yaka_kodu, item_description,
|
||||
kategori, seri, yas_grubu, askili_yan, urun_ilk_grubu, urun_ana_grubu, urun_alt_grubu, market_key, stock_qty,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_365d, sales_qty_730d,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_365d, avg_daily_sales_90d,
|
||||
stock_days_90d, avg_price_usd_90d, cost_price_usd, base_price_usd, base_price_try,
|
||||
gross_profit_usd_90d, gross_margin_90d, customer_count_90d,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_180d, sales_qty_365d, sales_qty_730d,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_180d, sales_usd_365d, avg_daily_sales_90d, avg_daily_sales_180d,
|
||||
stock_days_90d, stock_days_180d, avg_price_usd_90d, avg_price_usd_180d, cost_price_usd, base_price_usd, base_price_try,
|
||||
gross_profit_usd_90d, gross_profit_usd_180d, gross_margin_90d, gross_margin_180d,
|
||||
unit_profit_cost_90d, unit_profit_cost_180d, unit_profit_base_90d, unit_profit_base_180d, market_count_90d, customer_count_90d,
|
||||
sales_index_90d, price_index_90d, margin_index_90d, performance_score,
|
||||
performance_bucket, recommendation, last_sale_date, last_ref_number, updated_at
|
||||
)
|
||||
@@ -527,16 +555,18 @@ SELECT
|
||||
$1::date,
|
||||
product_code, color_code, yaka_kodu, item_description,
|
||||
kategori, seri, yas_grubu, askili_yan, urun_ilk_grubu, urun_ana_grubu, urun_alt_grubu, market_key, stock_qty,
|
||||
COALESCE(sales_qty_30d, 0), COALESCE(sales_qty_90d, 0), COALESCE(sales_qty_365d, 0), COALESCE(sales_qty_730d, 0),
|
||||
COALESCE(sales_usd_30d, 0), COALESCE(sales_usd_90d, 0), COALESCE(sales_usd_365d, 0), COALESCE(avg_daily_sales_90d, 0),
|
||||
COALESCE(stock_days_90d, 0), COALESCE(avg_price_usd_90d, 0), COALESCE(cost_price_usd, 0), COALESCE(base_price_usd, 0), COALESCE(base_price_try, 0),
|
||||
COALESCE(gross_profit_usd_90d, 0), COALESCE(gross_margin_90d, 0), COALESCE(customer_count_90d, 0),
|
||||
COALESCE(sales_qty_30d, 0), COALESCE(sales_qty_90d, 0), COALESCE(sales_qty_180d, 0), COALESCE(sales_qty_365d, 0), COALESCE(sales_qty_730d, 0),
|
||||
COALESCE(sales_usd_30d, 0), COALESCE(sales_usd_90d, 0), COALESCE(sales_usd_180d, 0), COALESCE(sales_usd_365d, 0), COALESCE(avg_daily_sales_90d, 0), COALESCE(avg_daily_sales_180d, 0),
|
||||
COALESCE(stock_days_90d, 0), COALESCE(stock_days_180d, 0), COALESCE(avg_price_usd_90d, 0), COALESCE(avg_price_usd_180d, 0), COALESCE(cost_price_usd, 0), COALESCE(base_price_usd, 0), COALESCE(base_price_try, 0),
|
||||
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(40, COALESCE(sales_index_90d, 0) * 20)
|
||||
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)
|
||||
+ CASE WHEN COALESCE(stock_days_90d, 0) BETWEEN 10 AND 90 THEN 15 WHEN COALESCE(stock_days_90d, 0) > 180 THEN -10 ELSE 0 END
|
||||
+ 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_index_90d,0) >= 1.25 AND COALESCE(gross_margin_90d,0) >= 0.25 THEN 'YILDIZ_URUN'
|
||||
|
||||
Reference in New Issue
Block a user