Erp Asistanı Erp Asistanı
Netsis SQL

Netsis Ortalama Tahsilat Süresi SQL: TBLCAHAR ile DSO Analizi

Netsis TBLCAHAR tablosu ile ortalama tahsilat süresi (DSO) ve tahsilat hızı hesaplama rehberi. Borç alacak yönü, devir mantığı ve hazır SQL sorguları.

Erp Asistanı Erp Asistanı Editör ekibi 5 dk okuma
Netsis Ortalama Tahsilat Süresi SQL: TBLCAHAR ile DSO Analizi

Netsis ERP kullanan işletmelerde nakit akışını ve işletme sermayesini doğru yönetebilmenin en temel göstergesi alacakların ortalama tahsilat süresidir (DSO - Days Sales Outstanding). Netsis veri tabanında tüm cari finansal hareketler TBLCAHAR tablosunda tutulur. Ancak tahsilat hızını SQL ile hesaplarken en çok karşılaşılan sorun, cari hareketlerin borç ve alacak yönünün karıştırılması, devir kayıtlarının ciroya dahil edilmesi ve açık faturaların doğru filtrelenememesidir. Cari hareket mantığının temelleri için Netsis cari ekstre ve bakiye rehberine ve genel mimari için Netsis tablo yapısı rehberine göz atabilirsiniz.

Bu rehberde TBLCAHAR tablosu üzerinden borç/alacak dinamiklerini netleştirip, hem klasik DSO formülünü hem de ilk hareket ve devir bazlı alternatif tahsilat süresi hesaplamalarını çalışır SQL sorgularıyla ele alıyoruz.

TBLCAHAR tablosunda borç, alacak ve hareket türleri

Netsis'te müşteri carisine kesilen her satış faturası cariyi borçlandırır (BORC sütununa yazılır). Müşteriden yapılan nakit, banka, çek veya senet tahsilatları ise cariyi alacaklandırır (ALACAK sütununa yazılır). Müşteri bakiyesi formülü her zaman SUM(BORC) - SUM(ALACAK) şeklindedir.

TBLCAHAR tablosundaki HAREKET_TURU sütunu evrakın niteliğini belirler. DSO hesaplarken ciro toplamına yalnızca gerçek satış faturalarını (HAREKET_TURU = 'B') dahil etmeli, açılış devirlerini ('A') ve dekont düzeltmelerini ayırt etmelisiniz.

HAREKET_TURU Belge Türü Cari Etkisi DSO / Ciro Hesabındaki Rolü
A Devir Borç veya Alacak Ciroya katılmaz; devir bakiyesine eklenir
B Fatura (Satış) Borç (Müşteri için) Dönem kredili satış cirosunu oluşturur
C İade Faturası Alacak Net ciro için düşülür
D Kasa Tahsilatı Alacak Tahsilat tutarıdır
E Müşteri Senedi Alacak Tahsilat / kıymetli evrak girişi
G Müşteri Çeki Alacak Tahsilat / kıymetli evrak girişi
K Dekont Borç / Alacak Virman veya düzeltme işlemidir

1. Müşteri bazında klasik DSO (Days Sales Outstanding) hesabı

Klasik DSO formülü, belirlenen dönem sonundaki açık bakiyenin o dönemin net satış tutarına oranlanıp gün sayısıyla çarpılmasıyla elde edilir:

DSO = (Dönem Sonu Açık Bakiye / Dönem Net Satış Cirosu) * Dönem Gün Sayısı

Aşağıdaki sorgu, seçilen tarih aralığında satış yapan müşterilerin dönem cirosunu, tahsilatlarını ve dönem sonu bakiyesini hesaplayarak DSO gününü çıkarır:

-- 1. Cari bazında klasik DSO analizi (Dönem Sonu Bakiye / Satış Cirosu * Gün Sayısı)
DECLARE @BasTarih DATETIME = '2026-01-01';
DECLARE @BitTarih DATETIME = '2026-03-31';
DECLARE @GunSayisi INT = DATEDIFF(DAY, @BasTarih, @BitTarih) + 1;

SELECT
    c.CARI_KOD,
    c.CARI_ISIM,
    SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END) AS [Donem_Fatura_Borc],
    SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU IN ('D','E','G','K') THEN h.ALACAK ELSE 0 END) AS [Donem_Tahsilat_Alacak],
    SUM(CASE WHEN h.TARIH <= @BitTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) AS [Kapanis_Bakiyesi],
    CASE
        WHEN SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END) > 0
        THEN CAST((SUM(CASE WHEN h.TARIH <= @BitTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) /
                   SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END)) * @GunSayisi AS DECIMAL(10,2))
        ELSE 0
    END AS [DSO_Gun]
FROM TBLCASABIT c
JOIN TBLCAHAR h ON h.CARI_KOD = c.CARI_KOD
WHERE c.CARI_TIP IN ('A','T')
  AND h.SUBE_KODU = 0
GROUP BY c.CARI_KOD, c.CARI_ISIM
HAVING SUM(CASE WHEN h.TARIH <= @BitTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) > 0
ORDER BY [Kapanis_Bakiyesi] DESC;

