product performance grouped kpi improvements

This commit is contained in:
M_Kececi
2026-07-03 03:43:17 +03:00
parent 94c83c3825
commit a05e6bf1e2
2 changed files with 42 additions and 8 deletions
+27 -6
View File
@@ -347,6 +347,10 @@ CREATE TABLE IF NOT EXISTS mk_product_performance_sales_daily (
`ALTER TABLE mk_product_performance_sales_daily ADD COLUMN IF NOT EXISTS urun_ana_grubu TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE mk_product_performance_sales_daily ADD COLUMN IF NOT EXISTS urun_alt_grubu TEXT NOT NULL DEFAULT ''`,
`
UPDATE mk_product_performance_sales_daily
SET urun_ilk_grubu = '', updated_at = now()
WHERE upper(translate(btrim(urun_ilk_grubu), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON')`,
`
DO $$
BEGIN
IF EXISTS (
@@ -457,6 +461,10 @@ CREATE TABLE IF NOT EXISTS mk_product_performance_kpi_daily (
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS urun_ilk_grubu TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS urun_ana_grubu TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE mk_product_performance_kpi_daily ADD COLUMN IF NOT EXISTS urun_alt_grubu TEXT NOT NULL DEFAULT ''`,
`
UPDATE mk_product_performance_kpi_daily
SET urun_ilk_grubu = '', updated_at = now()
WHERE upper(translate(btrim(urun_ilk_grubu), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON')`,
`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_usd_180d 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`,
@@ -667,6 +675,7 @@ func refreshProductPerformanceSales(ctx context.Context, tx *sql.Tx, startDate,
); err != nil {
return count, err
}
r.UrunIlkGrubu = cleanProductPerformanceFirstGroup(r.UrunIlkGrubu)
if _, err := tx.ExecContext(ctx, `
INSERT INTO mk_product_performance_sales_daily (
sales_date, product_code, color_code, yaka_kodu, item_description,
@@ -1001,6 +1010,7 @@ LIMIT $`+fmt.Sprint(len(args)-1)+` OFFSET $`+fmt.Sprint(len(args)), args...)
); err != nil {
return nil, 0, err
}
r.UrunIlkGrubu = cleanProductPerformanceFirstGroup(r.UrunIlkGrubu)
out = append(out, r)
}
return out, total, rows.Err()
@@ -1340,6 +1350,7 @@ LIMIT $1
); err != nil {
return nil, err
}
r.UrunIlkGrubu = cleanProductPerformanceFirstGroup(r.UrunIlkGrubu)
out = append(out, r)
}
return out, rows.Err()
@@ -2172,6 +2183,7 @@ LIMIT $1
); err != nil {
return nil, err
}
r.UrunIlkGrubu = cleanProductPerformanceFirstGroup(r.UrunIlkGrubu)
out = append(out, r)
}
return out, rows.Err()
@@ -2324,7 +2336,7 @@ func ListProductPerformanceSalesBreakdown(ctx context.Context, pg *sql.DB, break
"item_description": "MAX(s.item_description)",
"kategori": "COALESCE(MAX(s.kategori),'')",
"askili_yan": "MAX(s.askili_yan)",
"urun_ilk_grubu": "COALESCE(MAX(s.urun_ilk_grubu),'')",
"urun_ilk_grubu": "COALESCE(MAX(CASE WHEN upper(translate(btrim(COALESCE(s.urun_ilk_grubu,'')), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON') THEN '' ELSE s.urun_ilk_grubu END),'')",
"urun_ana_grubu": "COALESCE(MAX(s.urun_ana_grubu),'')",
"urun_alt_grubu": "MAX(s.urun_alt_grubu)",
"market_key": "s.market_key",
@@ -2351,7 +2363,7 @@ func ListProductPerformanceSalesBreakdown(ctx context.Context, pg *sql.DB, break
selected["market_key"] = true
selected["customer_code"] = true
selected["customer_name"] = true
groupCols = []string{"s.color_code", "s.yaka_kodu", "s.urun_ilk_grubu", "s.askili_yan", "s.kategori", "s.urun_ana_grubu", "s.urun_alt_grubu", "s.product_code", "s.customer_country", "s.market_key", "s.customer_segment", "s.customer_code"}
groupCols = []string{"CASE WHEN upper(translate(btrim(COALESCE(s.urun_ilk_grubu,'')), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON') THEN '' ELSE s.urun_ilk_grubu END", "s.color_code", "s.yaka_kodu", "s.askili_yan", "s.kategori", "s.urun_ana_grubu", "s.urun_alt_grubu", "s.product_code", "s.customer_country", "s.market_key", "s.customer_segment", "s.customer_code"}
case "product_country_segment_market_customer":
selected["product_code"] = true
selected["item_description"] = true
@@ -2414,7 +2426,7 @@ func ListProductPerformanceSalesBreakdown(ctx context.Context, pg *sql.DB, break
selected["market_key"] = true
selected["customer_code"] = true
selected["customer_name"] = true
groupCols = []string{"s.color_code", "s.yaka_kodu", "s.urun_ilk_grubu", "s.askili_yan", "s.kategori", "s.urun_ana_grubu", "s.urun_alt_grubu", "s.product_code", "s.customer_country", "s.market_key", "s.customer_segment", "s.customer_code"}
groupCols = []string{"CASE WHEN upper(translate(btrim(COALESCE(s.urun_ilk_grubu,'')), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON') THEN '' ELSE s.urun_ilk_grubu END", "s.color_code", "s.yaka_kodu", "s.askili_yan", "s.kategori", "s.urun_ana_grubu", "s.urun_alt_grubu", "s.product_code", "s.customer_country", "s.market_key", "s.customer_segment", "s.customer_code"}
}
selectExpr := func(name string) string {
@@ -2432,7 +2444,10 @@ WITH LatestKPI AS (
yaka_kodu,
COALESCE(kategori,'') AS kategori,
askili_yan,
COALESCE(urun_ilk_grubu,'') AS urun_ilk_grubu,
CASE
WHEN upper(translate(btrim(COALESCE(urun_ilk_grubu,'')), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON') THEN ''
ELSE COALESCE(urun_ilk_grubu,'')
END AS urun_ilk_grubu,
COALESCE(urun_ana_grubu,'') AS urun_ana_grubu,
urun_alt_grubu
FROM mk_product_performance_kpi_daily
@@ -3027,7 +3042,10 @@ WITH Source AS (
seri,
yas_grubu,
askili_yan,
COALESCE(urun_ilk_grubu,'') AS urun_ilk_grubu,
CASE
WHEN upper(translate(btrim(COALESCE(urun_ilk_grubu,'')), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON') THEN ''
ELSE COALESCE(urun_ilk_grubu,'')
END AS urun_ilk_grubu,
COALESCE(urun_ana_grubu,'') AS urun_ana_grubu,
urun_alt_grubu,
market_key,
@@ -3066,7 +3084,9 @@ WITH Source AS (
func productPerformanceSQLGroupExpr(field string) (string, bool) {
switch field {
case "kategori", "askili_yan", "urun_ilk_grubu", "urun_ana_grubu", "urun_alt_grubu", "product_code", "item_description", "color_code", "yaka_kodu":
case "urun_ilk_grubu":
return "CASE WHEN upper(translate(btrim(COALESCE(urun_ilk_grubu,'')), 'İŞĞÜÖÇ', 'ISGUOC')) IN ('YETISKIN', 'YETISKIN/GARSON', 'GARSON') THEN '' ELSE COALESCE(urun_ilk_grubu,'') END", true
case "kategori", "askili_yan", "urun_ana_grubu", "urun_alt_grubu", "product_code", "item_description", "color_code", "yaka_kodu":
return field, true
case "market_key":
return "btrim(regexp_replace(COALESCE(market_key,''), '^.*\\|', ''))", true
@@ -4008,6 +4028,7 @@ ORDER BY product_code, color_code, yaka_kodu, performance_score DESC
if err := rows.Scan(&productCode, &colorCode, &yakaKodu, &p.itemDescription, &p.kategori, &p.askiliYan, &p.urunIlkGrubu, &p.urunAnaGrubu, &p.urunAltGrubu); err != nil {
return nil, err
}
p.urunIlkGrubu = cleanProductPerformanceFirstGroup(p.urunIlkGrubu)
out[productPerformanceVariantKey(productCode, colorCode, yakaKodu)] = p
}
return out, rows.Err()
@@ -3844,10 +3844,12 @@ async function loadBackendGroupedRows () {
}
function normalizeGroupedDisplayRow (tabKey, row) {
const nextRow = { ...row }
normalizeGroupedProductHierarchyValues(nextRow)
if (tabKey === 'order_product_customers' || tabKey === 'order_market_details') {
return withOrderPeriodScores({ ...row })
return withOrderPeriodScores(nextRow)
}
const next = withPeriodScores({ ...row })
const next = withPeriodScores(nextRow)
if (tabKey !== 'products' && tabKey !== 'idle') {
next.customer_score_90d = Number(next.customer_score_90d || customerSalesPeriodScore(periodMetricSource(next, '90d')))
next.customer_score_180d = Number(next.customer_score_180d || customerSalesPeriodScore(periodMetricSource(next, '180d')))
@@ -3857,6 +3859,17 @@ function normalizeGroupedDisplayRow (tabKey, row) {
return next
}
function normalizeGroupedProductHierarchyValues (row) {
row.urun_ilk_grubu = cleanProductFirstGroupValue(row.urun_ilk_grubu)
if (row.__group && row.group_field === 'urun_ilk_grubu') {
const cleanValue = cleanProductFirstGroupValue(row.group_value || row.label || row.urun_ilk_grubu)
row.group_value = cleanValue
row.label = cleanValue
row.urun_ilk_grubu = cleanValue
}
return row
}
function responseRowCount (data) {
if (Array.isArray(data)) return data.length
if (Array.isArray(data?.rows)) return data.rows.length