Mikro Cari Yaşlandırma Raporu SQL: Vade Analizi Sorgusu
Nakit akışını doğru yönetmek, vadesi geçmiş alacakların sıkı takibinden geçer. Mikro ERP kullanan işletmelerde finans yöneticilerinin en çok ihtiyaç duyduğu raporların başında cari yaşlandırma gelir. Ancak Mikro'da standart raporların dışına çıkıp SQL Server Management Studio (SSMS) üzerinde özel bir rapor tasarlamak istediğinizde, vade hesaplama mantığındaki bazı teknik tuzaklarla karşılaşırsınız. Bu rehberde, Mikro veritabanı yapısına uygun, 30, 60, 90 gün ve üzeri vadeleri analiz eden, doğrudan kopyalayıp çalıştırabileceğiniz SQL sorgularını paylaşıyoruz.
Mikro'da cari hareketlerin parasal bacağı CARI_HESAP_HAREKETLERI tablosunda tutulur. Bu tablodaki vade yapısını ve borç/alacak mantığını doğru analiz etmek, hatalı rapor almanın önüne geçecektir. Benzer bakiye hesaplama mantığı için Mikro cari ekstre ve bakiye raporu yazımıza da göz atabilirsiniz.
Mikro'da Vade ve Yaşlandırma Mantığı
Mikro ERP veritabanında en sık yapılan hata, vade kolonunun bir tarih değeri taşıdığını varsaymaktır. CARI_HESAP_HAREKETLERI tablosundaki cha_vade kolonu bir tarih değil, vade gün sayısını ifade eden bir int (tamsayı) değerdir. Örneğin, peşin işlemlerde bu alan 0 değerini alır. 30 gün vadeli bir faturada ise 30 yazar.
Gerçek vade tarihini bulmak için hareket tarihi olan cha_tarihi alanına bu gün sayısını eklememiz gerekir. SQL Server üzerinde bu işlemi DATEADD fonksiyonu ile gerçekleştiririz:
- Vade Tarihi Hesaplama:
DATEADD(DAY, cha_vade, cha_tarihi) - Gecikme Gün Sayısı (Yaş):
DATEDIFF(DAY, Vade_Tarihi, GETDATE())
Bu matematiksel formülleri SQL sorgularımızda CASE WHEN koşulları ile birleştirerek yaşlandırma kovalarını (0-30, 31-60, 61-90, 90+) oluşturacağız.
| İşlem | SQL Karşılığı | Açıklama |
|---|---|---|
| Vade Tarihi | DATEADD(DAY, cha_vade, cha_tarihi) |
Fatura tarihine vade gününü ekler |
| Gecikme Gün (Yaş) | DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) |
Bugün ile vade tarihi arasındaki gün farkı |
| Net Tutar (Yönlü) | CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END |
Borç hareketlerini artı, alacakları eksi sayar |
| İptal Filtresi | cha_iptal = 0 |
İptal edilmiş kayıtları eler |
1. Cari Hareket Bazında Vade ve Gecikme Detayı
İlk sorgumuz, cari hareketleri tek tek listeleyerek her bir hareketin vade tarihini ve bugün itibarıyla kaç gün geciktiğini (veya vadesine kaç gün kaldığını) gösterir. Bu sorgu, yaşlandırma mantığının arka planda nasıl çalıştığını anlamak için temel oluşturur.
SELECT
cha_kod,
cha_tarihi,
cha_vade AS [Vade Gün],
DATEADD(DAY, cha_vade, cha_tarihi) AS [Vade Tarihi],
DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) AS [Gecikme Gün],
CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END AS [Net Tutar]
FROM CARI_HESAP_HAREKETLERI
WHERE cha_iptal = 0
ORDER BY cha_tarihi DESC;
2. Cari Hareket Bazında 30/60/90 Gün Kovaları
Bu sorguda, her bir cari hareketin tutarını gecikme gün sayısına göre ilgili vade dilimine (kovasına) dağıtıyoruz. Vadesi henüz gelmemiş olan tutarlar ise ayrı bir kolonda listelenir.
SELECT
cha_kod,
cha_tarihi,
DATEADD(DAY, cha_vade, cha_tarihi) AS [Vade Tarihi],
CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END AS [Bakiye],
-- Vadesi Gelmemiş
CASE WHEN DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) <= 0
THEN CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END ELSE 0 END AS [Vadesi Gelmemiş],
-- 1 - 30 Gün Gecikenler
CASE WHEN DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) BETWEEN 1 AND 30
THEN CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END ELSE 0 END AS [1-30 Gün],
-- 31 - 60 Gün Gecikenler
CASE WHEN DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) BETWEEN 31 AND 60
THEN CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END ELSE 0 END AS [31-60 Gün],
-- 61 - 90 Gün Gecikenler
CASE WHEN DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) BETWEEN 61 AND 90
THEN CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END ELSE 0 END AS [61-90 Gün],
-- 90 Günden Fazla Gecikenler
CASE WHEN DATEDIFF(DAY, DATEADD(DAY, cha_vade, cha_tarihi), GETDATE()) > 90
THEN CASE WHEN cha_tip = 0 THEN cha_meblag ELSE -cha_meblag END ELSE 0 END AS [90+ Gün]
FROM CARI_HESAP_HAREKETLERI
WHERE cha_iptal = 0;
3. Cari Bazında Özet Yaşlandırma Raporu (Müşteri Listesi)
Yönetim raporlamalarında hareket detayından ziyade müşteri bazında toplam risk ve gecikme dağılımı istenir. Aşağıdaki sorgu, CARI_HESAPLAR tablosu ile join kurarak aktif olan tüm müşterilerin toplam bakiyelerini ve bu bakiyelerin vade dilimlerine göre dağılımını özetler.
SELECT
c.cari_kod AS [Cari Kod],
LTRIM(RTRIM(c.cari_unvan1 + ' ' + ISNULL(c.cari_unvan2, ''))) AS [Cari Ünvan],
SUM(CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END) AS [Toplam Bakiye],
-- Vade Dağılımları
SUM(CASE WHEN (DATEDIFF(DAY, ch.cha_tarihi, GETDATE()) - ch.cha_vade) <= 0
THEN CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END ELSE 0 END) AS [Vadesi Gelmemiş],
SUM(CASE WHEN (DATEDIFF(DAY, ch.cha_tarihi, GETDATE()) - ch.cha_vade) BETWEEN 1 AND 30
THEN CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END ELSE 0 END) AS [1-30 Gün],
SUM(CASE WHEN (DATEDIFF(DAY, ch.cha_tarihi, GETDATE()) - ch.cha_vade) BETWEEN 31 AND 60
THEN CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END ELSE 0 END) AS [31-60 Gün],
SUM(CASE WHEN (DATEDIFF(DAY, ch.cha_tarihi, GETDATE()) - ch.cha_vade) BETWEEN 61 AND 90
THEN CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END ELSE 0 END) AS [61-90 Gün],
SUM(CASE WHEN (DATEDIFF(DAY, ch.cha_tarihi, GETDATE()) - ch.cha_vade) > 90
THEN CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END ELSE 0 END) AS [90+ Gün]
FROM CARI_HESAP_HAREKETLERI ch
JOIN CARI_HESAPLAR c ON c.cari_kod = ch.cha_kod
WHERE ch.cha_iptal = 0
AND c.cari_iptal = 0
AND c.cari_hidden = 0
GROUP BY c.cari_kod, c.cari_unvan1, c.cari_unvan2
HAVING SUM(CASE WHEN ch.cha_tip = 0 THEN ch.cha_meblag ELSE -ch.cha_meblag END) <> 0
ORDER BY [Toplam Bakiye] DESC;
Açık Hesap (Açık Kalem) Eşlemesi ve fn_CariFoy Notu
Yakından incelediğinizde yukarıdaki sorguların "ham hareket bazlı" çalıştığını fark edeceksiniz. Yani bir müşterinin 120 gün öncesinden kalan bir borç faturası varsa ve müşteri dün bir ödeme yaptıysa, bu ödeme (alacak hareketi) vadesi gelmemiş kısma eksi bakiye olarak yazılabilir.
Gerçek bir "Açık Hesap Yaşlandırma" raporu, yapılan ödemelerin hangi faturaları kapattığını bilmek zorundadır (Matching / Eşleme). Mikro içerisindeki kapama kayıtlarını ve karmaşık döviz/vade mantıklarını çözmek için SQL'de sıfırdan eşleme algoritması yazmak yerine, Mikro'nun kendi yazdığı hazır fonksiyonları kullanmak çok daha sağlıklıdır.
Özellikle fn_CariFoy fonksiyonu, cari hareketleri bakiye ve vade kapamaları yapılmış şekilde analiz etmenize olanak tanır. Bu fonksiyonların kullanımı hakkında detaylı bilgi edinmek için Mikro fonksiyonları ve şifreli kolonlar rehberimizi inceleyebilirsiniz.
Sık yapılan hatalar
- cha_vade alanını tarih sanmak:
cha_vadealanını doğrudanGETDATE()ile karşılaştırmaya çalışmak SQL Server'da8115aritmetik taşma hatasına yol açar. Bu alan sadece gün sayısıdır. - İptal kayıtlarını filtrelememek: Sorgu kriterlerine
cha_iptal = 0eklenmediğinde, silinmiş veya iptal edilmiş faturalar da yaşlandırma tutarlarına dahil olur ve raporu bozar. - Döviz farklarını atlamak:
cha_meblagalanı hareketin orijinal döviz cinsindendir. Eğer çoklu döviz kullanıyorsanız, tutarlarıcha_d_kurile çarparak TL'ye çevirmeli veya döviz cinsine göre filtrelemelisiniz. - İadeleri hesaba katmamak: Satış faturalarının iadeleri
cha_normal_Iade = 1olarak işaretlenir. Bu kayıtların bakiye yönünü doğru yönetmek gerekir.
Sık sorulanlar
Soru? cha_vade değeri sıfır olan kayıtlar ne anlama gelir?
Cevap: Vade değeri 0 olan kayıtlar peşin işlemlerdir. Bu durumda vade tarihi, hareketin gerçekleştiği cha_tarihi gününe eşit olur.
Soru? Bu sorgu ödemeleri faturalarla otomatik eşleştirir mi?
Cevap: Hayır, bu sorgu ham hareket yaşlandırmasıdır. Alacak hareketleri (ödemeler) toplam bakiyeyi düşürür ancak spesifik bir faturayı kapatmaz. Kesin açık hesap yaşlandırması için Mikro'nun kapama tabloları veya fn_CariFoy fonksiyonu kullanılmalıdır.
Soru? Sadece belirli bir şubenin yaşlandırma raporunu nasıl alabilirim?
Cevap: Sorgunun WHERE koşuluna AND cha_subeno = @sube_kodu filtresini ekleyerek şube bazlı kırılım elde edebilirsiniz.
Cari yaşlandırma ve vade analizi, nakit akışınızı korumanın en kritik adımıdır. Mikro veritabanınızda daha ileri düzey analizler yapmak, plasiyer bazlı gecikme raporları hazırlamak veya bu verileri otomatik olarak Excel'e aktarmak istiyorsanız Erp Asistanı'nı kullanabilirsiniz. Erp Asistanı'na ücretsiz üye olun, rapor isteklerinizi Türkçe yazın, SQL bilginiz olmasa bile saniyeler içinde çalışan sorgulara ulaşın.
Mikro'da 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.