---
title: "Mikro ERP Cari Kredi Derecelendirme ve Risk Skorlama: Yaşlandırma Verileriyle Otomatik Sınıflandırma"
description: "Müşterilerinizi A-B-C-D-E risk sınıflarına otomatik ayırın. Ortalama tahsilat süresi, vadesinde ödeme yüzdesi, bakiye trendi ve çek riski bileşenleriyle SQL tabanlı kredi derecelendirme modeli."
date: 2026-06-27
category: mikro-erp
tags: ["mikro-erp", "sql-server", "cari-hesap", "risk-skorlama", "derecelendirme", "kredi-limit", "karar-destek", "astaflow"]
url: https://mikroerp.dev/blog/mikro-erp-cari-kredi-derecelendirme-skorlama-sql/
---

## Neden Otomatik Derecelendirme?

"Bu müşteriye daha fazla vadeli satış yapabilir miyiz?" sorusunu her defasında bir kişinin tecrübesine bırakmak **ölçeklenebilir değildir**. 500+ müşteriniz varsa, her birini tek tek incelemek imkânsızdır.

**Otomatik derecelendirme** ERP verilerinden hesaplanan metriklerle müşterilerinizi risk sınıflarına ayırır:

| Sınıf | Risk | Kredi Kararı |
|---|---|---|
| **A** | Çok Düşük | Vade uzatılabilir, limit artırılabilir |
| **B** | Düşük | Standart vade, limit yeterli |
| **C** | Orta | Yakın takip, teminat istenmeli |
| **D** | Yüksek | Vade kısaltılmalı, limit düşürülmeli |
| **E** | Çok Yüksek | Peşin satış veya satış durdurma |

## Skor Bileşenleri ve Ağırlıkları

Kredi skoru 5 bileşenden oluşur. Her bileşen 0-100 arası puan alır, sonra ağırlıkla çarpılır:

| Bileşen | Ağırlık | Veri Kaynağı |
|---|---|---|
| Ortalama Tahsilat Süresi | %30 | FIFO parça ağırlıklı DSO |
| Vadesinde Ödeme Yüzdesi | %25 | FIFO parça bazlı vade analizi |
| Mevcut Bakiye / Limit Oranı | %20 | Bakiye vs teminat karşılaştırması |
| Bakiye Trend Yönü | %15 | Son 3 ay bakiye değişimi |
| Çek/Senet Risk Faktörü | %10 | Vadeli ödeme aracı oranı |

## Adım 1: Test Verisi ile Skorlama (Mikro ERP Gerekmez)

Önce konsepti anlamak için test verisi ile çalışalım:

```sql
-- =============================================
-- TEST VERISI - Kendi DB'nizde calistirabilirsiniz
-- =============================================
IF OBJECT_ID('tempdb..#CariMetrikler') IS NOT NULL DROP TABLE #CariMetrikler;

CREATE TABLE #CariMetrikler (
    CariKod VARCHAR(50),
    CariAd VARCHAR(200),
    OrtTahsilatGun DECIMAL(10,1),      -- Ort. tahsilat suresi (gun)
    VadesindeOdemeYuzde DECIMAL(5,1),  -- Vadesinde odeme %
    MevcutBakiye DECIMAL(18,2),        -- Acik bakiye
    KrediLimiti DECIMAL(18,2),         -- Teminat/limit
    BakiyeOncekiAy DECIMAL(18,2),      -- Onceki ay bakiye
    BakiyeIkiAyOnce DECIMAL(18,2),     -- 2 ay onceki bakiye
    CekOrani DECIMAL(5,1)              -- Toplam tahsilatta cek yuzdesi
);

INSERT INTO #CariMetrikler VALUES
    ('120.001', 'ABC Matbaa Ltd.', 28.5, 92.0, 45000, 100000, 42000, 38000, 15.0),
    ('120.002', 'XYZ Ticaret A.S.', 65.3, 48.0, 180000, 50000, 150000, 120000, 85.0),
    ('120.003', 'DEF Gida San.', 42.0, 71.0, 95000, 80000, 100000, 110000, 45.0),
    ('120.004', 'GHI Insaat', 15.2, 98.0, 12000, 200000, 15000, 10000, 0.0),
    ('120.005', 'JKL Tekstil', 88.7, 35.0, 250000, 30000, 200000, 160000, 92.0);
```