2. Devir bakiyeli ve dönem içi tahsilat karşılama oranı

Önceki yıldan devreden yüksek bir borç bakiyesi varsa, cari dönemdeki tahsilatların yalnızca o dönemin faturalarını mı yoksa devri mi kapattığını ayırt etmek gerekir. Bu sorguda dönem başı devir bakiyesi ile dönem içi yeni faturalar ayrı toplanır ve tahsilatın toplam yükümlülüğü karşılama oranı ölçülür:

-- 2. Devirli ve devirsiz satış/tahsilat karşılama oranı
DECLARE @BasTarih DATETIME = '2026-01-01';
DECLARE @BitTarih DATETIME = '2026-03-31';

SELECT
    c.CARI_KOD,
    c.CARI_ISIM,
    -- Devir Bakiyesi (Dönem başından önceki kümülatif bakiye)
    SUM(CASE WHEN h.TARIH < @BasTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) AS [Devir_Bakiyesi],
    -- Dönem Fatura Satışları
    SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END) AS [Donem_Satisi],
    -- Dönem Tahsilatları
    SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU <> 'B' THEN h.ALACAK ELSE 0 END) AS [Donem_Tahsilati],
    -- Güncel Toplam Bakiye
    SUM(h.BORC - h.ALACAK) AS [Guncel_Bakiye],
    -- Tahsilat Karşılama Oranı Yüzdesi
    CASE
        WHEN (SUM(CASE WHEN h.TARIH < @BasTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) +
              SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END)) > 0
        THEN CAST((SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU <> 'B' THEN h.ALACAK ELSE 0 END) /
              (SUM(CASE WHEN h.TARIH < @BasTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) +
               SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END))) * 100 AS DECIMAL(5,2))
        ELSE 0
    END AS [Tahsilat_Karsilama_Yuzdesi]
FROM TBLCASABIT c
JOIN TBLCAHAR h ON h.CARI_KOD = c.CARI_KOD
WHERE h.SUBE_KODU = 0
  AND h.TARIH <= @BitTarih
GROUP BY c.CARI_KOD, c.CARI_ISIM
HAVING SUM(h.BORC - h.ALACAK) <> 0
ORDER BY [Guncel_Bakiye] DESC;

3. İlk hareket ve son tahsilat tarihi bazlı tahsilat döngüsü süresi

Devir yaklaşımının aksine, bir müşterinin ilk faturalandığı tarih ile gerçekleştirdiği son tahsilat tarihi arasındaki takvim günü farkını ölçmek, müşterinin ne kadar süredir borçlu kaldığını gösterir:

-- 3. İlk fatura tarihinden itibaren tahsilat döngüsü ve gün süresi
SELECT
    c.CARI_KOD,
    c.CARI_ISIM,
    MIN(CASE WHEN h.HAREKET_TURU = 'B' THEN h.TARIH END) AS [Ilk_Fatura_Tarihi],
    MAX(CASE WHEN h.HAREKET_TURU IN ('D','E','G','K') THEN h.TARIH END) AS [Son_Tahsilat_Tarihi],
    DATEDIFF(DAY,
        MIN(CASE WHEN h.HAREKET_TURU = 'B' THEN h.TARIH END),
        ISNULL(MAX(CASE WHEN h.HAREKET_TURU IN ('D','E','G','K') THEN h.TARIH END), GETDATE())
    ) AS [Tahsilat_Dongu_Gunu],
    SUM(h.BORC) AS [Toplam_Borc],
    SUM(h.ALACAK) AS [Toplam_Alacak],
    SUM(h.BORC - h.ALACAK) AS [Acik_Bakiye]
FROM TBLCASABIT c
JOIN TBLCAHAR h ON h.CARI_KOD = c.CARI_KOD
WHERE h.SUBE_KODU = 0
  AND c.CARI_TIP IN ('A','T')
GROUP BY c.CARI_KOD, c.CARI_ISIM
HAVING SUM(h.BORC) > 0
ORDER BY [Acik_Bakiye] DESC;

4. Vade tarihi geçmiş açık faturaların gecikme gün analizi

TBLCAHAR tablosundaki VADE_TARIHI ve KAPATILMIS_TUTAR alanları yardımıyla, ödemesi vadesini geçmiş açık faturaların kaç gündür tahsil edilmediği listelenebilir:

-- 4. Vadesi geçen açık faturalar ve gecikme süresi
SELECT
    h.CARI_KOD,
    c.CARI_ISIM,
    h.BELGE_NO,
    h.TARIH AS [Fatura_Tarihi],
    h.VADE_TARIHI AS [Fatura_Vadesi],
    h.BORC AS [Fatura_Tutari],
    DATEDIFF(DAY, h.TARIH, h.VADE_TARIHI) AS [Taninan_Vade_Gunu],
    DATEDIFF(DAY, h.VADE_TARIHI, GETDATE()) AS [Gecikme_Gunu]
