package queries func productPerformanceSalesSQL() string { return ` ;WITH SalesLines AS ( SELECT I.InvoiceLineID, SalesDate = CAST(I.InvoiceDate AS date), I.InvoiceHeaderID, I.InvoiceNumber, ProductCode = LTRIM(RTRIM(I.ItemCode)), ColorCode = LTRIM(RTRIM(ISNULL(I.ColorCode, ''))), YakaKodu = 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(( SELECT AttributeDescription FROM cdItemAttributeDesc WITH(NOLOCK) WHERE cdItemAttributeDesc.ItemTypeCode = I.ItemTypeCode AND cdItemAttributeDesc.AttributeTypeCode = 1 AND cdItemAttributeDesc.AttributeCode = ( SELECT TOP 1 AttributeCode FROM prItemAttribute WITH(NOLOCK) WHERE AttributeTypeCode = 1 AND prItemAttribute.ItemTypeCode = I.ItemTypeCode AND prItemAttribute.ItemCode = I.ItemCode ) AND cdItemAttributeDesc.LangCode = 'TR' ), SPACE(0))), UrunAltGrubu = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdItemAttributeDesc WITH(NOLOCK) WHERE cdItemAttributeDesc.ItemTypeCode = I.ItemTypeCode AND cdItemAttributeDesc.AttributeTypeCode = 2 AND cdItemAttributeDesc.AttributeCode = ( SELECT TOP 1 AttributeCode FROM prItemAttribute WITH(NOLOCK) WHERE AttributeTypeCode = 2 AND prItemAttribute.ItemTypeCode = I.ItemTypeCode AND prItemAttribute.ItemCode = I.ItemCode ) AND cdItemAttributeDesc.LangCode = 'TR' ), SPACE(0))), Kategori = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdItemAttributeDesc WITH(NOLOCK) WHERE cdItemAttributeDesc.ItemTypeCode = I.ItemTypeCode AND cdItemAttributeDesc.AttributeTypeCode = 42 AND cdItemAttributeDesc.AttributeCode = ( SELECT TOP 1 AttributeCode FROM prItemAttribute WITH(NOLOCK) WHERE AttributeTypeCode = 42 AND prItemAttribute.ItemTypeCode = I.ItemTypeCode AND prItemAttribute.ItemCode = I.ItemCode ) AND cdItemAttributeDesc.LangCode = 'TR' ), SPACE(0))), UrunIlkGrubu = dbo.HG_Temizlik(ISNULL(( SELECT AttributeDescription FROM cdItemAttributeDesc WITH(NOLOCK) WHERE cdItemAttributeDesc.ItemTypeCode = I.ItemTypeCode AND cdItemAttributeDesc.AttributeTypeCode = 44 AND cdItemAttributeDesc.AttributeCode = ( SELECT TOP 1 AttributeCode FROM prItemAttribute WITH(NOLOCK) WHERE AttributeTypeCode = 44 AND prItemAttribute.ItemTypeCode = I.ItemTypeCode AND prItemAttribute.ItemCode = I.ItemCode ) AND cdItemAttributeDesc.LangCode = 'TR' ), SPACE(0))), AskiliYan = dbo.HG_Temizlik(ISNULL(( SELECT TOP 1 ProductAtt45 FROM ProductAttributesFilter WITH(NOLOCK) WHERE ProductAttributesFilter.ItemCode = I.ItemCode ), 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 WHERE I.InvoiceDate >= @p1 AND I.InvoiceDate < DATEADD(DAY, 1, @p2) AND I.ItemTypeCode = 1 AND (I.ItemCode LIKE 'S%' OR I.ItemCode LIKE 'O%' OR I.ItemCode LIKE 'X%' OR I.ItemCode LIKE 'N%') 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 = MAX(Kategori), YasGrubu = MAX(UrunIlkGrubu), AskiliYan = MAX(AskiliYan), UrunIlkGrubu = MAX(UrunIlkGrubu), UrunAnaGrubu = MAX(UrunAnaGrubu), UrunAltGrubu = MAX(UrunAltGrubu), MarketKey = CONCAT(MAX(Kategori), '|', MAX(UrunIlkGrubu), '|', 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 productPerformanceStockSQL() string { return ` ;WITH ActiveWarehouses AS ( SELECT WarehouseCode FROM (VALUES ('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') ) W(WarehouseCode) ), Raw AS ( SELECT ProductCode = LTRIM(RTRIM(S.ItemCode)), ColorCode = LTRIM(RTRIM(ISNULL(S.ColorCode, ''))), YakaKodu = 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 (S.ItemCode LIKE 'S%' OR S.ItemCode LIKE 'O%' OR S.ItemCode LIKE 'X%' OR S.ItemCode LIKE 'N%') 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 ), 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 Series ) 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 trPriceListLine WITH(NOLOCK) WHERE ItemTypeCode = 1 AND (ItemCode LIKE 'S%' OR ItemCode LIKE 'O%' OR ItemCode LIKE 'X%' OR ItemCode LIKE 'N%') UNION SELECT DISTINCT ItemCode FROM prItemBasePrice WITH(NOLOCK) WHERE ItemTypeCode = 1 AND (ItemCode LIKE 'S%' OR ItemCode LIKE 'O%' OR ItemCode LIKE 'X%' OR ItemCode LIKE 'N%') ), 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 pc.ItemCode, CostPriceUsd = ISNULL(c.CostPriceUsd, 0), BasePriceUsd = ISNULL(bp.BasePriceUsd, 0), BasePriceTry = ISNULL(bp.BasePriceTry, 0), c.LastPricingDate FROM ProductCodes pc 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 ), 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, MAX(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 '364 days') AS sales_qty_365d, SUM(sales_qty) FILTER (WHERE sales_date >= $1::date - INTERVAL '729 days') AS sales_qty_730d, SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '29 days') AS sales_usd_30d, SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '89 days') AS sales_usd_90d, SUM(sales_usd) FILTER (WHERE sales_date >= $1::date - INTERVAL '364 days') AS sales_usd_365d, SUM(customer_count) 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' AND sales_date <= $1::date 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_365d, sales_qty_730d, sales_usd_30d, sales_usd_90d, sales_usd_365d, 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, '' 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_365d, 0 AS sales_qty_730d, 0 AS sales_usd_30d, 0 AS sales_usd_90d, 0 AS sales_usd_365d, 0 AS customer_count_90d, NULL::date AS last_sale_date, '' AS last_ref_number FROM LatestStock ls WHERE COALESCE(ls.stock_qty, 0) <> 0 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 ) ), 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, 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, COALESCE(s.sales_usd_90d, 0) - (COALESCE(s.sales_qty_90d, 0) * COALESCE(pd.cost_price_usd, 0)) AS gross_profit_usd_90d, 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 FROM Scope s LEFT JOIN LatestStock ls ON ls.product_code=s.product_code AND ls.color_code=s.color_code AND ls.yaka_kodu=s.yaka_kodu LEFT JOIN mk_product_performance_price_dim pd ON pd.product_code=s.product_code ), 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.*, 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 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 ) INSERT INTO mk_product_performance_kpi_daily ( kpi_date, product_code, color_code, yaka_kodu, item_description, kategori, seri, yas_grubu, askili_yan, urun_ilk_grubu, urun_ana_grubu, urun_alt_grubu, market_key, stock_qty, sales_qty_30d, sales_qty_90d, sales_qty_365d, sales_qty_730d, sales_usd_30d, sales_usd_90d, sales_usd_365d, avg_daily_sales_90d, stock_days_90d, avg_price_usd_90d, cost_price_usd, base_price_usd, base_price_try, gross_profit_usd_90d, gross_margin_90d, customer_count_90d, sales_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_365d, 0), COALESCE(sales_qty_730d, 0), COALESCE(sales_usd_30d, 0), COALESCE(sales_usd_90d, 0), COALESCE(sales_usd_365d, 0), COALESCE(avg_daily_sales_90d, 0), COALESCE(stock_days_90d, 0), COALESCE(avg_price_usd_90d, 0), COALESCE(cost_price_usd, 0), COALESCE(base_price_usd, 0), COALESCE(base_price_try, 0), COALESCE(gross_profit_usd_90d, 0), COALESCE(gross_margin_90d, 0), COALESCE(customer_count_90d, 0), COALESCE(sales_index_90d, 0), COALESCE(price_index_90d, 0), COALESCE(margin_index_90d, 0), ROUND( LEAST(40, COALESCE(sales_index_90d, 0) * 20) + LEAST(25, GREATEST(COALESCE(gross_margin_90d, 0), 0) * 50) + LEAST(20, COALESCE(customer_count_90d, 0) * 2) + CASE WHEN COALESCE(stock_days_90d, 0) BETWEEN 10 AND 90 THEN 15 WHEN COALESCE(stock_days_90d, 0) > 180 THEN -10 ELSE 0 END , 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 üstü satış ve iyi marj: stok ve fiyat gücü takip edilmeli.' WHEN COALESCE(stock_qty,0) <= 0 AND COALESCE(sales_qty_90d,0) > 0 THEN 'Talep var, stok yok: üretim/satın alma planına alınmalı.' WHEN COALESCE(stock_days_90d,0) > 180 AND COALESCE(sales_index_90d,0) < 0.75 THEN 'Stok yüksek, satış piyasa altı: kampanya veya fiyat kontrolü gerekli.' WHEN COALESCE(price_index_90d,0) > 1.10 AND COALESCE(sales_index_90d,0) < 0.80 THEN 'Fiyat piyasa üstünde ve satış zayıf: fiyat revizyonu değerlendirilmeli.' WHEN COALESCE(price_index_90d,0) < 0.90 AND COALESCE(sales_index_90d,0) > 1.00 THEN 'Satış güçlü, fiyat piyasa altı: taban fiyat artışı değerlendirilebilir.' ELSE 'Düzenli takip.' END AS recommendation, last_sale_date, COALESCE(last_ref_number, ''), now() FROM Scored ` }