package queries func productPerformanceSalesSQL() string { return ` ;WITH SalesLines AS ( SELECT I.InvoiceLineID, SalesDate = CAST(I.InvoiceDate AS date), I.InvoiceHeaderID, I.InvoiceNumber, ProductCode = UPPER(LTRIM(RTRIM(I.ItemCode))), ColorCode = UPPER(LTRIM(RTRIM(ISNULL(I.ColorCode, '')))), YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(I.ItemDim2Code, '')))), ItemDescription = dbo.HG_Temizlik(ISNULL(( SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK) WHERE cdItemDesc.ItemTypeCode = I.ItemTypeCode AND cdItemDesc.ItemCode = I.ItemCode AND cdItemDesc.LangCode = 'TR' ), SPACE(0))), UrunAnaGrubu = dbo.HG_Temizlik(ISNULL(PAF.ProductAtt01, SPACE(0))), UrunAltGrubu = dbo.HG_Temizlik(ISNULL(PAF.ProductAtt02, SPACE(0))), Kategori = dbo.HG_Temizlik(ISNULL(PAF.ProductAtt44, SPACE(0))), UrunIlkGrubu = dbo.HG_Temizlik(ISNULL(PAF.ProductAtt42, SPACE(0))), AskiliYan = dbo.HG_Temizlik(ISNULL(PAF.ProductAtt45, SPACE(0))), ChannelCode = CASE WHEN I.ProcessCode IN ('R') THEN dbo.HG_Temizlik(ISNULL(( SELECT OfficeDescription FROM cdOfficeDesc WITH(NOLOCK) WHERE cdOfficeDesc.OfficeCode = I.OfficeCode AND cdOfficeDesc.LangCode = 'TR' ), SPACE(0))) ELSE dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdCurrAccAttributeDesc WITH(NOLOCK) WHERE cdCurrAccAttributeDesc.CurrAccTypeCode = 3 AND AttributeTypeCode = 1 AND CAF.CustomerAtt01 = AttributeCode AND cdCurrAccAttributeDesc.LangCode = 'TR' ), SPACE(0))) END, CustomerCountry = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdCurrAccAttributeDesc WITH(NOLOCK) WHERE cdCurrAccAttributeDesc.CurrAccTypeCode = 3 AND AttributeTypeCode = 5 AND CAF.CustomerAtt05 = AttributeCode AND cdCurrAccAttributeDesc.LangCode = 'TR' ), SPACE(0))), CustomerSegment = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdCurrAccAttributeDesc WITH(NOLOCK) WHERE cdCurrAccAttributeDesc.CurrAccTypeCode = 3 AND AttributeTypeCode = 11 AND CAF.CustomerAtt11 = AttributeCode AND cdCurrAccAttributeDesc.LangCode = 'TR' ), SPACE(0))), CustomerCode = CASE WHEN I.ProcessCode = 'R' THEN dbo.HG_Temizlik(ISNULL(I.StoreCode, '')) ELSE dbo.HG_Temizlik(ISNULL(I.CurrAccCode, '')) END, CustomerDescription = CASE WHEN I.ProcessCode = 'R' THEN dbo.HG_Temizlik(ISNULL(( SELECT CurrAccDescription FROM cdCurrAccDesc WITH(NOLOCK) WHERE cdCurrAccDesc.CurrAccTypeCode = 5 AND cdCurrAccDesc.CurrAccCode = I.StoreCode AND cdCurrAccDesc.LangCode = 'TR' ), SPACE(0))) ELSE dbo.HG_Temizlik(ISNULL(( SELECT CurrAccDescription FROM cdCurrAccDesc WITH(NOLOCK) WHERE cdCurrAccDesc.CurrAccTypeCode = I.CurrAccTypeCode AND cdCurrAccDesc.CurrAccCode = I.CurrAccCode AND cdCurrAccDesc.LangCode = 'TR' ), 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), RN = ROW_NUMBER() OVER ( PARTITION BY I.InvoiceLineID ORDER BY I.InvoiceDate DESC, I.InvoiceNumber ) FROM AllInvoicesWithAttributes I WITH(NOLOCK) LEFT OUTER JOIN CustomerAttributesFilter CAF WITH(NOLOCK) ON CAF.CurrAccTypeCode = I.CurrAccTypeCode AND CAF.CurrAccCode = I.CurrAccCode LEFT OUTER JOIN ProductAttributesFilter PAF WITH(NOLOCK) ON PAF.ItemCode = I.ItemCode WHERE I.InvoiceDate >= @p1 AND I.InvoiceDate < DATEADD(DAY, 1, @p2) AND I.ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(I.ItemCode))) = 13 AND (@p3 = '' OR UPPER(LTRIM(RTRIM(I.ItemCode))) LIKE @p3 + '%') AND ( (I.CompanyCode = 1 AND I.ATAtt01 IN (1,2) AND I.ProcessCode IN ('WS','R')) OR (I.CompanyCode = 4 AND I.ProcessCode = 'R') ) AND EXISTS ( SELECT 1 FROM trDebitHeader DH WITH(NOLOCK) INNER JOIN trDebitLine DL WITH(NOLOCK) ON DL.DebitHeaderID = DH.DebitHeaderID WHERE DH.ApplicationCode = 'Invoi' AND DH.ApplicationID = I.InvoiceHeaderID ) ) SELECT SalesDate, ProductCode, ColorCode, YakaKodu, ItemDescription = MAX(ItemDescription), Kategori = MAX(Kategori), Seri = '', YasGrubu = '', AskiliYan = ISNULL(NULLIF(MAX(AskiliYan), '-'), ''), UrunIlkGrubu = MAX(UrunIlkGrubu), UrunAnaGrubu = MAX(UrunAnaGrubu), UrunAltGrubu = MAX(UrunAltGrubu), MarketKey = CONCAT(MAX(Kategori), '|', MAX(UrunIlkGrubu), '|', ISNULL(NULLIF(MAX(AskiliYan), '-'), ''), '|', MAX(UrunAnaGrubu), '|', MAX(UrunAltGrubu), '|', ChannelCode), ChannelCode, CustomerCountry = ISNULL(NULLIF(CustomerCountry, ''), '-'), CustomerSegment = ISNULL(NULLIF(CustomerSegment, ''), '-'), CustomerCode = ISNULL(NULLIF(CustomerCode, ''), '-'), CustomerDescription = MAX(ISNULL(NULLIF(CustomerDescription, ''), '-')), SalesQty = ISNULL(SUM(Qty1), 0), SalesTL = ISNULL(SUM(TLAmount), 0), SalesUSD = ISNULL(SUM(USDAmount), 0), AvgPriceUSD = ISNULL(SUM(USDAmount) / NULLIF(SUM(Qty1), 0), 0), InvoiceLineCount = COUNT(DISTINCT InvoiceLineID), InvoiceCount = COUNT(DISTINCT InvoiceHeaderID), CustomerCount = COUNT(DISTINCT CustomerCode), LastRefNumber = MAX(InvoiceNumber) FROM SalesLines WHERE RN = 1 GROUP BY SalesDate, ProductCode, ColorCode, YakaKodu, ChannelCode, CustomerCountry, CustomerSegment, CustomerCode ` } func productPerformanceStockSQLUnused() string { return ` ;WITH ActiveWarehouses AS ( SELECT WarehouseCode FROM (VALUES ('1-0-12'),('1.01.2014'),('1.02.2005'),('1.02.2004'),('1-0-43'), ('4.02.2001'),('1-0-55'),('1.01.2003'),('1-0-21'),('1-0-2'), ('1.01.2004'),('1-0-49'),('1-0-37'),('1-0-29'),('1-0-28'), ('1-0-10'),('100'),('1.02.2006'),('1-0-42'),('1.01.2002'), ('1-0-52') ) W(WarehouseCode) ), Raw AS ( SELECT ProductCode = UPPER(LTRIM(RTRIM(S.ItemCode))), ColorCode = UPPER(LTRIM(RTRIM(ISNULL(S.ColorCode, '')))), YakaKodu = UPPER(LTRIM(RTRIM(ISNULL(S.ItemDim2Code, '')))), MovementDate = CAST(S.DocumentDate AS date), ProcessCode = CASE WHEN LTRIM(RTRIM(ISNULL(S.ProcessCode, ''))) <> '' THEN LTRIM(RTRIM(S.ProcessCode)) ELSE LTRIM(RTRIM(ISNULL(S.InnerProcessCode, ''))) END, InQty = SUM(S.In_Qty1), OutQty = SUM(S.Out_Qty1), NetQty = SUM(S.InventoryQty1) FROM StockWithCost S WITH(NOLOCK) INNER JOIN ActiveWarehouses W ON W.WarehouseCode = LTRIM(RTRIM(S.WarehouseCode)) WHERE S.ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(S.ItemCode))) = 13 AND (@p3 = '' OR UPPER(LTRIM(RTRIM(S.ItemCode))) LIKE @p3 + '%') AND S.DocumentDate < DATEADD(DAY, 1, @p2) GROUP BY S.ItemCode, S.ColorCode, S.ItemDim2Code, CAST(S.DocumentDate AS date), CASE WHEN LTRIM(RTRIM(ISNULL(S.ProcessCode, ''))) <> '' THEN LTRIM(RTRIM(S.ProcessCode)) ELSE LTRIM(RTRIM(ISNULL(S.InnerProcessCode, ''))) END ), Opening AS ( SELECT StockDate = @p1, ProductCode, ColorCode, YakaKodu, NetQty = SUM(NetQty), InQty = CAST(0 AS decimal(18,4)), OutQty = CAST(0 AS decimal(18,4)), KpiInQty = CAST(0 AS decimal(18,4)), KpiOutQty = CAST(0 AS decimal(18,4)), SalesMovementQty = CAST(0 AS decimal(18,4)), ProductionInQty = CAST(0 AS decimal(18,4)), PurchaseInQty = CAST(0 AS decimal(18,4)), ConsumptionOutQty = CAST(0 AS decimal(18,4)), CountDiffQty = CAST(0 AS decimal(18,4)) FROM Raw WHERE MovementDate < @p1 GROUP BY ProductCode, ColorCode, YakaKodu ), Daily AS ( SELECT StockDate = MovementDate, ProductCode, ColorCode, YakaKodu, NetQty = SUM(NetQty), InQty = SUM(InQty), OutQty = SUM(OutQty), KpiInQty = SUM(CASE WHEN ProcessCode IN ('OP','BP','CI') THEN InQty ELSE 0 END), KpiOutQty = SUM(CASE WHEN ProcessCode IN ('R','WS','OC','CO') THEN OutQty ELSE 0 END), SalesMovementQty = SUM(CASE WHEN ProcessCode IN ('R','WS') THEN OutQty ELSE 0 END), ProductionInQty = SUM(CASE WHEN ProcessCode = 'OP' THEN InQty ELSE 0 END), PurchaseInQty = SUM(CASE WHEN ProcessCode = 'BP' THEN InQty ELSE 0 END), ConsumptionOutQty = SUM(CASE WHEN ProcessCode = 'OC' THEN OutQty ELSE 0 END), CountDiffQty = SUM(CASE WHEN ProcessCode IN ('CO','CI') THEN NetQty ELSE 0 END) FROM Raw WHERE MovementDate BETWEEN @p1 AND @p2 GROUP BY MovementDate, ProductCode, ColorCode, YakaKodu ), Series AS ( SELECT * FROM Opening UNION ALL SELECT * FROM Daily ), Collapsed AS ( SELECT StockDate, ProductCode, ColorCode, YakaKodu, NetQty = SUM(NetQty), InQty = SUM(InQty), OutQty = SUM(OutQty), KpiInQty = SUM(KpiInQty), KpiOutQty = SUM(KpiOutQty), SalesMovementQty = SUM(SalesMovementQty), ProductionInQty = SUM(ProductionInQty), PurchaseInQty = SUM(PurchaseInQty), ConsumptionOutQty = SUM(ConsumptionOutQty), CountDiffQty = SUM(CountDiffQty) FROM Series GROUP BY StockDate, ProductCode, ColorCode, YakaKodu ), Running AS ( SELECT StockDate, ProductCode, ColorCode, YakaKodu, StockQty = SUM(NetQty) OVER ( PARTITION BY ProductCode, ColorCode, YakaKodu ORDER BY StockDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), InQty, OutQty, KpiInQty, KpiOutQty, SalesMovementQty, ProductionInQty, PurchaseInQty, ConsumptionOutQty, CountDiffQty FROM Collapsed ) SELECT StockDate, ProductCode, ColorCode, YakaKodu, StockQty, InQty, OutQty, KpiInQty, KpiOutQty, SalesMovementQty, ProductionInQty, PurchaseInQty, ConsumptionOutQty, CountDiffQty FROM Running WHERE StockDate BETWEEN @p1 AND @p2 ORDER BY StockDate, ProductCode, ColorCode, YakaKodu ` } func productPerformancePriceSQL() string { return ` ;WITH ProductCodes AS ( SELECT DISTINCT ItemCode FROM cdItem WITH(NOLOCK) WHERE ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(ItemCode))) = 13 AND (@p1 = '' OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE @p1 + '%') UNION SELECT DISTINCT ItemCode FROM trPriceListLine WITH(NOLOCK) WHERE ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(ItemCode))) = 13 AND (@p1 = '' OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE @p1 + '%') UNION SELECT DISTINCT ItemCode FROM prItemBasePrice WITH(NOLOCK) WHERE ItemTypeCode = 1 AND LEN(LTRIM(RTRIM(ItemCode))) = 13 AND (@p1 = '' OR UPPER(LTRIM(RTRIM(ItemCode))) LIKE @p1 + '%') ), LatestPrice AS ( SELECT p.ItemCode, DocCurrencyCode = LTRIM(RTRIM(p.DocCurrencyCode)), p.Price, rn = ROW_NUMBER() OVER ( PARTITION BY p.ItemCode, LTRIM(RTRIM(p.DocCurrencyCode)) ORDER BY p.ValidDate DESC, p.ValidTime DESC, p.LastUpdatedDate DESC ) FROM trPriceListLine p WITH(NOLOCK) INNER JOIN ProductCodes pc ON pc.ItemCode = p.ItemCode WHERE p.ItemTypeCode = 1 AND ISNULL(p.IsDisabled, 0) = 0 AND LTRIM(RTRIM(p.DocCurrencyCode)) IN ('USD', 'TRY') AND ( (LTRIM(RTRIM(p.DocCurrencyCode)) = 'USD' AND LTRIM(RTRIM(p.PriceGroupCode)) = 'TM-USD') OR (LTRIM(RTRIM(p.DocCurrencyCode)) = 'TRY' AND LTRIM(RTRIM(p.PriceGroupCode)) = 'TM-TRY') ) AND p.Price > 0 ), BasePrice AS ( SELECT ItemCode, BasePriceUsd = MAX(CASE WHEN DocCurrencyCode = 'USD' THEN Price END), BasePriceTry = MAX(CASE WHEN DocCurrencyCode = 'TRY' THEN Price END) FROM LatestPrice WHERE rn = 1 GROUP BY ItemCode ), Cost AS ( SELECT b.ItemCode, CostPriceUsd = CAST(b.Price AS decimal(18,2)), LastPricingDate = CAST(b.PriceDate AS date), rn = ROW_NUMBER() OVER ( PARTITION BY b.ItemCode ORDER BY b.PriceDate DESC, b.LastUpdatedDate DESC ) FROM prItemBasePrice b WITH(NOLOCK) INNER JOIN ProductCodes pc ON pc.ItemCode = b.ItemCode WHERE b.ItemTypeCode = 1 AND b.BasePriceCode = 1 AND LTRIM(RTRIM(b.CurrencyCode)) = 'USD' ) SELECT UPPER(LTRIM(RTRIM(pc.ItemCode))) AS ItemCode, ItemDescription = dbo.HG_Temizlik(ISNULL(( SELECT ItemDescription FROM cdItemDesc WITH(NOLOCK) WHERE cdItemDesc.ItemTypeCode = 1 AND cdItemDesc.ItemCode = pc.ItemCode AND cdItemDesc.LangCode = 'TR' ), SPACE(0))), Kategori = dbo.HG_Temizlik(ISNULL(paf.ProductAtt44, SPACE(0))), AskiliYan = dbo.HG_Temizlik(ISNULL(paf.ProductAtt45, SPACE(0))), UrunIlkGrubu = dbo.HG_Temizlik(ISNULL(paf.ProductAtt42, SPACE(0))), UrunAnaGrubu = dbo.HG_Temizlik(ISNULL(paf.ProductAtt01, SPACE(0))), UrunAltGrubu = dbo.HG_Temizlik(ISNULL(paf.ProductAtt02, SPACE(0))), CostPriceUsd = ISNULL(c.CostPriceUsd, 0), BasePriceUsd = ISNULL(bp.BasePriceUsd, 0), BasePriceTry = ISNULL(bp.BasePriceTry, 0), c.LastPricingDate FROM ProductCodes pc LEFT JOIN ProductAttributesFilter paf WITH(NOLOCK) ON paf.ItemCode = pc.ItemCode LEFT JOIN BasePrice bp ON bp.ItemCode = pc.ItemCode LEFT JOIN Cost c ON c.ItemCode = pc.ItemCode AND c.rn = 1 ` } func productPerformanceKPISQL() string { return ` WITH LatestStock 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 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, color_code, yaka_kodu, market_key, MAX(item_description) AS item_description, MAX(kategori) AS kategori, MAX(seri) AS seri, MAX(yas_grubu) AS yas_grubu, COALESCE(MAX(NULLIF(askili_yan, '-')), '') AS askili_yan, MAX(urun_ilk_grubu) AS urun_ilk_grubu, MAX(urun_ana_grubu) AS urun_ana_grubu, 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 '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 >= DATE '2022-01-01' AND sales_date <= $1::date 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') GROUP BY product_code, color_code, yaka_kodu, market_key ), 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_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 SELECT ls.product_code, ls.color_code, ls.yaka_kodu, 'STOK' AS market_key, '' AS item_description, '' AS kategori, '' AS seri, '' AS yas_grubu, '' AS askili_yan, COALESCE(pd.urun_ilk_grubu, '') AS urun_ilk_grubu, '' AS urun_ana_grubu, '' 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_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 FROM LatestStock ls LEFT JOIN mk_product_performance_price_dim pd ON pd.product_code=ls.product_code WHERE COALESCE(ls.stock_qty, 0) <> 0 AND upper(translate(btrim(COALESCE(pd.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') AND NOT EXISTS ( SELECT 1 FROM SalesAgg sa WHERE sa.product_code = ls.product_code AND sa.color_code = ls.color_code AND sa.yaka_kodu = ls.yaka_kodu ) ), PriceDim AS ( SELECT product_code, COALESCE(urun_ilk_grubu, '') AS urun_ilk_grubu, COALESCE(urun_ana_grubu, '') AS urun_ana_grubu, COALESCE(urun_alt_grubu, '') AS urun_alt_grubu, CASE WHEN cost_price_usd > 0 AND base_price_usd > 0 AND cost_price_usd < base_price_usd THEN base_price_usd ELSE cost_price_usd END AS cost_price_usd, CASE WHEN cost_price_usd > 0 AND base_price_usd > 0 AND cost_price_usd < base_price_usd THEN cost_price_usd ELSE base_price_usd END AS base_price_usd, base_price_try FROM mk_product_performance_price_dim ), Base AS ( SELECT s.*, COALESCE(ls.stock_qty, 0) AS stock_qty, COALESCE(pd.cost_price_usd, 0) AS cost_price_usd, 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, 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, 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, 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 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 PriceDim pd ON pd.product_code=s.product_code WHERE upper(translate(btrim(COALESCE(NULLIF(s.urun_ilk_grubu,''), pd.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') ), 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, AVG(NULLIF(sales_qty_90d, 0)) AS market_avg_sales_qty_90d, AVG(NULLIF(avg_price_usd_90d, 0)) AS market_avg_price_usd_90d, AVG(NULLIF(gross_margin_90d, 0)) AS market_avg_margin_90d FROM Base GROUP BY market_key ), 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.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 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_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, recommendation, last_sale_date, last_ref_number, updated_at ) 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_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), 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_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' WHEN COALESCE(stock_days_90d,0) > 180 AND COALESCE(sales_index_90d,0) < 0.75 THEN 'STOK_RISKI' WHEN COALESCE(price_index_90d,0) > 1.10 AND COALESCE(sales_index_90d,0) < 0.80 THEN 'FIYAT_BASKISI' WHEN COALESCE(price_index_90d,0) < 0.90 AND COALESCE(sales_index_90d,0) > 1.00 THEN 'FIYAT_FIRSATI' ELSE 'TAKIP' END AS performance_bucket, CASE WHEN COALESCE(sales_index_90d,0) >= 1.25 AND COALESCE(gross_margin_90d,0) >= 0.25 THEN 'Piyasa ustu satis ve iyi marj: stok ve fiyat gucu takip edilmeli.' WHEN COALESCE(stock_qty,0) <= 0 AND COALESCE(sales_qty_90d,0) > 0 THEN 'Talep var, stok yok: uretim/satin alma planina alinmali.' WHEN COALESCE(stock_days_90d,0) > 180 AND COALESCE(sales_index_90d,0) < 0.75 THEN 'Stok yuksek, satis piyasa alti: kampanya veya fiyat kontrolu gerekli.' WHEN COALESCE(price_index_90d,0) > 1.10 AND COALESCE(sales_index_90d,0) < 0.80 THEN 'Fiyat piyasa ustunde ve satis zayif: fiyat revizyonu degerlendirilmeli.' WHEN COALESCE(price_index_90d,0) < 0.90 AND COALESCE(sales_index_90d,0) > 1.00 THEN 'Satis guclu, fiyat piyasa alti: taban fiyat artisi degerlendirilebilir.' ELSE 'Duzenli takip.' END AS recommendation, last_sale_date, COALESCE(last_ref_number, ''), now() FROM Scored ` }