FROM TBLCAHAR h
JOIN TBLCASABIT c ON c.CARI_KOD = h.CARI_KOD
WHERE h.HAREKET_TURU = 'B'
  AND h.BORC > 0
  AND h.SUBE_KODU = 0
  AND h.VADE_TARIHI IS NOT NULL
  AND h.VADE_TARIHI < GETDATE()
  AND (h.BORC - ISNULL(h.KAPATILMIS_TUTAR, 0)) > 0
ORDER BY [Gecikme_Gunu] DESC;

5. Plasiyer bazında ortalama DSO ve tahsilat performansı

Satış ekibinin tahsilat başarısını ölçmek için PLASIYER_KODU kırılımında DSO hesaplanabilir. Benzer rapor şablonları için Netsis hazır SQL sorguları listesini de inceleyebilirsiniz.

-- 5. Plasiyer bazında ortalama DSO ve bakiye dağılımı
DECLARE @BasTarih DATETIME = '2026-01-01';
DECLARE @BitTarih DATETIME = '2026-03-31';
DECLARE @GunSayisi INT = DATEDIFF(DAY, @BasTarih, @BitTarih) + 1;

SELECT
    ISNULL(h.PLASIYER_KODU, 'TANIMSIZ') AS [Plasiyer_Kodu],
    COUNT(DISTINCT h.CARI_KOD) AS [Musteri_Sayisi],
    SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END) AS [Toplam_Satis],
    SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU <> 'B' THEN h.ALACAK ELSE 0 END) AS [Toplam_Tahsilat],
    SUM(CASE WHEN h.TARIH <= @BitTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) AS [Toplam_Acik_Bakiye],
    CASE
        WHEN SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END) > 0
        THEN CAST((SUM(CASE WHEN h.TARIH <= @BitTarih THEN (h.BORC - h.ALACAK) ELSE 0 END) /
                   SUM(CASE WHEN h.TARIH BETWEEN @BasTarih AND @BitTarih AND h.HAREKET_TURU = 'B' THEN h.BORC ELSE 0 END)) * @GunSayisi AS DECIMAL(10,1))
        ELSE 0
    END AS [Plasiyer_Ortalama_DSO]
FROM TBLCAHAR h
WHERE h.SUBE_KODU = 0
GROUP BY h.PLASIYER_KODU
ORDER BY [Toplam_Satis] DESC;

Sık yapılan hatalar

  • SUBE_KODU filtresini atlamak: Çok şubeli veritabanlarında SUBE_KODU şartı eklenmediğinde birden fazla şubenin fatura ve tahsilatları birbirine karışır.
  • Borç ve alacak yönünü ters almak: Müşteri satış faturası her zaman BORC sütunundadır. Müşteriden gelen nakit veya çek tahsilatı ise ALACAK sütununa yazılır. İşaret hatası DSO'yu negatif veya anlamsız çıkarır.
  • Devir hareketini ciro saymak: HAREKET_TURU = 'A' olan devir kayıtları o dönemin satışı değildir. DSO paydasındaki satış cirosuna sadece 'B' (fatura) hareketleri dahil edilmelidir.
  • Dövizli carilerde yerel tutarı kontrol etmemek: BORC ve ALACAK sütunları yerel para birimindedir. Dövizli işlem yapılıyorsa DOVIZ_TURU ve DOVIZ_TUTAR sütunları dikkate alınmalıdır.
  • Sıfır cirolu müşterilerde sıfıra bölme hatası: Satış yapılmamış ancak devirden bakiyesi olan müşterilerde DSO formülünün paydası 0 olacağı için CASE WHEN kontrolüyle bölme işlemi korunmalıdır.

Sık sorulanlar

DSO süresinin yüksek çıkması ne anlama gelir? DSO gün sayısının yüksek olması, şirketin kestiği faturaların bedelini geç tahsil ettiğini veya alacakların tahsil edilemeyip biriktiğini gösterir. Bu durum işletme sermayesi ihtiyacını artırır.

Devir bazlı hesaplama ile ilk hareket bazlı hesaplama arasındaki temel fark nedir? Devir bazlı hesaplama, geçmiş yıllardan aktarılan toplam bakiye yükünü dönemsel ciroya oranlar. İlk hareket bazlı hesaplama ise müşterinin ilk faturalandığı günden son ödemesine kadar geçen takvimsel döngü süresini ölçer.

Netsis'te kapalı faturalar DSO hesabını etkiler mi? HKA = 'K' (kapalı fatura) olarak kesilen faturalarda tahsilat anında gerçekleşmiştir; ancak TBLCAHAR üzerinde hem borç hem alacak satırı oluşur. Net bakiye sıfırlandığı için DSO formülünde payı artırmaz, sağlıklı sonucu korur.


Netsis veritabanınızda ortalama tahsilat süresi, cari yaşlandırma ve plasiyer performans raporlarını manuel sorgularla uğraşmadan anlık olarak almak için Erp Asistanı'nı kullanabilirsiniz.

Ücretsiz üye olun, istediğiniz sorguyu doğal dille alın →

Bu yazıyı paylaş
Konuşarak raporlayın

Netsis'te SQL ve raporu konuşarak alın

Türkçe sorunuzu yazın, şemanıza uygun çalışan SQL'i ya da hazır uygulamanızı saniyeler içinde alın. Kredi kartı gerekmez.