Two computer hard drives and a shiny disk displayed on a wooden surface.
SAP

Konya’da 95 çalışanlı bir otomotiv yedek parça üreticisi, SAP B1 sistemini 4 yıl önce kurmuştu ama raporlama hala “ay sonu Excel’e döküm + manuel pivot” düzeyindeydi. Yönetim “stok devir hızı, müşteri karlılığı, ürün bazlı margin” sorularına saatlerce cevap veremiyordu. 5 aylık BI programıyla Power BI + HANA SQL view’leri kuruldu. Bu yazı sahadaki teknik kararlar.

SAP B1 Raporlama Araçları

Araç Tip Kullanım
Built-in queries (Query Manager) SQL select Hızlı liste raporu
Crystal Reports Operational Fatura, irsaliye, fiş template’leri
Excel Reports & Interactive Analysis Self-service Pivot, filtreli analiz
Pervasive Analytics (HANA only) Dashboard KPI dashboard
External BI (Power BI / Tableau) Modern BI Cross-data, ML, advanced viz

Karar: Operasyonel doküman → Crystal; günlük analiz → Power BI.

HANA SQL View’leri

SAP B1 HANA’da çalışıyor. Power BI doğrudan SAP tablo’ya bağlanmak yerine SQL view kullanılıyor (governance + performance):

-- Müşteri karlılık view
CREATE OR REPLACE VIEW "BI_CUSTOMER_PROFIT" AS
SELECT 
    o."CardCode",
    o."CardName",
    DATE(o."DocDate") AS "InvoiceDate",
    o."DocNum",
    SUM(d."LineTotal") AS "Revenue",
    SUM(d."Quantity" * COALESCE(d."StockPrice", 0)) AS "Cost",
    SUM(d."LineTotal") - SUM(d."Quantity" * COALESCE(d."StockPrice", 0)) AS "GrossProfit",
    CASE WHEN SUM(d."LineTotal") = 0 THEN 0
         ELSE ROUND(100.0 * (SUM(d."LineTotal") - SUM(d."Quantity" * COALESCE(d."StockPrice", 0))) 
                / SUM(d."LineTotal"), 2)
    END AS "GrossMarginPct"
FROM "OINV" o
JOIN "INV1" d ON o."DocEntry" = d."DocEntry"
WHERE o."CANCELED" = 'N'
  AND o."DocDate" >= ADD_MONTHS(CURRENT_DATE, -36)
GROUP BY o."CardCode", o."CardName", DATE(o."DocDate"), o."DocNum";
-- Ürün ciro + margin view
CREATE OR REPLACE VIEW "BI_PRODUCT_PERFORMANCE" AS
SELECT
    i."ItemCode",
    i."ItemName",
    i."ItmsGrpCod",
    g."ItmsGrpNam" AS "Category",
    DATE(o."DocDate") AS "Date",
    SUM(d."Quantity") AS "QtySold",
    SUM(d."LineTotal") AS "Revenue",
    SUM(d."Quantity" * i."AvgPrice") AS "EstCost",
    AVG(d."Price") AS "AvgPrice"
FROM "INV1" d
JOIN "OINV" o ON d."DocEntry" = o."DocEntry"
JOIN "OITM" i ON d."ItemCode" = i."ItemCode"
JOIN "OITB" g ON i."ItmsGrpCod" = g."ItmsGrpCod"
WHERE o."CANCELED" = 'N'
GROUP BY i."ItemCode", i."ItemName", i."ItmsGrpCod", g."ItmsGrpNam", DATE(o."DocDate");
-- Stok devir hızı view
CREATE OR REPLACE VIEW "BI_INVENTORY_TURNOVER" AS
SELECT
    i."ItemCode",
    i."ItemName",
    SUM(d."Quantity" * i."AvgPrice") OVER (PARTITION BY i."ItemCode") AS "COGS_12M",
    i."OnHand" * i."AvgPrice" AS "InventoryValue",
    CASE WHEN i."OnHand" * i."AvgPrice" = 0 THEN 0
         ELSE SUM(d."Quantity" * i."AvgPrice") OVER (PARTITION BY i."ItemCode") 
              / NULLIF(i."OnHand" * i."AvgPrice", 0)
    END AS "TurnoverRatio"
FROM "OITM" i
LEFT JOIN "INV1" d ON i."ItemCode" = d."ItemCode"
LEFT JOIN "OINV" o ON d."DocEntry" = o."DocEntry"
WHERE o."DocDate" >= ADD_MONTHS(CURRENT_DATE, -12)
GROUP BY i."ItemCode", i."ItemName", i."OnHand", i."AvgPrice", d."Quantity";

Power BI Bağlantısı

Power BI Desktop → Get Data → SAP HANA → Direct Query veya Import.

  • Direct Query: Real-time, ama yavaş (her interaction HANA’ya gidiyor)
  • Import: Hızlı, ama veri model’i yenilenmesi lazım (gece 03:00 schedule)

Karma model: KPI dashboard import (gece refresh), drill-down detay direct query.

Dashboard Örneği: Yönetici Paneli

4 ana KPI:

  1. Aylık Ciro: Hedef vs gerçekleşme, YoY karşılaştırma
  2. Brüt Marj %: Trend + ürün kategorisi breakdown
  3. Stok Devir Hızı: Top 20 yavaş hareketli SKU
  4. Müşteri ABC Analizi: A müşteri (cironun %80’i), B (%15), C (%5)

DAX Örneği: Pareto Analizi

RunningRevenue = 
CALCULATE(
    SUM(Sales[Revenue]),
    FILTER(
        ALL(Customers[CustomerName]),
        Customers[TotalRevenueRank] <= MAX(Customers[TotalRevenueRank])
    )
)

CumulativePct = 
DIVIDE(
    [RunningRevenue],
    CALCULATE(SUM(Sales[Revenue]), ALL(Customers))
)

ABCClass = 
SWITCH(
    TRUE(),
    [CumulativePct] <= 0.80, "A",
    [CumulativePct] <= 0.95, "B",
    "C"
)

Row-Level Security (RLS)

Satış müdürleri sadece kendi bölgelerini görmeli:

// Power BI RLS rule
[Region] = LOOKUPVALUE(
    UserRegions[Region],
    UserRegions[UserEmail], 
    USERPRINCIPALNAME()
)

Sonuçlar (5 Ay)

Metrik Önce Sonra
Aylık rapor hazırlık süresi ~~22 saat (manuel Excel) 0 (otomatik refresh)
Yönetim “neden” sorusuna cevap süresi ~~3 gün ~~5 dk (drill-down)
Stok devir hızı görünürlüğü Aylık Anlık
Yavaş hareketli SKU temizlik %0 %18 stok azalması
Müşteri karlılık görünürlüğü Yıllık Aylık (3 zarar müşteri tespit + fiyat revize)

Sahada Düşülen Üç Tuzak

  1. SAP tablolarına direkt Power BI bağlamak: 1.000+ tablo karışık, Power BI yorucu. SQL view layer şart.
  2. Tüm raporu Direct Query yapmak: Her tıklama HANA’yı yoruyor, kullanıcı şikayet ediyor. KPI import + detay direct query.
  3. RLS yapmadan herkesi her veriye sokmak: Satış müdürü rakip bölgenin verisini görmemeli. RLS day 1.

CloudSpark olarak SAP B1 raporlama, HANA SQL view tasarımı, Power BI dashboard, RLS ve veri ambarı projeleri için danışmanlık veriyoruz.

🇹🇷 Türkçe🇬🇧 English🇩🇪 Deutsch🇫🇷 Français🇸🇦 العربية🇷🇺 Русский🇪🇸 Español