## Adım 2: Her Bileşenin Puanlanması

```sql
;WITH Puanlama AS (
    SELECT
        CariKod,
        CariAd,
        OrtTahsilatGun,
        VadesindeOdemeYuzde,
        MevcutBakiye,
        KrediLimiti,

        -- BILESEN 1: Ort. Tahsilat Suresi Puani (0-100)
        -- 0-30 gun = 100, 30-60 gun = 75, 60-90 gun = 50, 90-120 gun = 25, 120+ = 0
        CASE
            WHEN OrtTahsilatGun <= 30 THEN 100
            WHEN OrtTahsilatGun <= 60 THEN 100 - ((OrtTahsilatGun - 30) * 100.0 / 90)
            WHEN OrtTahsilatGun <= 90 THEN 50 - ((OrtTahsilatGun - 60) * 50.0 / 60)
            WHEN OrtTahsilatGun <= 120 THEN 25 - ((OrtTahsilatGun - 90) * 25.0 / 30)
            ELSE 0
        END AS TahsilatPuan,

        -- BILESEN 2: Vadesinde Odeme Puani (0-100)
        -- Direkt yuzde degeri kullanilir
        VadesindeOdemeYuzde AS VadePuan,

        -- BILESEN 3: Bakiye/Limit Orani Puani (0-100)
        -- Bakiye < %50 limit = 100, %50-80 = 75, %80-100 = 50, %100-150 = 25, >%150 = 0
        CASE
            WHEN KrediLimiti = 0 THEN 0  -- Limitsiz = en riskli
            WHEN MevcutBakiye / KrediLimiti <= 0.5 THEN 100
            WHEN MevcutBakiye / KrediLimiti <= 0.8 THEN 75
            WHEN MevcutBakiye / KrediLimiti <= 1.0 THEN 50
            WHEN MevcutBakiye / KrediLimiti <= 1.5 THEN 25
            ELSE 0
        END AS LimitPuan,

        -- BILESEN 4: Bakiye Trend Puani (0-100)
        -- Bakiye azaliyorsa iyi (100), artiyorsa kotu (0)
        CASE
            WHEN MevcutBakiye < BakiyeIkiAyOnce THEN 100  -- Azaliyor: iyi
            WHEN MevcutBakiye = BakiyeIkiAyOnce THEN 75   -- Sabit: orta
            WHEN MevcutBakiye < BakiyeIkiAyOnce * 1.2 THEN 50  -- Hafif artiyor
            WHEN MevcutBakiye < BakiyeIkiAyOnce * 1.5 THEN 25  -- Belirgin artiyor
            ELSE 0                                               -- Hizla artiyor
        END AS TrendPuan,

        -- BILESEN 5: Cek Riski Puani (0-100)
        -- Dusuk cek orani = yuksek puan
        CASE
            WHEN CekOrani <= 20 THEN 100   -- Cogunlukla nakit
            WHEN CekOrani <= 40 THEN 80
            WHEN CekOrani <= 60 THEN 60
            WHEN CekOrani <= 80 THEN 40
            ELSE 20                         -- Cogunlukla cek = riskli
        END AS CekPuan

    FROM #CariMetrikler
),

-- AGIRLIKLI SKOR HESAPLAMA
Skorlama AS (
    SELECT
        CariKod,
        CariAd,
        OrtTahsilatGun,
        VadesindeOdemeYuzde,
        MevcutBakiye,
        KrediLimiti,
        TahsilatPuan,
        VadePuan,
        LimitPuan,
        TrendPuan,
        CekPuan,

        -- TOPLAM SKOR (agirlikli ortalama)
        CONVERT(decimal(5,1),
            TahsilatPuan * 0.30       -- %30
          + VadePuan * 0.25           -- %25
          + LimitPuan * 0.20          -- %20
          + TrendPuan * 0.15          -- %15
          + CekPuan * 0.10            -- %10
        ) AS ToplamSkor
    FROM Puanlama
)

-- SINIFLANDIRMA
SELECT
    CariKod AS [Cari Kodu],
    CariAd AS [Musteri],
    ToplamSkor AS [Kredi Skoru],
    CASE
        WHEN ToplamSkor >= 80 THEN 'A'
        WHEN ToplamSkor >= 65 THEN 'B'
        WHEN ToplamSkor >= 50 THEN 'C'
        WHEN ToplamSkor >= 35 THEN 'D'
        ELSE 'E'
    END AS [Risk Sinifi],
    CASE
        WHEN ToplamSkor >= 80 THEN 'Cok Dusuk Risk'
        WHEN ToplamSkor >= 65 THEN 'Dusuk Risk'
        WHEN ToplamSkor >= 50 THEN 'Orta Risk'
        WHEN ToplamSkor >= 35 THEN 'Yuksek Risk'
        ELSE 'Cok Yuksek Risk'
    END AS [Risk Durumu],

    -- Bilesen detaylari
    TahsilatPuan AS [Tahsilat Puan],
    VadePuan AS [Vade Puan],
    LimitPuan AS [Limit Puan],
    TrendPuan AS [Trend Puan],
    CekPuan AS [Cek Puan],

    -- Ek bilgiler
    CONVERT(VARCHAR, OrtTahsilatGun) + ' gun' AS [Ort Tahsilat],
    CONVERT(VARCHAR, CONVERT(int, VadesindeOdemeYuzde)) + '%' AS [Vadesinde %],
    CONVERT(VARCHAR, CONVERT(int, MevcutBakiye)) + ' / '
        + CONVERT(VARCHAR, CONVERT(int, KrediLimiti)) AS [Bakiye/Limit]

FROM Skorlama
ORDER BY ToplamSkor DESC;
```

