Mikro ERP Cari Ekstre Raporu SQL Sorgusu: Borç, Alacak ve Bakiye Takibi

Mikro ERP'de cari hesap ekstre raporu SQL ile nasıl alınır? CARI_HESAP_HAREKETLERI tablosundan borç/alacak listesi, running total ile bakiye hesaplama...

Sorun: “Bu Carinin Ekstresi Neden Tutmuyor?”

Muhasebe departmanı soruyor: “120.ABC müşterisinin ekstresi neden uymuyor?” Mikro’dan aldığınız ekstre ile SQL’den çektiğiniz bakiye farklı çıkıyor. Üstelik hangi fatura ödendi, hangisi açık kaldı belli değil.

Bu genellikle şu sebeplerden kaynaklanır:

  • cha_tip (borç/alacak) alanı yanlış filtreleniyor
  • İptal kayıtlar (cha_iptal = 1) dahil ediliyor
  • Vade bilgisi ile tarih bilgisi karıştırılıyor
  • cha_meblag yerine yanlış tutar alanı kullanılıyor

Hangi Tablo, Hangi Alan?

Cari ekstre için tek tablo yeterli: CARI_HESAP_HAREKETLERI (Tablo No: 51)

AlanAçıklamaKullanım
cha_kodCari koduWHERE filtresi
cha_tarihiHareket tarihiSıralama ve dönem filtresi
cha_tip0=Borç, 1=AlacakBakiye hesabı
cha_meblagHareket tutarı (ana döviz)Ekstre meblağı
cha_evrak_tipEvrak tipi (0=Alış Faturası, 63=Satış Faturası vb.)Satır açıklaması
cha_evrakno_seri / cha_evrakno_siraEvrak seri ve sıra noFatura numarası
cha_belge_noBelge numarasıFatura/fiş numarası
cha_aciklamaAçıklamaSatır detayı
cha_vadeVade tarihiVade analizi
cha_iptalİptal flagİptal kayıtları hariç tutma

Kaynak: CARI_HESAP_HAREKETLERI alan yapısı

Yanlış Yaklaşım

İnternetteki birçok örnekte şunu görürsünüz:

-- ❌ YANLIŞ: Bakiye hesabı yok, iptal kayıtlar dahil
SELECT cha_tarihi, cha_meblag 
FROM CARI_HESAP_HAREKETLERI 
WHERE cha_kod = '120.001'

Bu sorgu size sadece bir sayı listesi verir. Hangi satırda bakiye ne oldu, borç mu alacak mı, iptal mi — hiçbiri belli değildir.

Doğru Yaklaşım: Running Total ile Ekstre

SELECT 
    ROW_NUMBER() OVER (ORDER BY cha_tarihi, cha_evrakno_sira) AS [Sira],
    CONVERT(VARCHAR(10), cha_tarihi, 104)     AS [Tarih],
    CASE cha_evrak_tip
        WHEN 0  THEN 'Alis Faturasi'
        WHEN 63 THEN 'Satis Faturasi'
        WHEN 1  THEN 'Tahsilat'
        WHEN 64 THEN 'Tediye'
        WHEN 29 THEN 'Acilis Fisi'
        WHEN 31 THEN 'Borc Dekontu'
        WHEN 32 THEN 'Alacak Dekontu'
        ELSE 'Tip: ' + CAST(cha_evrak_tip AS VARCHAR)
    END                                        AS [Evrak Tipi],
    cha_evrakno_seri + '-' + 
        CAST(cha_evrakno_sira AS VARCHAR)       AS [Evrak No],
    cha_belge_no                                AS [Belge No],
    cha_aciklama                                AS [Aciklama],
    CASE WHEN cha_tip = 0 
         THEN cha_meblag ELSE 0 END            AS [Borc],
    CASE WHEN cha_tip = 1 
         THEN cha_meblag ELSE 0 END            AS [Alacak],
    SUM(CASE WHEN cha_tip = 0 THEN cha_meblag 
             ELSE -cha_meblag END) 
        OVER (ORDER BY cha_tarihi, cha_evrakno_sira 
              ROWS UNBOUNDED PRECEDING)         AS [Bakiye]
