product performance grouped kpi improvements
This commit is contained in:
@@ -20,14 +20,24 @@ type ProductPerformanceRow struct {
|
||||
SalesQty180 float64 `json:"sales_qty_180d"`
|
||||
SalesQty365 float64 `json:"sales_qty_365d"`
|
||||
SalesQty730 float64 `json:"sales_qty_730d"`
|
||||
SalesQtyTotal float64 `json:"sales_qty_total"`
|
||||
SalesUSD30 float64 `json:"sales_usd_30d"`
|
||||
SalesUSD90 float64 `json:"sales_usd_90d"`
|
||||
SalesUSD180 float64 `json:"sales_usd_180d"`
|
||||
SalesUSD365 float64 `json:"sales_usd_365d"`
|
||||
SalesUSDTotal float64 `json:"sales_usd_total"`
|
||||
AvgDailySales90 float64 `json:"avg_daily_sales_90d"`
|
||||
AvgDailySales180 float64 `json:"avg_daily_sales_180d"`
|
||||
AvgDailySales365 float64 `json:"avg_daily_sales_365d"`
|
||||
AvgDailySalesTotal float64 `json:"avg_daily_sales_total"`
|
||||
StockDays90 float64 `json:"stock_days_90d"`
|
||||
StockDays180 float64 `json:"stock_days_180d"`
|
||||
StockDays365 float64 `json:"stock_days_365d"`
|
||||
StockDaysTotal float64 `json:"stock_days_total"`
|
||||
StockTurnover90 float64 `json:"stock_turnover_90d"`
|
||||
StockTurnover180 float64 `json:"stock_turnover_180d"`
|
||||
StockTurnover365 float64 `json:"stock_turnover_365d"`
|
||||
StockTurnoverTotal float64 `json:"stock_turnover_total"`
|
||||
AvgPriceUSD90 float64 `json:"avg_price_usd_90d"`
|
||||
AvgPriceUSD180 float64 `json:"avg_price_usd_180d"`
|
||||
CostPriceUSD float64 `json:"cost_price_usd"`
|
||||
|
||||
@@ -505,9 +505,19 @@ UPDATE mk_product_performance_kpi_daily
|
||||
SET askili_yan = '', updated_at = now()
|
||||
WHERE btrim(askili_yan) = '-'`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS sales_qty_180d NUMERIC(18,4) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS sales_qty_total NUMERIC(18,4) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS sales_usd_180d NUMERIC(18,4) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS sales_usd_total NUMERIC(18,4) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS avg_daily_sales_180d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS avg_daily_sales_365d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS avg_daily_sales_total NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_days_180d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_days_365d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_days_total NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_turnover_90d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_turnover_180d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_turnover_365d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS stock_turnover_total NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS avg_price_usd_180d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS gross_profit_usd_180d NUMERIC(18,4) NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS gross_margin_180d NUMERIC(18,6) NOT NULL DEFAULT 0`,
|
||||
@@ -1073,9 +1083,12 @@ func ListProductPerformance(ctx context.Context, pg *sql.DB, f ProductPerformanc
|
||||
SELECT
|
||||
to_char(kpi_date,'YYYY-MM-DD'), 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_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,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_180d, sales_qty_365d, sales_qty_730d, sales_qty_total,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_180d, sales_usd_365d, sales_usd_total,
|
||||
avg_daily_sales_90d, avg_daily_sales_180d, avg_daily_sales_365d, avg_daily_sales_total,
|
||||
stock_days_90d, stock_days_180d, stock_days_365d, stock_days_total,
|
||||
stock_turnover_90d, stock_turnover_180d, stock_turnover_365d, stock_turnover_total,
|
||||
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,
|
||||
@@ -1095,9 +1108,12 @@ LIMIT $`+fmt.Sprint(len(args)-1)+` OFFSET $`+fmt.Sprint(len(args)), args...)
|
||||
if err := rows.Scan(
|
||||
&r.KpiDate, &r.ProductCode, &r.ColorCode, &r.YakaKodu, &r.ItemDescription,
|
||||
&r.Kategori, &r.Seri, &r.YasGrubu, &r.AskiliYan, &r.UrunIlkGrubu, &r.UrunAnaGrubu, &r.UrunAltGrubu, &r.MarketKey, &r.StockQty,
|
||||
&r.SalesQty30, &r.SalesQty90, &r.SalesQty180, &r.SalesQty365, &r.SalesQty730,
|
||||
&r.SalesUSD30, &r.SalesUSD90, &r.SalesUSD180, &r.SalesUSD365, &r.AvgDailySales90, &r.AvgDailySales180,
|
||||
&r.StockDays90, &r.StockDays180, &r.AvgPriceUSD90, &r.AvgPriceUSD180, &r.CostPriceUSD, &r.BasePriceUSD, &r.BasePriceTRY,
|
||||
&r.SalesQty30, &r.SalesQty90, &r.SalesQty180, &r.SalesQty365, &r.SalesQty730, &r.SalesQtyTotal,
|
||||
&r.SalesUSD30, &r.SalesUSD90, &r.SalesUSD180, &r.SalesUSD365, &r.SalesUSDTotal,
|
||||
&r.AvgDailySales90, &r.AvgDailySales180, &r.AvgDailySales365, &r.AvgDailySalesTotal,
|
||||
&r.StockDays90, &r.StockDays180, &r.StockDays365, &r.StockDaysTotal,
|
||||
&r.StockTurnover90, &r.StockTurnover180, &r.StockTurnover365, &r.StockTurnoverTotal,
|
||||
&r.AvgPriceUSD90, &r.AvgPriceUSD180, &r.CostPriceUSD, &r.BasePriceUSD, &r.BasePriceTRY,
|
||||
&r.GrossProfitUSD90, &r.GrossProfitUSD180, &r.GrossMargin90, &r.GrossMargin180,
|
||||
&r.UnitProfitCost90, &r.UnitProfitCost180, &r.UnitProfitBase90, &r.UnitProfitBase180, &r.MarketCount90, &r.CustomerCount90, &r.SalesIndex90,
|
||||
&r.PriceIndex90, &r.MarginIndex90, &r.PerformanceScore, &r.PerformanceBucket,
|
||||
@@ -1232,6 +1248,16 @@ StockAgg AS (
|
||||
WHERE s.stock_date = (SELECT stock_date FROM LatestStockDate)
|
||||
GROUP BY s.product_code, s.color_code, s.yaka_kodu
|
||||
),
|
||||
StockTotalStart AS (
|
||||
SELECT DISTINCT ON (s.product_code, s.color_code, s.yaka_kodu)
|
||||
s.product_code,
|
||||
s.color_code,
|
||||
s.yaka_kodu,
|
||||
s.stock_qty
|
||||
FROM mk_product_performance_stock_daily s
|
||||
WHERE s.stock_date <= DATE '2022-01-01'
|
||||
ORDER BY s.product_code, s.color_code, s.yaka_kodu, s.stock_date DESC
|
||||
),
|
||||
Dim AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code,
|
||||
@@ -1354,7 +1380,7 @@ Scored AS (
|
||||
b.sales_qty_total / GREATEST(1, (Bounds.period_end - Bounds.period_start + 1)) AS avg_daily_sales_total,
|
||||
CASE
|
||||
WHEN b.sales_qty_total <= 0 THEN 9999
|
||||
ELSE COALESCE(st.stock_qty, 0) / NULLIF(b.sales_qty_total / GREATEST(1, (Bounds.period_end - Bounds.period_start + 1)), 0)
|
||||
ELSE ((COALESCE(st_start.stock_qty, 0) + COALESCE(st.stock_qty, 0)) / 2.0) / NULLIF(b.sales_qty_total / GREATEST(1, (Bounds.period_end - Bounds.period_start + 1)), 0)
|
||||
END AS stock_days_total,
|
||||
CASE WHEN b.sales_qty_total <= 0 THEN 0 ELSE b.sales_usd_total / NULLIF(b.sales_qty_total,0) END AS avg_price_usd_total,
|
||||
COALESCE(pd.cost_price_usd,0) AS cost_price_usd,
|
||||
@@ -1379,6 +1405,10 @@ Scored AS (
|
||||
ON st.product_code = b.product_code
|
||||
AND st.color_code = b.color_code
|
||||
AND st.yaka_kodu = b.yaka_kodu
|
||||
LEFT JOIN StockTotalStart st_start
|
||||
ON st_start.product_code = b.product_code
|
||||
AND st_start.color_code = b.color_code
|
||||
AND st_start.yaka_kodu = b.yaka_kodu
|
||||
LEFT JOIN mk_product_performance_price_dim pd ON pd.product_code = b.product_code
|
||||
LEFT JOIN Spread sp
|
||||
ON sp.product_code = b.product_code
|
||||
@@ -2548,6 +2578,46 @@ StockAgg AS (
|
||||
WHERE stock_date = (SELECT MAX(stock_date) FROM mk_product_performance_stock_daily)
|
||||
GROUP BY product_code, color_code, yaka_kodu
|
||||
),
|
||||
Stock90Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= current_date - INTERVAL '89 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock180Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= current_date - INTERVAL '179 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock365Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= current_date - INTERVAL '359 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
StockTotalStart AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code,
|
||||
color_code,
|
||||
yaka_kodu,
|
||||
stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= DATE '2022-01-01'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Agg AS (
|
||||
SELECT
|
||||
$2::text AS breakdown,
|
||||
@@ -2567,6 +2637,10 @@ Agg AS (
|
||||
%s,
|
||||
COUNT(DISTINCT product_code) AS product_count,
|
||||
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,
|
||||
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,
|
||||
@@ -2637,11 +2711,19 @@ Agg AS (
|
||||
s.*,
|
||||
COALESCE(pd.base_price_usd,0) AS base_price_usd,
|
||||
COALESCE(pd.cost_price_usd,0) AS cost_price_usd,
|
||||
COALESCE(st.stock_qty,0) AS stock_qty
|
||||
COALESCE(st.stock_qty,0) AS stock_qty,
|
||||
(COALESCE(s90.stock_qty,0) + COALESCE(st.stock_qty,0)) / 2.0 AS avg_stock_90d,
|
||||
(COALESCE(s180.stock_qty,0) + COALESCE(st.stock_qty,0)) / 2.0 AS avg_stock_180d,
|
||||
(COALESCE(s365.stock_qty,0) + COALESCE(st.stock_qty,0)) / 2.0 AS avg_stock_365d,
|
||||
(COALESCE(stotal.stock_qty,0) + COALESCE(st.stock_qty,0)) / 2.0 AS avg_stock_total
|
||||
FROM mk_product_performance_sales_daily s
|
||||
LEFT JOIN mk_product_performance_price_dim pd ON pd.product_code = s.product_code
|
||||
LEFT JOIN LatestKPI k ON k.product_code = s.product_code AND k.color_code = s.color_code AND k.yaka_kodu = s.yaka_kodu
|
||||
LEFT JOIN StockAgg st ON st.product_code = s.product_code AND st.color_code = s.color_code AND st.yaka_kodu = s.yaka_kodu
|
||||
LEFT JOIN Stock90Start s90 ON s90.product_code = s.product_code AND s90.color_code = s.color_code AND s90.yaka_kodu = s.yaka_kodu
|
||||
LEFT JOIN Stock180Start s180 ON s180.product_code = s.product_code AND s180.color_code = s.color_code AND s180.yaka_kodu = s.yaka_kodu
|
||||
LEFT JOIN Stock365Start s365 ON s365.product_code = s.product_code AND s365.color_code = s.color_code AND s365.yaka_kodu = s.yaka_kodu
|
||||
LEFT JOIN StockTotalStart stotal ON stotal.product_code = s.product_code AND stotal.color_code = s.color_code AND stotal.yaka_kodu = s.yaka_kodu
|
||||
) s
|
||||
WHERE sales_date >= DATE '2022-01-01'
|
||||
GROUP BY %s
|
||||
@@ -2738,10 +2820,10 @@ SELECT
|
||||
gross_profit_cost_usd_total,
|
||||
gross_margin_base_total,
|
||||
gross_margin_cost_total,
|
||||
CASE WHEN stock_qty > 0 THEN sales_qty_90d / NULLIF(stock_qty,0) ELSE 0 END AS stock_turnover_90d,
|
||||
CASE WHEN stock_qty > 0 THEN sales_qty_180d / NULLIF(stock_qty,0) ELSE 0 END AS stock_turnover_180d,
|
||||
CASE WHEN stock_qty > 0 THEN sales_qty_365d / NULLIF(stock_qty,0) ELSE 0 END AS stock_turnover_365d,
|
||||
CASE WHEN stock_qty > 0 THEN sales_qty_total / NULLIF(stock_qty,0) ELSE 0 END AS stock_turnover_total,
|
||||
CASE WHEN avg_stock_90d > 0 THEN sales_qty_90d / NULLIF(avg_stock_90d,0) ELSE 0 END AS stock_turnover_90d,
|
||||
CASE WHEN avg_stock_180d > 0 THEN sales_qty_180d / NULLIF(avg_stock_180d,0) ELSE 0 END AS stock_turnover_180d,
|
||||
CASE WHEN avg_stock_365d > 0 THEN sales_qty_365d / NULLIF(avg_stock_365d,0) ELSE 0 END AS stock_turnover_365d,
|
||||
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
|
||||
@@ -2786,7 +2868,7 @@ SELECT
|
||||
+ 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 stock_qty > 0 THEN sales_qty_90d / NULLIF(stock_qty,0) ELSE 0 END) * 5),
|
||||
+ LEAST(10, (CASE WHEN avg_stock_90d > 0 THEN sales_qty_90d / NULLIF(avg_stock_90d,0) ELSE 0 END) * 5),
|
||||
4
|
||||
)
|
||||
END AS performance_score,
|
||||
@@ -2982,9 +3064,11 @@ SELECT jsonb_build_object(
|
||||
'sales_qty_90d', sales_qty_90d,
|
||||
'sales_qty_180d', sales_qty_180d,
|
||||
'sales_qty_365d', sales_qty_365d,
|
||||
'sales_qty_total', sales_qty_total,
|
||||
'sales_usd_90d', sales_usd_90d,
|
||||
'sales_usd_180d', sales_usd_180d,
|
||||
'sales_usd_365d', sales_usd_365d,
|
||||
'sales_usd_total', sales_usd_total,
|
||||
'avg_price_usd_90d', avg_price_usd_90d,
|
||||
'avg_price_usd_180d', avg_price_usd_180d,
|
||||
'cost_price_usd', cost_price_usd,
|
||||
@@ -3006,9 +3090,14 @@ SELECT jsonb_build_object(
|
||||
'performance_score', performance_score,
|
||||
'performance_bucket', performance_bucket,
|
||||
'idle_cost_usd', idle_cost_usd,
|
||||
'stock_turnover_90d', CASE WHEN stock_qty > 0 THEN sales_qty_90d / NULLIF(stock_qty,0) ELSE 0 END,
|
||||
'stock_turnover_180d', CASE WHEN stock_qty > 0 THEN sales_qty_180d / NULLIF(stock_qty,0) ELSE 0 END,
|
||||
'stock_turnover_365d', CASE WHEN stock_qty > 0 THEN sales_qty_365d / NULLIF(stock_qty,0) ELSE 0 END
|
||||
'stock_days_90d', stock_days_90d,
|
||||
'stock_days_180d', stock_days_180d,
|
||||
'stock_days_365d', stock_days_365d,
|
||||
'stock_days_total', stock_days_total,
|
||||
'stock_turnover_90d', CASE WHEN avg_stock_90d > 0 THEN sales_qty_90d / NULLIF(avg_stock_90d,0) ELSE 0 END,
|
||||
'stock_turnover_180d', CASE WHEN avg_stock_180d > 0 THEN sales_qty_180d / NULLIF(avg_stock_180d,0) ELSE 0 END,
|
||||
'stock_turnover_365d', CASE WHEN avg_stock_365d > 0 THEN sales_qty_365d / NULLIF(avg_stock_365d,0) ELSE 0 END,
|
||||
'stock_turnover_total', CASE WHEN avg_stock_total > 0 THEN sales_qty_total / NULLIF(avg_stock_total,0) ELSE 0 END
|
||||
) AS row_json
|
||||
FROM (
|
||||
SELECT
|
||||
@@ -3028,12 +3117,22 @@ FROM (
|
||||
COALESCE((ARRAY_AGG(NULLIF(urun_alt_grubu,'') ORDER BY performance_score DESC NULLS LAST))[1], '') AS urun_alt_grubu,
|
||||
COALESCE((ARRAY_AGG(NULLIF(market_key,'') ORDER BY performance_score DESC NULLS LAST))[1], '') AS market_key,
|
||||
COALESCE(SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END),0) AS stock_qty,
|
||||
COALESCE(SUM(CASE WHEN stock_variant_rank = 1 THEN avg_stock_90d ELSE 0 END),0) AS avg_stock_90d,
|
||||
COALESCE(SUM(CASE WHEN stock_variant_rank = 1 THEN avg_stock_180d ELSE 0 END),0) AS avg_stock_180d,
|
||||
COALESCE(SUM(CASE WHEN stock_variant_rank = 1 THEN avg_stock_365d ELSE 0 END),0) AS avg_stock_365d,
|
||||
COALESCE(SUM(CASE WHEN stock_variant_rank = 1 THEN avg_stock_total ELSE 0 END),0) AS avg_stock_total,
|
||||
COALESCE(SUM(sales_qty_90d),0) AS sales_qty_90d,
|
||||
COALESCE(SUM(sales_qty_180d),0) AS sales_qty_180d,
|
||||
COALESCE(SUM(sales_qty_365d),0) AS sales_qty_365d,
|
||||
COALESCE(SUM(sales_qty_total),0) AS sales_qty_total,
|
||||
COALESCE(SUM(sales_usd_90d),0) AS sales_usd_90d,
|
||||
COALESCE(SUM(sales_usd_180d),0) AS sales_usd_180d,
|
||||
COALESCE(SUM(sales_usd_365d),0) AS sales_usd_365d,
|
||||
COALESCE(SUM(sales_usd_total),0) AS sales_usd_total,
|
||||
CASE WHEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END) > 0 THEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_days_90d * stock_qty ELSE 0 END) / NULLIF(SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END),0) ELSE 0 END AS stock_days_90d,
|
||||
CASE WHEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END) > 0 THEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_days_180d * stock_qty ELSE 0 END) / NULLIF(SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END),0) ELSE 0 END AS stock_days_180d,
|
||||
CASE WHEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END) > 0 THEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_days_365d * stock_qty ELSE 0 END) / NULLIF(SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END),0) ELSE 0 END AS stock_days_365d,
|
||||
CASE WHEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END) > 0 THEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_days_total * stock_qty ELSE 0 END) / NULLIF(SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END),0) ELSE 0 END AS stock_days_total,
|
||||
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(sales_usd_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS avg_price_usd_90d,
|
||||
CASE WHEN SUM(sales_qty_180d) > 0 THEN SUM(sales_usd_180d) / NULLIF(SUM(sales_qty_180d),0) ELSE 0 END AS avg_price_usd_180d,
|
||||
CASE WHEN SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END) > 0 THEN SUM(CASE WHEN stock_variant_rank = 1 THEN cost_price_usd * stock_qty ELSE 0 END) / NULLIF(SUM(CASE WHEN stock_variant_rank = 1 THEN stock_qty ELSE 0 END),0) ELSE 0 END AS cost_price_usd,
|
||||
@@ -3082,9 +3181,10 @@ func queryProductPerformanceSQLLeafRows(ctx context.Context, pg *sql.DB, mode st
|
||||
query := productPerformanceSQLSourceCTE(mode) + fmt.Sprintf(`
|
||||
SELECT to_jsonb(t) || jsonb_build_object(
|
||||
'row_key', 'leaf|' || product_code || '|' || color_code || '|' || yaka_kodu || '|' || market_key,
|
||||
'stock_turnover_90d', CASE WHEN stock_qty > 0 THEN sales_qty_90d / NULLIF(stock_qty,0) ELSE 0 END,
|
||||
'stock_turnover_180d', CASE WHEN stock_qty > 0 THEN sales_qty_180d / NULLIF(stock_qty,0) ELSE 0 END,
|
||||
'stock_turnover_365d', CASE WHEN stock_qty > 0 THEN sales_qty_365d / NULLIF(stock_qty,0) ELSE 0 END
|
||||
'stock_turnover_90d', CASE WHEN avg_stock_90d > 0 THEN sales_qty_90d / NULLIF(avg_stock_90d,0) ELSE 0 END,
|
||||
'stock_turnover_180d', CASE WHEN avg_stock_180d > 0 THEN sales_qty_180d / NULLIF(avg_stock_180d,0) ELSE 0 END,
|
||||
'stock_turnover_365d', CASE WHEN avg_stock_365d > 0 THEN sales_qty_365d / NULLIF(avg_stock_365d,0) ELSE 0 END,
|
||||
'stock_turnover_total', CASE WHEN avg_stock_total > 0 THEN sales_qty_total / NULLIF(avg_stock_total,0) ELSE 0 END
|
||||
) AS row_json
|
||||
FROM Source t
|
||||
%s
|
||||
@@ -3123,7 +3223,39 @@ func productPerformanceSQLSourceCTE(mode string) string {
|
||||
AND (performance_bucket = 'STOK_RISKI' OR COALESCE(sales_qty_90d,0) = 0 OR COALESCE(stock_days_90d,0) > 180)`
|
||||
}
|
||||
return `
|
||||
WITH Source AS (
|
||||
WITH LatestKPIDate AS (
|
||||
SELECT MAX(kpi_date) AS kpi_date
|
||||
FROM mk_product_performance_kpi_daily
|
||||
),
|
||||
Stock90Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily, LatestKPIDate
|
||||
WHERE stock_date <= LatestKPIDate.kpi_date - INTERVAL '89 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock180Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily, LatestKPIDate
|
||||
WHERE stock_date <= LatestKPIDate.kpi_date - INTERVAL '179 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock365Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily, LatestKPIDate
|
||||
WHERE stock_date <= LatestKPIDate.kpi_date - INTERVAL '359 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
StockTotalStart AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= DATE '2022-01-01'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Source AS (
|
||||
SELECT
|
||||
product_code,
|
||||
color_code,
|
||||
@@ -3142,12 +3274,22 @@ WITH Source AS (
|
||||
urun_alt_grubu,
|
||||
market_key,
|
||||
COALESCE(stock_qty,0) AS stock_qty,
|
||||
(COALESCE((SELECT s.stock_qty FROM Stock90Start s WHERE s.product_code = mk_product_performance_kpi_daily.product_code AND s.color_code = mk_product_performance_kpi_daily.color_code AND s.yaka_kodu = mk_product_performance_kpi_daily.yaka_kodu),0) + COALESCE(stock_qty,0)) / 2.0 AS avg_stock_90d,
|
||||
(COALESCE((SELECT s.stock_qty FROM Stock180Start s WHERE s.product_code = mk_product_performance_kpi_daily.product_code AND s.color_code = mk_product_performance_kpi_daily.color_code AND s.yaka_kodu = mk_product_performance_kpi_daily.yaka_kodu),0) + COALESCE(stock_qty,0)) / 2.0 AS avg_stock_180d,
|
||||
(COALESCE((SELECT s.stock_qty FROM Stock365Start s WHERE s.product_code = mk_product_performance_kpi_daily.product_code AND s.color_code = mk_product_performance_kpi_daily.color_code AND s.yaka_kodu = mk_product_performance_kpi_daily.yaka_kodu),0) + COALESCE(stock_qty,0)) / 2.0 AS avg_stock_365d,
|
||||
(COALESCE((SELECT s.stock_qty FROM StockTotalStart s WHERE s.product_code = mk_product_performance_kpi_daily.product_code AND s.color_code = mk_product_performance_kpi_daily.color_code AND s.yaka_kodu = mk_product_performance_kpi_daily.yaka_kodu),0) + COALESCE(stock_qty,0)) / 2.0 AS avg_stock_total,
|
||||
COALESCE(sales_qty_90d,0) AS sales_qty_90d,
|
||||
COALESCE(sales_qty_180d,0) AS sales_qty_180d,
|
||||
COALESCE(sales_qty_365d,0) AS sales_qty_365d,
|
||||
COALESCE(sales_qty_total,0) AS sales_qty_total,
|
||||
COALESCE(sales_usd_90d,0) AS sales_usd_90d,
|
||||
COALESCE(sales_usd_180d,0) AS sales_usd_180d,
|
||||
COALESCE(sales_usd_365d,0) AS sales_usd_365d,
|
||||
COALESCE(sales_usd_total,0) AS sales_usd_total,
|
||||
COALESCE(stock_days_90d,0) AS stock_days_90d,
|
||||
COALESCE(stock_days_180d,0) AS stock_days_180d,
|
||||
COALESCE(stock_days_365d,0) AS stock_days_365d,
|
||||
COALESCE(stock_days_total,0) AS stock_days_total,
|
||||
COALESCE(avg_price_usd_90d,0) AS avg_price_usd_90d,
|
||||
COALESCE(avg_price_usd_180d,0) AS avg_price_usd_180d,
|
||||
COALESCE(cost_price_usd,0) AS cost_price_usd,
|
||||
@@ -3430,7 +3572,7 @@ func deriveProductPerformanceGroupMetrics(out map[string]any, groupField string)
|
||||
sales := floatFromMap(out, "sales_usd_"+suffix)
|
||||
qty := floatFromMap(out, "sales_qty_"+suffix)
|
||||
stockQty := floatFromMap(out, "stock_qty")
|
||||
if stockQty > 0 {
|
||||
if _, exists := out["stock_turnover_"+suffix]; !exists && stockQty > 0 {
|
||||
out["stock_turnover_"+suffix] = qty / stockQty
|
||||
}
|
||||
if qty > 0 {
|
||||
@@ -4012,10 +4154,20 @@ func productPerformanceOrderBy(sortBy string, desc bool) string {
|
||||
"stock_qty": "stock_qty",
|
||||
"sales_qty_90d": "sales_qty_90d",
|
||||
"sales_qty_180d": "sales_qty_180d",
|
||||
"sales_qty_365d": "sales_qty_365d",
|
||||
"sales_qty_total": "sales_qty_total",
|
||||
"sales_usd_90d": "sales_usd_90d",
|
||||
"sales_usd_180d": "sales_usd_180d",
|
||||
"sales_usd_365d": "sales_usd_365d",
|
||||
"sales_usd_total": "sales_usd_total",
|
||||
"stock_days_90d": "stock_days_90d",
|
||||
"stock_days_180d": "stock_days_180d",
|
||||
"stock_days_365d": "stock_days_365d",
|
||||
"stock_days_total": "stock_days_total",
|
||||
"stock_turnover_90d": "stock_turnover_90d",
|
||||
"stock_turnover_180d": "stock_turnover_180d",
|
||||
"stock_turnover_365d": "stock_turnover_365d",
|
||||
"stock_turnover_total": "stock_turnover_total",
|
||||
"avg_price_usd_90d": "avg_price_usd_90d",
|
||||
"avg_price_usd_180d": "avg_price_usd_180d",
|
||||
"base_price_usd": "base_price_usd",
|
||||
|
||||
@@ -396,6 +396,34 @@ WITH LatestStock AS (
|
||||
WHERE stock_date <= $1
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock90Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= $1::date - INTERVAL '89 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock180Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= $1::date - INTERVAL '179 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
Stock365Start AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= $1::date - INTERVAL '359 days'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
StockTotalStart AS (
|
||||
SELECT DISTINCT ON (product_code, color_code, yaka_kodu)
|
||||
product_code, color_code, yaka_kodu, stock_qty
|
||||
FROM mk_product_performance_stock_daily
|
||||
WHERE stock_date <= DATE '2022-01-01'
|
||||
ORDER BY product_code, color_code, yaka_kodu, stock_date DESC
|
||||
),
|
||||
SalesAgg AS (
|
||||
SELECT
|
||||
product_code,
|
||||
@@ -415,15 +443,17 @@ SalesAgg AS (
|
||||
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 '359 days') AS sales_qty_365d,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '729 days') AS sales_qty_730d,
|
||||
SUM(sales_qty) FILTER (WHERE sales_date >= DATE '2022-01-01') AS sales_qty_total,
|
||||
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 '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,
|
||||
MAX(sales_date) AS last_sale_date,
|
||||
MAX(last_ref_number) AS last_ref_number
|
||||
FROM mk_product_performance_sales_daily
|
||||
WHERE sales_date >= $1::date - INTERVAL '729 days'
|
||||
WHERE sales_date >= DATE '2022-01-01'
|
||||
AND sales_date <= $1::date
|
||||
GROUP BY product_code, color_code, yaka_kodu, market_key
|
||||
),
|
||||
@@ -431,8 +461,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_180d, sales_qty_365d, sales_qty_730d,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_180d, sales_usd_365d,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_180d, sales_qty_365d, sales_qty_730d, sales_qty_total,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_180d, sales_usd_365d, sales_usd_total,
|
||||
customer_count_90d, last_sale_date, last_ref_number
|
||||
FROM SalesAgg
|
||||
UNION ALL
|
||||
@@ -454,10 +484,12 @@ Scope AS (
|
||||
0 AS sales_qty_180d,
|
||||
0 AS sales_qty_365d,
|
||||
0 AS sales_qty_730d,
|
||||
0 AS sales_qty_total,
|
||||
0 AS sales_usd_30d,
|
||||
0 AS sales_usd_90d,
|
||||
0 AS sales_usd_180d,
|
||||
0 AS sales_usd_365d,
|
||||
0 AS sales_usd_total,
|
||||
0 AS customer_count_90d,
|
||||
NULL::date AS last_sale_date,
|
||||
'' AS last_ref_number
|
||||
@@ -480,6 +512,12 @@ Base AS (
|
||||
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,
|
||||
COALESCE(s.sales_qty_365d, 0) / 360.0 AS avg_daily_sales_365d,
|
||||
COALESCE(s.sales_qty_total, 0) / GREATEST(1, ($1::date - DATE '2022-01-01') + 1) AS avg_daily_sales_total,
|
||||
(COALESCE(s90.stock_qty, 0) + COALESCE(ls.stock_qty, 0)) / 2.0 AS avg_stock_90d,
|
||||
(COALESCE(s180.stock_qty, 0) + COALESCE(ls.stock_qty, 0)) / 2.0 AS avg_stock_180d,
|
||||
(COALESCE(s365.stock_qty, 0) + COALESCE(ls.stock_qty, 0)) / 2.0 AS avg_stock_365d,
|
||||
(COALESCE(stotal.stock_qty, 0) + COALESCE(ls.stock_qty, 0)) / 2.0 AS avg_stock_total,
|
||||
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,
|
||||
@@ -496,6 +534,10 @@ Base AS (
|
||||
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 Stock90Start s90 ON s90.product_code=s.product_code AND s90.color_code=s.color_code AND s90.yaka_kodu=s.yaka_kodu
|
||||
LEFT JOIN Stock180Start s180 ON s180.product_code=s.product_code AND s180.color_code=s.color_code AND s180.yaka_kodu=s.yaka_kodu
|
||||
LEFT JOIN Stock365Start s365 ON s365.product_code=s.product_code AND s365.color_code=s.color_code AND s365.yaka_kodu=s.yaka_kodu
|
||||
LEFT JOIN StockTotalStart stotal ON stotal.product_code=s.product_code AND stotal.color_code=s.color_code AND stotal.yaka_kodu=s.yaka_kodu
|
||||
LEFT JOIN mk_product_performance_price_dim pd ON pd.product_code=s.product_code
|
||||
),
|
||||
Spread AS (
|
||||
@@ -521,8 +563,14 @@ 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 b.avg_daily_sales_90d = 0 THEN 0 ELSE b.avg_stock_90d / NULLIF(b.avg_daily_sales_90d, 0) END AS stock_days_90d,
|
||||
CASE WHEN b.avg_daily_sales_180d = 0 THEN 0 ELSE b.avg_stock_180d / NULLIF(b.avg_daily_sales_180d, 0) END AS stock_days_180d,
|
||||
CASE WHEN b.avg_daily_sales_365d = 0 THEN 0 ELSE b.avg_stock_365d / NULLIF(b.avg_daily_sales_365d, 0) END AS stock_days_365d,
|
||||
CASE WHEN b.avg_daily_sales_total = 0 THEN 0 ELSE b.avg_stock_total / NULLIF(b.avg_daily_sales_total, 0) END AS stock_days_total,
|
||||
CASE WHEN b.avg_stock_90d = 0 THEN 0 ELSE b.sales_qty_90d / NULLIF(b.avg_stock_90d, 0) END AS stock_turnover_90d,
|
||||
CASE WHEN b.avg_stock_180d = 0 THEN 0 ELSE b.sales_qty_180d / NULLIF(b.avg_stock_180d, 0) END AS stock_turnover_180d,
|
||||
CASE WHEN b.avg_stock_365d = 0 THEN 0 ELSE b.sales_qty_365d / NULLIF(b.avg_stock_365d, 0) END AS stock_turnover_365d,
|
||||
CASE WHEN b.avg_stock_total = 0 THEN 0 ELSE b.sales_qty_total / NULLIF(b.avg_stock_total, 0) END AS stock_turnover_total,
|
||||
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
|
||||
@@ -533,9 +581,10 @@ Scored AS (
|
||||
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_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,
|
||||
sales_qty_30d, sales_qty_90d, sales_qty_180d, sales_qty_365d, sales_qty_730d, sales_qty_total,
|
||||
sales_usd_30d, sales_usd_90d, sales_usd_180d, sales_usd_365d, sales_usd_total, avg_daily_sales_90d, avg_daily_sales_180d, avg_daily_sales_365d, avg_daily_sales_total,
|
||||
stock_days_90d, stock_days_180d, stock_days_365d, stock_days_total, stock_turnover_90d, stock_turnover_180d, stock_turnover_365d, stock_turnover_total,
|
||||
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,
|
||||
@@ -545,9 +594,10 @@ 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_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(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_qty_total, 0),
|
||||
COALESCE(sales_usd_30d, 0), COALESCE(sales_usd_90d, 0), COALESCE(sales_usd_180d, 0), COALESCE(sales_usd_365d, 0), COALESCE(sales_usd_total, 0), COALESCE(avg_daily_sales_90d, 0), COALESCE(avg_daily_sales_180d, 0), COALESCE(avg_daily_sales_365d, 0), COALESCE(avg_daily_sales_total, 0),
|
||||
COALESCE(stock_days_90d, 0), COALESCE(stock_days_180d, 0), COALESCE(stock_days_365d, 0), COALESCE(stock_days_total, 0), COALESCE(stock_turnover_90d, 0), COALESCE(stock_turnover_180d, 0), COALESCE(stock_turnover_365d, 0), COALESCE(stock_turnover_total, 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),
|
||||
|
||||
@@ -3,7 +3,7 @@ package queries
|
||||
// GetProductStockQuery:
|
||||
// Urun kodu bazli, STOCK/PICK/RESERVE/DISP ayrik CTE ile optimize sorgu.
|
||||
const GetProductStockQuery = `
|
||||
DECLARE @ProductCode NVARCHAR(50) = @p1;
|
||||
DECLARE @ProductCode NVARCHAR(50) = UPPER(LTRIM(RTRIM(@p1)));
|
||||
|
||||
;WITH STOCK AS
|
||||
(
|
||||
@@ -14,7 +14,7 @@ DECLARE @ProductCode NVARCHAR(50) = @p1;
|
||||
StoreCode,
|
||||
WarehouseCode,
|
||||
ItemTypeCode,
|
||||
ItemCode,
|
||||
UPPER(LTRIM(RTRIM(ItemCode))) AS ItemCode,
|
||||
ColorCode,
|
||||
ItemDim1Code,
|
||||
ItemDim2Code,
|
||||
@@ -22,12 +22,12 @@ DECLARE @ProductCode NVARCHAR(50) = @p1;
|
||||
SUM(In_Qty1 - Out_Qty1) AS InventoryQty1
|
||||
FROM trStock
|
||||
WHERE ItemTypeCode = 1
|
||||
AND ItemCode = @ProductCode
|
||||
AND LEN(ItemCode) = 13
|
||||
AND UPPER(LTRIM(RTRIM(ItemCode))) = @ProductCode
|
||||
AND LEN(LTRIM(RTRIM(ItemCode))) = 13
|
||||
AND LEN(@ProductCode) = 13
|
||||
GROUP BY
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))), ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code
|
||||
),
|
||||
|
||||
@@ -35,17 +35,17 @@ PICK AS
|
||||
(
|
||||
SELECT
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))) AS ItemCode, ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code,
|
||||
SUM(Qty1) AS PickingQty1
|
||||
FROM PickingStates
|
||||
WHERE ItemTypeCode = 1
|
||||
AND ItemCode = @ProductCode
|
||||
AND LEN(ItemCode) = 13
|
||||
AND UPPER(LTRIM(RTRIM(ItemCode))) = @ProductCode
|
||||
AND LEN(LTRIM(RTRIM(ItemCode))) = 13
|
||||
AND LEN(@ProductCode) = 13
|
||||
GROUP BY
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))), ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code
|
||||
),
|
||||
|
||||
@@ -53,17 +53,17 @@ RESERVE AS
|
||||
(
|
||||
SELECT
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))) AS ItemCode, ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code,
|
||||
SUM(Qty1) AS ReserveQty1
|
||||
FROM ReserveStates
|
||||
WHERE ItemTypeCode = 1
|
||||
AND ItemCode = @ProductCode
|
||||
AND LEN(ItemCode) = 13
|
||||
AND UPPER(LTRIM(RTRIM(ItemCode))) = @ProductCode
|
||||
AND LEN(LTRIM(RTRIM(ItemCode))) = 13
|
||||
AND LEN(@ProductCode) = 13
|
||||
GROUP BY
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))), ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code
|
||||
),
|
||||
|
||||
@@ -71,17 +71,17 @@ DISP AS
|
||||
(
|
||||
SELECT
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))) AS ItemCode, ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code,
|
||||
SUM(Qty1) AS DispOrderQty1
|
||||
FROM DispOrderStates
|
||||
WHERE ItemTypeCode = 1
|
||||
AND ItemCode = @ProductCode
|
||||
AND LEN(ItemCode) = 13
|
||||
AND UPPER(LTRIM(RTRIM(ItemCode))) = @ProductCode
|
||||
AND LEN(LTRIM(RTRIM(ItemCode))) = 13
|
||||
AND LEN(@ProductCode) = 13
|
||||
GROUP BY
|
||||
CompanyCode, OfficeCode, StoreTypeCode, StoreCode, WarehouseCode,
|
||||
ItemTypeCode, ItemCode, ColorCode,
|
||||
ItemTypeCode, UPPER(LTRIM(RTRIM(ItemCode))), ColorCode,
|
||||
ItemDim1Code, ItemDim2Code, ItemDim3Code
|
||||
)
|
||||
|
||||
@@ -185,14 +185,14 @@ AND DP.ItemDim2Code=S.ItemDim2Code
|
||||
AND DP.ItemDim3Code=S.ItemDim3Code
|
||||
|
||||
JOIN cdItem
|
||||
ON S.ItemCode = cdItem.ItemCode
|
||||
ON UPPER(LTRIM(RTRIM(S.ItemCode))) = UPPER(LTRIM(RTRIM(cdItem.ItemCode)))
|
||||
AND S.ItemTypeCode = cdItem.ItemTypeCode
|
||||
|
||||
LEFT JOIN cdUnitOfMeasure
|
||||
ON cdItem.UnitOfMeasureCode1 = cdUnitOfMeasure.UnitOfMeasureCode
|
||||
|
||||
LEFT JOIN ProductFilterWithDescription('TR') P
|
||||
ON P.ProductCode = S.ItemCode
|
||||
ON UPPER(LTRIM(RTRIM(P.ProductCode))) = UPPER(LTRIM(RTRIM(S.ItemCode)))
|
||||
|
||||
LEFT JOIN bsItemTypeDesc
|
||||
ON bsItemTypeDesc.ItemTypeCode = S.ItemTypeCode
|
||||
@@ -214,14 +214,14 @@ LEFT JOIN (
|
||||
ROW_NUMBER() OVER (PARTITION BY ItemCode, ItemTypeCode ORDER BY PriceDate DESC) AS RowNum
|
||||
FROM prItemBasePrice
|
||||
) prFilteredBasePrice
|
||||
ON prFilteredBasePrice.ItemCode = S.ItemCode
|
||||
ON UPPER(LTRIM(RTRIM(prFilteredBasePrice.ItemCode))) = UPPER(LTRIM(RTRIM(S.ItemCode)))
|
||||
AND prFilteredBasePrice.ItemTypeCode = S.ItemTypeCode
|
||||
AND prFilteredBasePrice.RowNum = 1
|
||||
|
||||
WHERE
|
||||
S.ItemTypeCode IN (1)
|
||||
AND S.ItemCode = @ProductCode
|
||||
AND LEN(S.ItemCode) = 13
|
||||
AND UPPER(LTRIM(RTRIM(S.ItemCode))) = @ProductCode
|
||||
AND LEN(LTRIM(RTRIM(S.ItemCode))) = 13
|
||||
AND LEN(@ProductCode) = 13
|
||||
AND (
|
||||
S.InventoryQty1
|
||||
@@ -234,6 +234,6 @@ WHERE
|
||||
(
|
||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36','1-0-4','1-0-29'
|
||||
);
|
||||
`
|
||||
|
||||
@@ -28,7 +28,7 @@ IF OBJECT_ID('dbo.ProductFilterTRCache','U') IS NOT NULL
|
||||
BEGIN
|
||||
INSERT INTO #AttrBase (ProductCode, Kategori, UrunAnaGrubu, UrunAltGrubu, UrunIcerigi, Fit, DropVal)
|
||||
SELECT
|
||||
ProductCode,
|
||||
UPPER(LTRIM(RTRIM(ProductCode))) AS ProductCode,
|
||||
Kategori = LTRIM(RTRIM(ProductAtt44Desc)),
|
||||
UrunAnaGrubu = LTRIM(RTRIM(ProductAtt01Desc)),
|
||||
UrunAltGrubu = LTRIM(RTRIM(ProductAtt02Desc)),
|
||||
@@ -48,7 +48,7 @@ ELSE
|
||||
BEGIN
|
||||
INSERT INTO #AttrBase (ProductCode, Kategori, UrunAnaGrubu, UrunAltGrubu, UrunIcerigi, Fit, DropVal)
|
||||
SELECT
|
||||
ProductCode,
|
||||
UPPER(LTRIM(RTRIM(ProductCode))) AS ProductCode,
|
||||
Kategori = LTRIM(RTRIM(ProductAtt44Desc)),
|
||||
UrunAnaGrubu = LTRIM(RTRIM(ProductAtt01Desc)),
|
||||
UrunAltGrubu = LTRIM(RTRIM(ProductAtt02Desc)),
|
||||
@@ -101,40 +101,40 @@ CREATE NONCLUSTERED INDEX IX_AttrBase_Filter ON #AttrBase(Kategori, UrunAnaGrubu
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
P.ItemCode, P.ColorCode, P.ItemDim1Code, P.ItemDim2Code,
|
||||
UPPER(LTRIM(RTRIM(P.ItemCode))) AS ItemCode, P.ColorCode, P.ItemDim1Code, P.ItemDim2Code,
|
||||
P.Qty1 AS PickingQty1, 0 AS ReserveQty1, 0 AS DispOrderQty1, 0 AS InventoryQty1
|
||||
FROM PickingStates P
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = P.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(P.ItemCode)))
|
||||
WHERE P.ItemTypeCode = 1
|
||||
AND LEN(P.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(P.ItemCode))) = 13
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
R.ItemCode, R.ColorCode, R.ItemDim1Code, R.ItemDim2Code,
|
||||
UPPER(LTRIM(RTRIM(R.ItemCode))) AS ItemCode, R.ColorCode, R.ItemDim1Code, R.ItemDim2Code,
|
||||
0, R.Qty1, 0, 0
|
||||
FROM ReserveStates R
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = R.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(R.ItemCode)))
|
||||
WHERE R.ItemTypeCode = 1
|
||||
AND LEN(R.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(R.ItemCode))) = 13
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
D.ItemCode, D.ColorCode, D.ItemDim1Code, D.ItemDim2Code,
|
||||
UPPER(LTRIM(RTRIM(D.ItemCode))) AS ItemCode, D.ColorCode, D.ItemDim1Code, D.ItemDim2Code,
|
||||
0, 0, D.Qty1, 0
|
||||
FROM DispOrderStates D
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = D.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(D.ItemCode)))
|
||||
WHERE D.ItemTypeCode = 1
|
||||
AND LEN(D.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(D.ItemCode))) = 13
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
T.ItemCode, T.ColorCode, T.ItemDim1Code, T.ItemDim2Code,
|
||||
UPPER(LTRIM(RTRIM(T.ItemCode))) AS ItemCode, T.ColorCode, T.ItemDim1Code, T.ItemDim2Code,
|
||||
0, 0, 0, SUM(T.In_Qty1 - T.Out_Qty1)
|
||||
FROM trStock T
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = T.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(T.ItemCode)))
|
||||
WHERE T.ItemTypeCode = 1
|
||||
AND LEN(T.ItemCode) = 13
|
||||
GROUP BY T.ItemCode, T.ColorCode, T.ItemDim1Code, T.ItemDim2Code
|
||||
AND LEN(LTRIM(RTRIM(T.ItemCode))) = 13
|
||||
GROUP BY UPPER(LTRIM(RTRIM(T.ItemCode))), T.ColorCode, T.ItemDim1Code, T.ItemDim2Code
|
||||
) X
|
||||
GROUP BY X.ItemCode, X.ColorCode, X.ItemDim1Code, X.ItemDim2Code
|
||||
),
|
||||
@@ -180,7 +180,7 @@ SELECT 'renk', X.FieldValue
|
||||
FROM (
|
||||
SELECT DISTINCT FieldValue = CASE WHEN A.RenkAciklama <> '' THEN A.RenkAciklama ELSE A.Renk END
|
||||
FROM Avail A
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = A.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(A.ItemCode)))
|
||||
WHERE (CASE WHEN A.RenkAciklama <> '' THEN A.RenkAciklama ELSE A.Renk END) <> ''
|
||||
AND (@Kategori IS NULL OR AB.Kategori = @Kategori)
|
||||
AND (@UrunAnaGrubu IS NULL OR AB.UrunAnaGrubu = @UrunAnaGrubu)
|
||||
@@ -196,7 +196,7 @@ SELECT 'renk2', X.FieldValue
|
||||
FROM (
|
||||
SELECT DISTINCT FieldValue = A.Renk2
|
||||
FROM Avail A
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = A.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(A.ItemCode)))
|
||||
WHERE A.Renk2 <> ''
|
||||
AND (@Kategori IS NULL OR AB.Kategori = @Kategori)
|
||||
AND (@UrunAnaGrubu IS NULL OR AB.UrunAnaGrubu = @UrunAnaGrubu)
|
||||
@@ -245,7 +245,7 @@ SELECT 'beden', X.FieldValue
|
||||
FROM (
|
||||
SELECT DISTINCT FieldValue = A.Beden
|
||||
FROM Avail A
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = A.ItemCode
|
||||
INNER JOIN #AttrBase AB ON AB.ProductCode = UPPER(LTRIM(RTRIM(A.ItemCode)))
|
||||
WHERE A.Beden <> ''
|
||||
AND (@Kategori IS NULL OR AB.Kategori = @Kategori)
|
||||
AND (@UrunAnaGrubu IS NULL OR AB.UrunAnaGrubu = @UrunAnaGrubu)
|
||||
@@ -346,7 +346,7 @@ BEGIN
|
||||
ProductAtt46Desc
|
||||
)
|
||||
SELECT
|
||||
C.ProductCode,
|
||||
UPPER(LTRIM(RTRIM(C.ProductCode))) AS ProductCode,
|
||||
C.ProductDescription,
|
||||
C.ProductAtt01Desc,
|
||||
C.ProductAtt02Desc,
|
||||
@@ -379,7 +379,7 @@ BEGIN
|
||||
ISNULL(PF.ProductAtt45Desc, '') AS ProductAtt45Desc,
|
||||
ISNULL(PF.ProductAtt46Desc, '') AS ProductAtt46Desc
|
||||
FROM dbo.ProductFilterTRCache C
|
||||
LEFT JOIN ProductFilterWithDescription('TR') PF ON PF.ProductCode = C.ProductCode
|
||||
LEFT JOIN ProductFilterWithDescription('TR') PF ON UPPER(LTRIM(RTRIM(PF.ProductCode))) = UPPER(LTRIM(RTRIM(C.ProductCode)))
|
||||
WHERE LEN(C.ProductCode) = 13
|
||||
AND (@Kategori IS NULL OR C.ProductAtt44Desc = @Kategori)
|
||||
AND (@UrunAnaGrubu IS NULL OR C.ProductAtt01Desc = @UrunAnaGrubu)
|
||||
@@ -426,7 +426,7 @@ BEGIN
|
||||
ProductAtt46Desc
|
||||
)
|
||||
SELECT
|
||||
ProductCode,
|
||||
UPPER(LTRIM(RTRIM(ProductCode))) AS ProductCode,
|
||||
ProductDescription,
|
||||
ProductAtt01Desc,
|
||||
ProductAtt02Desc,
|
||||
@@ -493,69 +493,69 @@ INV AS
|
||||
(
|
||||
SELECT
|
||||
P.CompanyCode, P.OfficeCode, P.StoreTypeCode, P.StoreCode, P.WarehouseCode,
|
||||
P.ItemTypeCode, P.ItemCode, P.ColorCode, P.ItemDim1Code, P.ItemDim2Code, P.ItemDim3Code,
|
||||
P.ItemTypeCode, UPPER(LTRIM(RTRIM(P.ItemCode))) AS ItemCode, P.ColorCode, P.ItemDim1Code, P.ItemDim2Code, P.ItemDim3Code,
|
||||
P.Qty1 AS PickingQty1, 0 AS ReserveQty1, 0 AS DispOrderQty1, 0 AS InventoryQty1
|
||||
FROM PickingStates P
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = P.ItemCode
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = UPPER(LTRIM(RTRIM(P.ItemCode)))
|
||||
WHERE P.ItemTypeCode = 1
|
||||
AND LEN(P.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(P.ItemCode))) = 13
|
||||
AND P.WarehouseCode IN
|
||||
(
|
||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36','1-0-4','1-0-29'
|
||||
)
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
R.CompanyCode, R.OfficeCode, R.StoreTypeCode, R.StoreCode, R.WarehouseCode,
|
||||
R.ItemTypeCode, R.ItemCode, R.ColorCode, R.ItemDim1Code, R.ItemDim2Code, R.ItemDim3Code,
|
||||
R.ItemTypeCode, UPPER(LTRIM(RTRIM(R.ItemCode))) AS ItemCode, R.ColorCode, R.ItemDim1Code, R.ItemDim2Code, R.ItemDim3Code,
|
||||
0, R.Qty1, 0, 0
|
||||
FROM ReserveStates R
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = R.ItemCode
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = UPPER(LTRIM(RTRIM(R.ItemCode)))
|
||||
WHERE R.ItemTypeCode = 1
|
||||
AND LEN(R.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(R.ItemCode))) = 13
|
||||
AND R.WarehouseCode IN
|
||||
(
|
||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36','1-0-4','1-0-29'
|
||||
)
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
D.CompanyCode, D.OfficeCode, D.StoreTypeCode, D.StoreCode, D.WarehouseCode,
|
||||
D.ItemTypeCode, D.ItemCode, D.ColorCode, D.ItemDim1Code, D.ItemDim2Code, D.ItemDim3Code,
|
||||
D.ItemTypeCode, UPPER(LTRIM(RTRIM(D.ItemCode))) AS ItemCode, D.ColorCode, D.ItemDim1Code, D.ItemDim2Code, D.ItemDim3Code,
|
||||
0, 0, D.Qty1, 0
|
||||
FROM DispOrderStates D
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = D.ItemCode
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = UPPER(LTRIM(RTRIM(D.ItemCode)))
|
||||
WHERE D.ItemTypeCode = 1
|
||||
AND LEN(D.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(D.ItemCode))) = 13
|
||||
AND D.WarehouseCode IN
|
||||
(
|
||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36','1-0-4','1-0-29'
|
||||
)
|
||||
|
||||
UNION ALL
|
||||
SELECT
|
||||
T.CompanyCode, T.OfficeCode, T.StoreTypeCode, T.StoreCode, T.WarehouseCode,
|
||||
T.ItemTypeCode, T.ItemCode, T.ColorCode, T.ItemDim1Code, T.ItemDim2Code, T.ItemDim3Code,
|
||||
T.ItemTypeCode, UPPER(LTRIM(RTRIM(T.ItemCode))) AS ItemCode, T.ColorCode, T.ItemDim1Code, T.ItemDim2Code, T.ItemDim3Code,
|
||||
0, 0, 0, SUM(T.In_Qty1 - T.Out_Qty1)
|
||||
FROM trStock T
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = T.ItemCode
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = UPPER(LTRIM(RTRIM(T.ItemCode)))
|
||||
WHERE T.ItemTypeCode = 1
|
||||
AND LEN(T.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(T.ItemCode))) = 13
|
||||
AND T.WarehouseCode IN
|
||||
(
|
||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36','1-0-4','1-0-29'
|
||||
)
|
||||
GROUP BY
|
||||
T.CompanyCode, T.OfficeCode, T.StoreTypeCode, T.StoreCode, T.WarehouseCode,
|
||||
T.ItemTypeCode, T.ItemCode, T.ColorCode, T.ItemDim1Code, T.ItemDim2Code, T.ItemDim3Code
|
||||
T.ItemTypeCode, UPPER(LTRIM(RTRIM(T.ItemCode))), T.ColorCode, T.ItemDim1Code, T.ItemDim2Code, T.ItemDim3Code
|
||||
) X
|
||||
GROUP BY
|
||||
X.CompanyCode, X.OfficeCode, X.StoreTypeCode, X.StoreCode, X.WarehouseCode,
|
||||
@@ -580,21 +580,21 @@ Avail AS
|
||||
FROM INV I
|
||||
JOIN cdItem CI
|
||||
ON CI.ItemTypeCode = I.ItemTypeCode
|
||||
AND CI.ItemCode = I.ItemCode
|
||||
AND UPPER(LTRIM(RTRIM(CI.ItemCode))) = I.ItemCode
|
||||
LEFT JOIN cdUnitOfMeasure U
|
||||
ON U.UnitOfMeasureCode = CI.UnitOfMeasureCode1
|
||||
LEFT JOIN cdColorDesc C
|
||||
ON C.ColorCode = I.ColorCode
|
||||
AND C.LangCode = 'TR'
|
||||
WHERE I.ItemTypeCode = 1
|
||||
AND LEN(I.ItemCode) = 13
|
||||
AND LEN(LTRIM(RTRIM(I.ItemCode))) = 13
|
||||
AND (I.InventoryQty1 - I.PickingQty1 - I.ReserveQty1 - I.DispOrderQty1) > 0
|
||||
AND CI.IsBlocked = 0
|
||||
AND I.WarehouseCode IN
|
||||
(
|
||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||
'1-0-33','101','1-014','1-0-49','1-0-36','1-0-4','1-0-29'
|
||||
)
|
||||
),
|
||||
Grouped AS
|
||||
@@ -604,7 +604,7 @@ Grouped AS
|
||||
A.ColorCode,
|
||||
A.ItemDim2Code
|
||||
FROM Avail A
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = A.ItemCode
|
||||
INNER JOIN #AttrFiltered AF ON AF.ProductCode = UPPER(LTRIM(RTRIM(A.ItemCode)))
|
||||
WHERE (@RenkList IS NULL OR CHARINDEX(NCHAR(31) + ISNULL((CASE WHEN A.RenkAciklama <> '' THEN A.RenkAciklama ELSE A.ColorCode END),'') + NCHAR(31), NCHAR(31) + @RenkList + NCHAR(31)) > 0)
|
||||
AND (@Renk2List IS NULL OR CHARINDEX(NCHAR(31) + ISNULL(A.ItemDim2Code,'') + NCHAR(31), NCHAR(31) + @Renk2List + NCHAR(31)) > 0)
|
||||
AND (
|
||||
@@ -669,7 +669,7 @@ INNER JOIN Grouped G
|
||||
AND G.ColorCode = A.ColorCode
|
||||
AND ISNULL(G.ItemDim2Code, '') = ISNULL(A.ItemDim2Code, '')
|
||||
INNER JOIN #AttrFiltered AF
|
||||
ON AF.ProductCode = A.ItemCode
|
||||
ON AF.ProductCode = UPPER(LTRIM(RTRIM(A.ItemCode)))
|
||||
LEFT JOIN cdWarehouseDesc W
|
||||
ON W.WarehouseCode = A.WarehouseCode
|
||||
AND W.LangCode = 'TR'
|
||||
@@ -680,8 +680,8 @@ OUTER APPLY (
|
||||
SELECT TOP 1 Price
|
||||
FROM prItemBasePrice PB
|
||||
WHERE PB.ItemTypeCode = 1
|
||||
AND PB.ItemCode = A.ItemCode
|
||||
AND LEN(PB.ItemCode) = 13
|
||||
AND UPPER(LTRIM(RTRIM(PB.ItemCode))) = UPPER(LTRIM(RTRIM(A.ItemCode)))
|
||||
AND LEN(LTRIM(RTRIM(PB.ItemCode))) = 13
|
||||
ORDER BY PB.PriceDate DESC
|
||||
) P
|
||||
OPTION (RECOMPILE);
|
||||
|
||||
@@ -1631,6 +1631,7 @@ const columns = [
|
||||
{ name: 'sales_usd_total', label: 'Genel USD', field: 'sales_usd_total', align: 'right', sortable: true },
|
||||
{ name: 'stock_days_90d', label: 'Stok Gün', field: row => formatNumber(row.stock_days_90d, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_days_180d', label: '180G Stok Gün', field: row => formatNumber(row.stock_days_180d, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_days_365d', label: '360G Stok Gün', field: row => formatNumber(row.stock_days_365d, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_days_total', label: 'Genel Stok Gün', field: row => formatNumber(row.stock_days_total, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_90d', label: '90G Stok Devir', field: row => formatNumber(row.stock_turnover_90d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_180d', label: '180G Stok Devir', field: row => formatNumber(row.stock_turnover_180d, 2), align: 'right', sortable: true },
|
||||
@@ -2821,13 +2822,15 @@ function productPeriodMetricSource (row, suffix) {
|
||||
const salesIndex = Number(row?.[`sales_index_${suffix}`] || 0)
|
||||
const qty = Number(row?.[`sales_qty_${suffix}`] || 0)
|
||||
const stockQty = Number(row?.stock_qty || 0)
|
||||
const turnoverKey = `stock_turnover_${suffix}`
|
||||
const hasTurnover = Object.prototype.hasOwnProperty.call(row || {}, turnoverKey)
|
||||
return {
|
||||
sales_index_90d: salesIndex,
|
||||
gross_margin_cost_90d: Number(row?.[`gross_margin_cost_${suffix}`] ?? 0),
|
||||
gross_margin_90d: Number(row?.[`gross_margin_${suffix}`] ?? 0),
|
||||
invoice_count_90d: Number(row?.[`invoice_count_${suffix}`] || 0),
|
||||
sales_qty_90d: qty,
|
||||
stock_turnover_90d: Number(row?.[`stock_turnover_${suffix}`] || 0) || (stockQty > 0 ? qty / stockQty : 0),
|
||||
stock_turnover_90d: hasTurnover ? Number(row?.[turnoverKey] || 0) : (stockQty > 0 ? qty / stockQty : 0),
|
||||
stock_qty: stockQty
|
||||
}
|
||||
}
|
||||
@@ -3115,9 +3118,9 @@ function withProductMargins (row) {
|
||||
return {
|
||||
...row,
|
||||
avg_price_usd_365d: Number(row?.sales_qty_365d || 0) > 0 ? Number(row?.sales_usd_365d || 0) / Number(row?.sales_qty_365d || 0) : 0,
|
||||
stock_turnover_90d: stockTurnover(row?.sales_qty_90d, row?.stock_qty),
|
||||
stock_turnover_180d: stockTurnover(row?.sales_qty_180d, row?.stock_qty),
|
||||
stock_turnover_365d: stockTurnover(row?.sales_qty_365d, row?.stock_qty),
|
||||
stock_turnover_90d: existingOrStockTurnover(row?.stock_turnover_90d, row?.sales_qty_90d, row?.stock_qty),
|
||||
stock_turnover_180d: existingOrStockTurnover(row?.stock_turnover_180d, row?.sales_qty_180d, row?.stock_qty),
|
||||
stock_turnover_365d: existingOrStockTurnover(row?.stock_turnover_365d, row?.sales_qty_365d, row?.stock_qty),
|
||||
gross_margin_base_90d: marginFromSalesCost(row?.sales_usd_90d, row?.sales_qty_90d, row?.base_price_usd),
|
||||
gross_margin_cost_90d: marginFromSalesCost(row?.sales_usd_90d, row?.sales_qty_90d, row?.cost_price_usd),
|
||||
gross_margin_base_180d: marginFromSalesCost(row?.sales_usd_180d, row?.sales_qty_180d, row?.base_price_usd),
|
||||
@@ -3128,7 +3131,7 @@ function withProductMargins (row) {
|
||||
function withGeneralMargins (row) {
|
||||
return {
|
||||
...row,
|
||||
stock_turnover_total: stockTurnover(row?.sales_qty_total, row?.stock_qty),
|
||||
stock_turnover_total: existingOrStockTurnover(row?.stock_turnover_total, row?.sales_qty_total, row?.stock_qty),
|
||||
gross_margin_base_total: marginFromSalesCost(row?.sales_usd_total, row?.sales_qty_total, row?.base_price_usd),
|
||||
gross_margin_cost_total: marginFromSalesCost(row?.sales_usd_total, row?.sales_qty_total, row?.cost_price_usd)
|
||||
}
|
||||
@@ -3140,6 +3143,11 @@ function stockTurnover (salesQty, stockQty) {
|
||||
return Number(salesQty || 0) / stock
|
||||
}
|
||||
|
||||
function existingOrStockTurnover (value, salesQty, stockQty) {
|
||||
const current = Number(value)
|
||||
return value !== undefined && value !== null && Number.isFinite(current) ? current : stockTurnover(salesQty, stockQty)
|
||||
}
|
||||
|
||||
function filterKey (tableKey, name) {
|
||||
return `${tableKey}:${name}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user