### Beklenen Output

| Cari Kodu | Müşteri | Skor | Sınıf | Risk | Tahsilat | Vade | Limit | Trend | Çek |
|---|---|---|---|---|---|---|---|---|---|
| 120.004 | GHİ İnşaat | 94,5 | A | Çok Düşük | 100 | 98 | 100 | 75 | 100 |
| 120.001 | ABC Matbaa | 85,8 | A | Çok Düşük | 100 | 92 | 100 | 0 | 80 |
| 120.003 | DEF Gıda | 60,7 | B | Düşük | 63 | 71 | 50 | 100 | 60 |
| 120.002 | XYZ Ticaret | 30,4 | E | Çok Yüksek | 17 | 48 | 0 | 0 | 20 |
| 120.005 | JKL Tekstil | 20,5 | E | Çok Yüksek | 0 | 35 | 0 | 0 | 20 |

## Adım 3: Mikro ERP Tabloları ile Gerçek Veri

Test verisini anladıysanız, gerçek Mikro ERP verilerinden metrikleri çekmek için şu tabloları kullanın:

```sql
-- Gercek Mikro ERP verisi ile metrik hesaplama
;WITH CariBakiye AS (
    SELECT
        cha_kod AS CariKod,
        SUM(CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END) AS MevcutBakiye
    FROM CARI_HESAP_HAREKETLERI WITH (NOLOCK)
    WHERE cha_iptal = 0
    GROUP BY cha_kod
    HAVING SUM(CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END) > 0
),
CariTeminat AS (
    SELECT
        ct_carikodu AS CariKod,
        SUM(ct_tutari) AS KrediLimiti
    FROM CARI_HESAP_TEMINATLARI WITH (NOLOCK)
    WHERE ISNULL(ct_iptal, 0) = 0
    GROUP BY ct_carikodu
),
TahsilatAraci AS (
    SELECT
        cha_kod AS CariKod,
        -- Cek yuzdesi
        100.0 * SUM(CASE WHEN cha_cinsi = 1 THEN cha_meblag ELSE 0 END)
              / NULLIF(SUM(cha_meblag), 0) AS CekOrani
    FROM CARI_HESAP_HAREKETLERI WITH (NOLOCK)
    WHERE cha_tip = 1 AND cha_iptal = 0 AND cha_meblag > 0
    GROUP BY cha_kod
)

SELECT
    cb.CariKod,
    c.cari_unvan1 AS CariAd,
    cb.MevcutBakiye,
    ISNULL(ct.KrediLimiti, 0) AS KrediLimiti,
    ISNULL(ta.CekOrani, 0) AS CekOrani
    -- OrtTahsilatGun ve VadesindeOdemeYuzde icin
    -- ayri FIFO hesaplama gerekir (ilgili yazilara bakin)
FROM CariBakiye cb
INNER JOIN CARI_HESAPLAR c WITH (NOLOCK) ON cb.CariKod = c.cari_kod
LEFT JOIN CariTeminat ct ON cb.CariKod = ct.CariKod
LEFT JOIN TahsilatAraci ta ON cb.CariKod = ta.CariKod
ORDER BY cb.MevcutBakiye DESC;
```