FROM CARI_HESAP_HAREKETLERI WITH (NOLOCK)
WHERE cha_kod = '120.001'                       -- Cari kodu (isletmenize gore degistirin)
  AND cha_iptal = 0                             -- Iptal kayitlari haric
  AND cha_tarihi >= CONVERT(datetime, '20260101', 112)   -- Donem basi
  AND cha_tarihi <= CONVERT(datetime, '20261231', 112)   -- Donem sonu
ORDER BY cha_tarihi, cha_evrakno_sira;

Çıktı:

Sıra │ Tarih      │ Evrak Tipi      │ Evrak No │ Borç      │ Alacak   │ Bakiye
─────┼────────────┼─────────────────┼──────────┼───────────┼──────────┼──────────
1    │ 02.01.2026 │ Açılış Fişi     │ A-1      │ 15.000,00 │     0,00 │ 15.000,00
2    │ 15.01.2026 │ Satış Faturası  │ B-4521   │ 8.500,00  │     0,00 │ 23.500,00
3    │ 20.01.2026 │ Tahsilat        │ C-102    │      0,00 │ 10.000,00│ 13.500,00
4    │ 03.02.2026 │ Satış Faturası  │ B-4580   │ 12.000,00 │     0,00 │ 25.500,00

Bakiye nasil hesaplaniyor? SUM() OVER (ROWS UNBOUNDED PRECEDING) ile her satirda onceki tum satirlarin toplamini alir. Borc (+), alacak (-) olarak islenir. Bu SQL Server’in Window Function ozelligidir.

Tüm Carilerin Bakiye Listesi (Özet)

Tek bir carinin ekstresi yerine, tüm carilerin güncel bakiyesini görmek için:

SELECT 
    C.cari_kod                                    AS [Cari Kodu],
    C.cari_unvan1                                 AS [Ünvan],
    SUM(CASE WHEN H.cha_tip = 0 THEN H.cha_meblag ELSE 0 END) AS [Toplam Borç],
    SUM(CASE WHEN H.cha_tip = 1 THEN H.cha_meblag ELSE 0 END) AS [Toplam Alacak],
    SUM(CASE WHEN H.cha_tip = 0 THEN H.cha_meblag 
             ELSE -H.cha_meblag END)              AS [Bakiye]
FROM CARI_HESAPLAR C WITH (NOLOCK)
INNER JOIN CARI_HESAP_HAREKETLERI H WITH (NOLOCK) 
    ON C.cari_kod = H.cha_kod
WHERE H.cha_iptal = 0
  AND H.cha_tarihi <= GETDATE()
GROUP BY C.cari_kod, C.cari_unvan1
HAVING SUM(CASE WHEN H.cha_tip = 0 THEN H.cha_meblag ELSE -H.cha_meblag END) <> 0
ORDER BY [Bakiye] DESC;

Sadece bakiyesi 0 olmayan carileri getirir. Borçlu müşteriler en üstte görünür.

Dikkat Edilecekler

Firma ve Şube Filtresi

Çok şubeli yapıda cha_firmano ve cha_subeno filtresi eklemeyi unutmayın:

AND cha_firmano = 0
AND cha_subeno = 0

Evrak Tip Kodları

cha_evrak_tip alanı 130+ farklı değer alabilir. En sık kullanılanlar:

KodEvrak Tipi
0Alış Faturası
63Satış Faturası
1Tahsilat Makbuzu
64Tediye Makbuzu
29Açılış Fişi
31Borç Dekontu
32Alacak Dekontu
4Çek Giriş Bordrosu
67Çek Çıkış Bordrosu

Performans

Büyük veritabanlarında CARI_HESAP_HAREKETLERI tablosu milyonlarca satır içerebilir. Mutlaka:

  • WITH (NOLOCK) kullanın
  • Tarih filtresi ekleyin
  • Sadece ihtiyaç duyduğunuz alanları SELECT edin

İlgili Yazılar


Bu rehber Mikro ERP API Docs tablo yapısına dayanarak hazırlanmıştır.

📚 İlgili Yazılar