> **Not:** Ortalama tahsilat süresi ve vadesinde ödeme yüzdesi için FIFO parça bazlı hesaplama gerekir. Detaylar:
> - [Ortalama Tahsilat Süresi (DSO)](/blog/mikro-erp-ortalama-tahsilat-suresi-dso-sql/)
> - [Vadesinde Ödeme Yüzdesi](/blog/mikro-erp-vadesinde-odeme-yuzdesi-sql/)

## Skor Bantlarını Özelleştirme

Yukarıdaki eşik değerleri ve ağırlıklar bir **başlangıç noktasıdır**. Kendi işletmenize göre ayarlamanız gereken parametreler:

### Tahsilat Süresi Eşikleri

| Sektör | "İyi" | "Kabul Edilebilir" | "Riskli" |
|---|---|---|---|
| **Perakende** | 0-15 gün | 15-30 gün | 30+ gün |
| **Toptan** | 0-45 gün | 45-90 gün | 90+ gün |
| **İnşaat/Proje** | 0-90 gün | 90-180 gün | 180+ gün |

### Ağırlıkları Değiştirme

```sql
-- Sektorunuze gore agirliklari degistirin
-- Toptan ticaret icin tahsilat suresi daha onemli:
TahsilatPuan * 0.35    -- %30 -> %35
VadePuan * 0.25        -- ayni
LimitPuan * 0.20       -- ayni
TrendPuan * 0.10       -- %15 -> %10
CekPuan * 0.10         -- ayni
-- Toplam: %100
```

## Kredi Limit Önerisi

Skor bazlı otomatik kredi limit önerisi:

```sql
-- Risk sinifina gore limit carpani
SELECT
    CariKod,
    CariAd,
    ToplamSkor,
    CASE
        WHEN ToplamSkor >= 80 THEN 'A'
        WHEN ToplamSkor >= 65 THEN 'B'
        WHEN ToplamSkor >= 50 THEN 'C'
        WHEN ToplamSkor >= 35 THEN 'D'
        ELSE 'E'
    END AS Sinif,

    -- Aylik ortalama satis
    MevcutBakiye AS [Mevcut Bakiye],

    -- Onerilen limit (risk sinifina gore carpan)
    CASE
        WHEN ToplamSkor >= 80 THEN MevcutBakiye * 3.0   -- A: 3 aylik
        WHEN ToplamSkor >= 65 THEN MevcutBakiye * 2.0   -- B: 2 aylik
        WHEN ToplamSkor >= 50 THEN MevcutBakiye * 1.0   -- C: 1 aylik
        WHEN ToplamSkor >= 35 THEN MevcutBakiye * 0.5   -- D: yarim aylik
        ELSE 0                                            -- E: limit yok
    END AS [Onerilen Limit]

FROM Skorlama
ORDER BY ToplamSkor DESC;
```

## Nihai Tam Sorgu: Kopyala — Yapıştır — Çalıştır

Test verisi dahil — herhangi bir SQL Server'da çalışır, Mikro ERP gerekmez:

```sql
-- =============================================
-- CARI KREDI DERECELENDIRME VE SKORLAMA
-- Kullanim: Direkt F5 basin, sonuc gelir
-- Test verisi dahil, Mikro ERP gerekmez
-- Uyumluluk: SQL Server 2016+
-- =============================================

-- TEST VERISI
IF OBJECT_ID('tempdb..#CariMetrikler') IS NOT NULL DROP TABLE #CariMetrikler;

CREATE TABLE #CariMetrikler (
    CariKod VARCHAR(50), CariAd VARCHAR(200),
    OrtTahsilatGun DECIMAL(10,1), VadesindeOdemeYuzde DECIMAL(5,1),
    MevcutBakiye DECIMAL(18,2), KrediLimiti DECIMAL(18,2),
    BakiyeOncekiAy DECIMAL(18,2), BakiyeIkiAyOnce DECIMAL(18,2),
    CekOrani DECIMAL(5,1)
);

INSERT INTO #CariMetrikler VALUES
    ('120.001', 'ABC Matbaa Ltd.',    28.5, 92.0, 45000,  100000, 42000,  38000,  15.0),
    ('120.002', 'XYZ Ticaret A.S.',   65.3, 48.0, 180000,  50000, 150000, 120000, 85.0),
    ('120.003', 'DEF Gida San.',      42.0, 71.0, 95000,   80000, 100000, 110000, 45.0),
    ('120.004', 'GHI Insaat',         15.2, 98.0, 12000,  200000, 15000,  10000,   0.0),
    ('120.005', 'JKL Tekstil',        88.7, 35.0, 250000,  30000, 200000, 160000, 92.0);

-- PUANLAMA + SINIFLANDIRMA
;WITH Skorlama AS (
    SELECT *,
        -- Tahsilat suresi puani (0-100)
        CASE WHEN OrtTahsilatGun <= 30 THEN 100
             WHEN OrtTahsilatGun <= 60 THEN 100 - ((OrtTahsilatGun-30) * 100.0/90)
             WHEN OrtTahsilatGun <= 90 THEN 50 - ((OrtTahsilatGun-60) * 50.0/60)
             ELSE 0 END AS P1,
        -- Vadesinde odeme puani
        VadesindeOdemeYuzde AS P2,
        -- Bakiye/limit puani
        CASE WHEN KrediLimiti = 0 THEN 0
             WHEN MevcutBakiye/KrediLimiti <= 0.5 THEN 100
             WHEN MevcutBakiye/KrediLimiti <= 0.8 THEN 75
             WHEN MevcutBakiye/KrediLimiti <= 1.0 THEN 50
             WHEN MevcutBakiye/KrediLimiti <= 1.5 THEN 25
             ELSE 0 END AS P3,
        -- Trend puani
        CASE WHEN MevcutBakiye < BakiyeIkiAyOnce THEN 100
             WHEN MevcutBakiye = BakiyeIkiAyOnce THEN 75
             WHEN MevcutBakiye < BakiyeIkiAyOnce * 1.2 THEN 50
             WHEN MevcutBakiye < BakiyeIkiAyOnce * 1.5 THEN 25
             ELSE 0 END AS P4,
        -- Cek risk puani
        CASE WHEN CekOrani <= 20 THEN 100 WHEN CekOrani <= 40 THEN 80
             WHEN CekOrani <= 60 THEN 60 WHEN CekOrani <= 80 THEN 40
             ELSE 20 END AS P5
    FROM #CariMetrikler
)

SELECT
    CariKod AS [Cari Kodu],
    CariAd AS [Musteri],
    CONVERT(decimal(5,1), P1*0.30 + P2*0.25 + P3*0.20 + P4*0.15 + P5*0.10) AS [Kredi Skoru],
    CASE
        WHEN P1*0.30+P2*0.25+P3*0.20+P4*0.15+P5*0.10 >= 80 THEN 'A - Cok Dusuk Risk'
        WHEN P1*0.30+P2*0.25+P3*0.20+P4*0.15+P5*0.10 >= 65 THEN 'B - Dusuk Risk'
        WHEN P1*0.30+P2*0.25+P3*0.20+P4*0.15+P5*0.10 >= 50 THEN 'C - Orta Risk'
        WHEN P1*0.30+P2*0.25+P3*0.20+P4*0.15+P5*0.10 >= 35 THEN 'D - Yuksek Risk'
        ELSE 'E - Cok Yuksek Risk'
    END AS [Risk Sinifi],
    CONVERT(int, P1) AS [Tahsilat], CONVERT(int, P2) AS [Vade],
    CONVERT(int, P3) AS [Limit], CONVERT(int, P4) AS [Trend], CONVERT(int, P5) AS [Cek],
    CONVERT(VARCHAR, OrtTahsilatGun) + ' gun' AS [Ort Tahsilat],
    CONVERT(VARCHAR, CONVERT(int, VadesindeOdemeYuzde)) + '%' AS [Vadesinde %],
    CONVERT(VARCHAR, CONVERT(int, MevcutBakiye)) + ' / '
        + CONVERT(VARCHAR, CONVERT(int, KrediLimiti)) AS [Bakiye/Limit]
FROM Skorlama
ORDER BY (P1*0.30 + P2*0.25 + P3*0.20 + P4*0.15 + P5*0.10) DESC;

DROP TABLE #CariMetrikler;
```

> **Kendi verilerinizle kullanmak için:** `#CariMetrikler` INSERT satırlarını Mikro ERP'den çektiğiniz gerçek metriklerle değiştirin. Metriklerin nasıl hesaplandığını [DSO](/blog/mikro-erp-ortalama-tahsilat-suresi-dso-sql/) ve [Vadesinde Ödeme](/blog/mikro-erp-vadesinde-odeme-yuzdesi-sql/) yazılarında bulabilirsiniz.

## Edge Cases

1. **Yeni müşteriler:** Yeterli geçmiş verisi olmayan müşteriler için varsayılan olarak **C sınıfı** (orta risk) atanabilir. 3 aylık veri biriktiğinde otomatik derecelendirme devreye girer.

2. **Mevsimsel müşteriler:** Tarım veya turizm sektöründe sezonluk alım yapan müşteriler için bakiye trend bileşeni yanıltıcı olabilir. Son 12 ay ortalaması daha sağlıklıdır.

3. **Grup şirketleri:** Aynı grubun farklı tüzel kişilikleri varsa, grup bazlı konsolide skor hesaplanmalıdır.

4. **Dövizli cariler:** Bakiye ve limit karşılaştırmasında aynı döviz cinsi kullanılmalıdır.

## İlgili Yazılar

- [Cari Risk Raporu — Bakiye, Sipariş, Teminat](/blog/mikro-erp-cari-risk-raporu-sql/)
- [Ortalama Tahsilat Süresi (DSO) Hesaplama](/blog/mikro-erp-ortalama-tahsilat-suresi-dso-sql/)
- [Vadesinde Ödeme Yüzdesi Analizi](/blog/mikro-erp-vadesinde-odeme-yuzdesi-sql/)
- [Cari Yaşlandırma SQL Sorgusu — FIFO Bakiye Dağıtımı](/blog/mikro-erp-cari-yaslandirma-sql-sorgusu/)
- [FIFO Fatura-Tahsilat Eşleştirme Algoritması](/blog/mikro-erp-fifo-fatura-tahsilat-eslestirme-sql/)
- [Çek ve Senet Gerçek Tahsilat Tarihi](/blog/mikro-erp-cek-senet-gercek-tahsilat-tarihi-sql/)
- [fn_CariRiskFoyu Analizi](/blog/mikro-erp-cari-risk-raporu-fn-caririsklfoyu-analizi/)

---

*Bu yazı [AstaFlow Case Study](/case-study) serisinin bir parçasıdır — cari derecelendirme skoru, yaşlandırma ve tahsilat modüllerinden elde edilen verileri tek bir karar destek metriğinde birleştirir.*