Mikro ERP 046355 Cari Risk Raporunu SQL ile Yeniden Üretmek: fn_CariRiskFoyu Analizi
Mikro ERP 046355 Detaylı Cari Bakiye-Ciro-Risk-Teminat raporunu SQL ile nasıl çözdük? fn_CariRiskFoyu fonksiyonu, ciro hesabının gerçek kaynağı, KDV tuzağı, çek/senet risk süresi ve performans optimizasyonu.
İş Problemi: Mikro’nun Hazır Raporu Var — Neden SQL ile Uğraşıyoruz?
Mikro ERP içinde şu rapor zaten mevcut:
(K) Detaylı Cari Hesap Bakiye-Ciro-Risk-Teminat Karşılaştırma Raporu (046355)
Mikro menüsünde 046355 numarasıyla bulunan bu rapor (benzer işlevi gören 046356 numaralı rapordan daha detaylı parametrelere sahiptir), tek ekranda cari kodu, toplam ciro, kredi toplamı, açık sipariş, faturalaşmamış irsaliye, açık hesap, kredi limiti, çek/senet detayı, ödenmeyen toplam ve toplam riski gösteriyor. Hızlı özet için 041000 Cari Hesap Risk Föyü de kullanılabilir ama 046355 çok daha kapsamlıdır.
Ama sorunlar var:
- Çok yavaş. 1600+ cari için Mikro’nun orijinal raporu 45 dakikanın üzerinde sürüyor.
- Kapalı kutu. Hangi tablolardan ne çektiğini göremiyorsunuz.
- Dışarı taşıyamıyorsunuz. Sonuçları web dashboard’a, Excel otomasyonuna veya özel uyarı sistemine aktarmak istediğinizde Mikro’nun arayüzüne bağımlı kalıyorsunuz.
Bu yazıda o raporu SQL tarafında birebir yeniden üretme sürecimizi anlatıyoruz. Üstelik optimize ettiğimiz SQL versiyonu aynı sonucu ~15 dakikada üretiyor — Mikro’nun orijinalinden 3 kat daha hızlı. Yanlış varsayımları, çıkmaz sokakları ve sonunda çalışan çözümü paylaşıyoruz.
Hedef: Raporun Ürettiği Kolonları SQL ile Eşleştirmek
Rapor çıktısındaki kolonlar:
| Kolon | Açıklama |
|---|---|
| Cari hesap kodu | Cari kart kodu |
| Cari hesap adı | Unvan |
| Temsilci kodu | Cari temsilcisi |
| Toplam ciro | Belirli tarih aralığında net satış cirosu |
| Kredi toplamı | Cariye tanımlı kredi limiti |
| Açık sipariş | Henüz teslim edilmemiş sipariş tutarı |
| Faturalaşmamış irsaliye | Sevk edilmiş ama faturası kesilmemiş mal |
| Açık hesap | Mevcut borç/alacak bakiyesi |
| Kredi limiti | Kullanılan kredi − toplam kredi |
| Kendi çeki / Müşterisinin çeki | Çek pozisyonları |
| Kendi senedi / Müşterisinin senedi | Senet pozisyonları |
| Ödenmeyen toplam | Tüm çek + senet toplamı |
| Toplam risk | Açık hesap + açık sipariş + irsaliye + çek/senet |
Doğrulama için tek bir cari seçtik ve Mikro raporundaki değerlerle SQL sonucumuzu satır satır karşılaştırdık.
İlk Adım: Mikro Ne Çalıştırıyor?
Rapor Mikro arayüzünde çalışırken SQL Server üzerindeki aktif session’ları izledik:
SELECT
r.session_id,
s.login_name,
s.host_name,
r.status,
r.total_elapsed_time / 1000 AS elapsed_seconds,
r.cpu_time,
LEFT(t.text, 4000) AS running_sql
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s
ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE s.program_name LIKE '%ABORON%' -- Mikro ERP istemci adı
AND r.session_id <> @@SPID
ORDER BY r.total_elapsed_time DESC;
Bu şekilde Mikro’nun arka planda hangi fonksiyonu çağırdığını yakaladık: dbo.fn_CariRiskFoyu.
fn_CariRiskFoyu: Risk Tarafının Kalbi
Fonksiyonun tanımını sp_helptext ile çektik. İçeride ciddi bir yapı var:
Hesapladığı bileşenler:
- Açık hesap bakiyesi
- Açık sipariş tutarı
- Faturalaşmamış irsaliye
- Kendi çeki / Müşterisinin çeki
- Kendi senedi / Müşterisinin senedi
- Kredi limiti / Kullanılan kredi
- Cari teminatlar
Kullandığı tablolar:
CARI_HESAPLAR, CARI_HESAP_TEMINATLARI, SIPARISLER,
STOK_HAREKETLERI, KONSINYE_HAREKETLERI, ODEME_EMIRLERI, FIRMALAR
İçeride çağırdığı diğer fonksiyonlar:
fn_CariHesapOrjinalDovizBakiye, fn_CariHesapAnaDovizBakiye,
fn_KurBul, fn_Evrak_Kalan_Miktar, fn_StokSatisFiyati,
fn_DinamikRiskOranlari
Fonksiyon bir table-valued function — her cari için detay satırları döndürüyor. Her satırda bir TipNo var:
| TipNo | Anlam |
|---|---|
| 1 | Açık hesap |
| 2 | Kendi çeki |
| 3 | Müşterisinin çeki |
| 4 | Kendi senedi |
| 5 | Müşterisinin senedi |
| 8 | Faturalaşmamış irsaliye |
| 9 | Açık sipariş |
Beş Kritik Keşif
Bu raporu birebir eşleştirene kadar beş önemli tuzağa düştük. Her biri ayrı bir ders.
1. Toplam Ciro: CARI_HESAP_HAREKETLERI Değil, STOK_HAREKETLERI
İlk denemede toplam ciroyu CARI_HESAP_HAREKETLERI tablosundan hesapladık. Mikro raporuyla eşleşmedi:
| Kaynak | Sonuç |
|---|---|
CARI_HESAP_HAREKETLERI / cha_meblag | 1.641.394,76 |
CARI_HESAP_HAREKETLERI net tahmini | 1.375.782,65 |
| Mikro rapor | 1.362.408,25 |
STOK_HAREKETLERI net satış satır toplamı | 1.362.408,25 ✓ |
Ders: Cari hareket tablosu “ciro” değil — tahsilat, vade farkı, kur farkı gibi finansal hareketleri de içerir. Mikro’nun ciro mantığı stok/fatura satırlarından geliyor.
Doğru formül:
SUM(
CASE WHEN ISNULL(sth_normal_iade, 0) = 1 THEN -1 ELSE 1 END
* (
sth_tutar
- (sth_iskonto1 + sth_iskonto2 + sth_iskonto3
+ sth_iskonto4 + sth_iskonto5 + sth_iskonto6)
+ (sth_masraf1 + sth_masraf2 + sth_masraf3 + sth_masraf4)
)
)
Filtreler: sth_iptal = 0, sth_fat_uid dolu (faturalaşmış satırlar), tarih aralığı.
2. Açık Sipariş: KDV Dahil/Hariç Farkı
İlk sipariş hesabımız 28.168,68 verdi. Mikro raporu 23.473,90 gösteriyordu.
23.473,90 × 1,20 = 28.168,68
Tam %20 KDV farkı. Rapor parametresinde “İrsaliye ve sipariş KDV dahil raporlansın” seçili değildi. KDV hariç hesaplamak gerekiyordu.
Birim fiyat formülü:
(
sip_tutar
- (sip_iskonto_1 + ... + sip_iskonto_6)
+ (sip_masraf_1 + ... + sip_masraf_4)
+ CASE WHEN @SiparisIrsaliyeKDVDahil = 1
THEN (sip_vergi + sip_masvergi + sip_Otv_Vergi + sip_otvtutari)
ELSE 0
END
) / NULLIF(sip_miktar, 0)
Kalan miktar: fn_Evrak_Kalan_Miktar(sip_miktar, sip_teslim_miktar, sip_kapat_fl)
3. Çek/Senet: TipAdi LIKE Değil, TipNo Kullanın
İlk denemede fonksiyon çıktısındaki metin alanıyla eşleşme yapmaya çalıştık:
-- YANLIŞ: Metin bazlı eşleşme güvenilir değil
WHERE TipAdi LIKE '%çek%'
Doğru yöntem, TipNo integer alanını kullanmak:
-- DOĞRU: TipNo ile kesin eşleşme
SUM(CASE WHEN TipNo = 3 THEN ISNULL(AnaDovizTutar, 0) ELSE 0 END)
AS MusterisininCeki
4. Cirolanan Çek/Senet Risk Süresi: NULL Verilirse Sonuç Eksik Gelir
İlk fn_CariRiskFoyu çağrısında @cirocekilkvade ve @cirosenetilkvade parametrelerini NULL vermiştik. Müşteri çeki ve senedi eksik geliyordu.
Rapor parametrelerinde tanımlı:
- Cirolanan çek vade sonrası risk süresi: 10 gün
- Cirolanan senet vade sonrası risk süresi: 30 gün
SQL karşılığı:
DECLARE @CiroCekIlkVade DATETIME
= DATEADD(DAY, -@CiroCekRiskSuresiGun, @Tarih);
DECLARE @CiroSenetIlkVade DATETIME
= DATEADD(DAY, -@CiroSenetRiskSuresiGun, @Tarih);
Bu düzeltmeden sonra çek/senet değerleri raporla birebir eşleşti.
5. fn_CariRiskFoyu Her Cari İçin Ayrı Çalışıyor
Fonksiyon CROSS APPLY ile her cari satırı için tekrar tekrar yürütülüyor. İçeride çok sayıda tablo ve scalar fonksiyon çağrısı var.
Mikro orijinal rapor (046355): 1600+ cari → 45+ dakika
Optimize SQL sorgumuz: 1600+ cari → ~15 dakika (3x hızlı)
Tek cari için kabul edilebilir, ama toplu rapor için ciddi darboğaz. Yine de Mikro’nun orijinal raporuna kıyasla temp tablo + index optimizasyonu ile ciddi hız kazanımı sağladık.
Doğrulama: Tek Cari Eşleşme Testi
Sorgu sonucunu Mikro 046355 raporuyla tek cari üzerinden birebir doğruladık:
Cari: [Örnek Cari] — Reklam ve Kırtasiye sektörü
Toplam ciro: 1.362.408,25 ✓
Kredi toplamı: 3.500.000,00 ✓
Açık sipariş: 23.473,90 ✓
Faturalaşmamış irsaliye: 0,00 ✓
Açık hesap: 2.896.672,94 ✓
Kredi limiti: -575.158,38 ✓
Kendi çeki: 0,00 ✓
Müşterisinin çeki: 691.362,19 ✓
Kendi senedi: 0,00 ✓
Müşterisinin senedi: 102.000,00 ✓
Ödenmeyen toplam: 793.362,19 ✓
Toplam risk: 3.713.509,03 ✓
Tüm değerler kuruşuna kadar eşleşti.
Nihai Optimize SQL Sorgusu
Aşağıdaki sorgu temp tablolar ve clustered index’ler ile optimize edilmiş nihai versiyondur:
SET NOCOUNT ON;
-- =============================================
-- ⚙️ AYARLAR: Kendi ortamınıza göre değiştirin
-- =============================================
DECLARE @FirmaNo INT = 0;
DECLARE @Tarih DATETIME = GETDATE();
DECLARE @CiroBaslangicTarihi DATETIME = '20260101'; -- ⚙️ Ciro başlangıcı
DECLARE @CariKodLike NVARCHAR(25) = 'M.35%'; -- ⚙️ Cari filtresi
DECLARE @SrmMerkezKodu NVARCHAR(25) = '';
DECLARE @BagliCarileriBirlikteHesapla BIT = 0;
DECLARE @TeminattaVadeKontrol BIT = 0;
DECLARE @SiparisIrsaliyeKDVDahil BIT = 0; -- ⚙️ KDV dahil/hariç
DECLARE @CiroCekRiskSuresiGun INT = 10; -- ⚙️ Çek risk süresi
DECLARE @CiroSenetRiskSuresiGun INT = 30; -- ⚙️ Senet risk süresi
DECLARE @CiroCekIlkVade DATETIME
= DATEADD(DAY, -@CiroCekRiskSuresiGun, @Tarih);
DECLARE @CiroSenetIlkVade DATETIME
= DATEADD(DAY, -@CiroSenetRiskSuresiGun, @Tarih);
IF OBJECT_ID('tempdb..#CariBase') IS NOT NULL DROP TABLE #CariBase;
IF OBJECT_ID('tempdb..#Ciro') IS NOT NULL DROP TABLE #Ciro;
IF OBJECT_ID('tempdb..#AcikSiparis') IS NOT NULL DROP TABLE #AcikSiparis;
IF OBJECT_ID('tempdb..#RiskOzet') IS NOT NULL DROP TABLE #RiskOzet;
------------------------------------------------------------
-- 1) Cari listesi
------------------------------------------------------------
SELECT
ch.cari_kod,
ch.cari_unvan1,
ch.cari_unvan2,
ch.cari_temsilci_kodu
INTO #CariBase
FROM CARI_HESAPLAR ch WITH (NOLOCK)
WHERE ch.cari_kod LIKE @CariKodLike;
CREATE UNIQUE CLUSTERED INDEX IX_CariBase ON #CariBase(cari_kod);
------------------------------------------------------------
-- 2) Toplam ciro — STOK_HAREKETLERI net satış satır toplamı
------------------------------------------------------------
SELECT
sth.sth_cari_kodu AS cari_kod,
SUM(
CASE WHEN ISNULL(sth.sth_normal_iade, 0) = 1
THEN -1 ELSE 1 END
* (
ISNULL(sth.sth_tutar, 0)
- (ISNULL(sth.sth_iskonto1, 0) + ISNULL(sth.sth_iskonto2, 0)
+ ISNULL(sth.sth_iskonto3, 0) + ISNULL(sth.sth_iskonto4, 0)
+ ISNULL(sth.sth_iskonto5, 0) + ISNULL(sth.sth_iskonto6, 0))
+ (ISNULL(sth.sth_masraf1, 0) + ISNULL(sth.sth_masraf2, 0)
+ ISNULL(sth.sth_masraf3, 0) + ISNULL(sth.sth_masraf4, 0))
)
) AS ToplamCiro
INTO #Ciro
FROM STOK_HAREKETLERI sth WITH (NOLOCK)
JOIN #CariBase cb ON cb.cari_kod = sth.sth_cari_kodu
WHERE sth.sth_tarih >= @CiroBaslangicTarihi
AND sth.sth_tarih <= @Tarih
AND ISNULL(sth.sth_iptal, 0) = 0
AND sth.sth_fat_uid IS NOT NULL
AND sth.sth_fat_uid <> '00000000-0000-0000-0000-000000000000'
GROUP BY sth.sth_cari_kodu;
CREATE UNIQUE CLUSTERED INDEX IX_Ciro ON #Ciro(cari_kod);
------------------------------------------------------------
-- 3) Açık sipariş — KDV parametresiyle
------------------------------------------------------------
SELECT
sip.sip_musteri_kod AS cari_kod,
SUM(
CASE WHEN sip.sip_tip = 0 THEN 1 ELSE -1 END
* dbo.fn_Evrak_Kalan_Miktar(
sip.sip_miktar, sip.sip_teslim_miktar, sip.sip_kapat_fl
)
* (
(
sip.sip_tutar
- (sip.sip_iskonto_1 + sip.sip_iskonto_2
+ sip.sip_iskonto_3 + sip.sip_iskonto_4
+ sip.sip_iskonto_5 + sip.sip_iskonto_6)
+ (sip.sip_masraf_1 + sip.sip_masraf_2
+ sip.sip_masraf_3 + sip.sip_masraf_4)
+ CASE WHEN @SiparisIrsaliyeKDVDahil = 1
THEN (sip.sip_vergi + sip.sip_masvergi
+ sip.sip_Otv_Vergi + sip.sip_otvtutari)
ELSE 0 END
) / NULLIF(sip.sip_miktar, 0)
)
* CASE WHEN sip.sip_doviz_cinsi > 0
THEN dbo.fn_KurBul(
@Tarih, sip.sip_doviz_cinsi,
dbo.fn_CariKurTipi(sip.sip_musteri_kod)
)
ELSE 1 END
) AS AcikSiparisTutar
INTO #AcikSiparis
FROM SIPARISLER sip WITH (NOLOCK)
JOIN #CariBase cb ON cb.cari_kod = sip.sip_musteri_kod
WHERE sip.sip_kapat_fl = 0
AND sip.sip_miktar > sip.sip_teslim_miktar
AND (sip.sip_cari_sormerk = @SrmMerkezKodu OR @SrmMerkezKodu = '')
GROUP BY sip.sip_musteri_kod;
CREATE UNIQUE CLUSTERED INDEX IX_AcikSiparis
ON #AcikSiparis(cari_kod);
------------------------------------------------------------
-- 4) Risk özet — fn_CariRiskFoyu (en ağır bölüm)
------------------------------------------------------------
SELECT
cb.cari_kod,
SUM(ISNULL(rf.[msg_S_1480\T], 0)) AS KrediToplami,
SUM(ISNULL(rf.[msg_S_1476\T], 0)) AS KullanilanKredi,
SUM(CASE WHEN rf.[#msg_S_1720] = 1
THEN ISNULL(rf.[msg_S_0103\T], 0) ELSE 0 END) AS AcikHesap,
SUM(CASE WHEN rf.[#msg_S_1720] = 8
THEN ISNULL(rf.[msg_S_0103\T], 0) ELSE 0 END)
AS FaturalasmamisIrsaliye,
SUM(CASE WHEN rf.[#msg_S_1720] = 2
THEN ISNULL(rf.[msg_S_0103\T], 0) ELSE 0 END) AS KendiCeki,
SUM(CASE WHEN rf.[#msg_S_1720] = 3
THEN ISNULL(rf.[msg_S_0103\T], 0) ELSE 0 END)
AS MusterisininCeki,
SUM(CASE WHEN rf.[#msg_S_1720] = 4
THEN ISNULL(rf.[msg_S_0103\T], 0) ELSE 0 END) AS KendiSenedi,
SUM(CASE WHEN rf.[#msg_S_1720] = 5
THEN ISNULL(rf.[msg_S_0103\T], 0) ELSE 0 END)
AS MusterisininSenedi
INTO #RiskOzet
FROM #CariBase cb
CROSS APPLY dbo.fn_CariRiskFoyu(
@FirmaNo, cb.cari_kod,
@CiroCekIlkVade, @CiroSenetIlkVade, @Tarih,
0, @SrmMerkezKodu,
@TeminattaVadeKontrol, @BagliCarileriBirlikteHesapla
) rf
GROUP BY cb.cari_kod;
CREATE UNIQUE CLUSTERED INDEX IX_RiskOzet ON #RiskOzet(cari_kod);
------------------------------------------------------------
-- 5) Final rapor
------------------------------------------------------------
SELECT
cb.cari_kod AS [Cari hesap kodu],
LTRIM(RTRIM(
ISNULL(cb.cari_unvan1, '') + ' ' + ISNULL(cb.cari_unvan2, '')
)) AS [Cari hesap adı],
cb.cari_temsilci_kodu AS [Temsilci kodu],
ROUND(ISNULL(c.ToplamCiro, 0), 2) AS [Toplam ciro],
ROUND(ISNULL(ro.KrediToplami, 0), 2) AS [Kredi toplamı],
ROUND(ISNULL(sip.AcikSiparisTutar, 0), 2) AS [Açık sipariş],
ROUND(ISNULL(ro.FaturalasmamisIrsaliye, 0), 2)
AS [Faturalaşmamış irsaliye],
ROUND(ISNULL(ro.AcikHesap, 0), 2) AS [Açık hesap],
ROUND(
ISNULL(ro.KullanilanKredi, 0) - ISNULL(ro.KrediToplami, 0), 2
) AS [Kredi limiti],
ROUND(ISNULL(ro.KendiCeki, 0), 2) AS [Kendi çeki],
ROUND(ISNULL(ro.MusterisininCeki, 0), 2) AS [Müşterisinin çeki],
ROUND(ISNULL(ro.KendiSenedi, 0), 2) AS [Kendi senedi],
ROUND(ISNULL(ro.MusterisininSenedi, 0), 2) AS [Müşterisinin senedi],
ROUND(
ISNULL(ro.KendiCeki, 0) + ISNULL(ro.MusterisininCeki, 0)
+ ISNULL(ro.KendiSenedi, 0) + ISNULL(ro.MusterisininSenedi, 0), 2
) AS [Ödenmeyen toplam],
ROUND(
ISNULL(ro.AcikHesap, 0) + ISNULL(sip.AcikSiparisTutar, 0)
+ ISNULL(ro.FaturalasmamisIrsaliye, 0)
+ ISNULL(ro.KendiCeki, 0) + ISNULL(ro.MusterisininCeki, 0)
+ ISNULL(ro.KendiSenedi, 0) + ISNULL(ro.MusterisininSenedi, 0), 2
) AS [Toplam risk]
FROM #CariBase cb
LEFT JOIN #RiskOzet ro ON ro.cari_kod = cb.cari_kod
LEFT JOIN #AcikSiparis sip ON sip.cari_kod = cb.cari_kod
LEFT JOIN #Ciro c ON c.cari_kod = cb.cari_kod
WHERE ISNULL(c.ToplamCiro, 0) <> 0
OR ISNULL(ro.KrediToplami, 0) <> 0
OR ISNULL(sip.AcikSiparisTutar, 0) <> 0
OR ISNULL(ro.AcikHesap, 0) <> 0
OR ISNULL(ro.KendiCeki, 0) <> 0
OR ISNULL(ro.MusterisininCeki, 0) <> 0
OR ISNULL(ro.KendiSenedi, 0) <> 0
OR ISNULL(ro.MusterisininSenedi, 0) <> 0
ORDER BY [Toplam risk] DESC, cb.cari_kod;
Performans: Darboğaz ve Optimizasyon
Darboğaz Analizi
Ana performans sorunu CROSS APPLY fn_CariRiskFoyu bölümüdür. Fonksiyon her cari için bağımsız çalışır ve içeride fn_CariHesapAnaDovizBakiye, fn_KurBul, fn_Evrak_Kalan_Miktar gibi alt fonksiyonları çağırır.
Mikro 046355 orijinal rapor: 1600+ cari → 45+ dakika
Optimize SQL sorgumuz: 1600+ cari → ~15 dakika
Kazanım: ~3x daha hızlı
Uygulanan Optimizasyonlar
Bu sorguda darboğazı hafifletmek için şunları yaptık:
- Temp tablo mimarisi — Her bileşen ayrı
#TempTable’a alındı. - Clustered index — Her temp tabloya
cari_kodüzerinde index eklendi. - Ciro ve sipariş ayrıştırma — Bu iki kalem fonksiyon dışında hesaplandı, böylece fonksiyonun yükü azaldı.
- Filtre daraltma —
@CariKodLikeile sadece ilgili cariler işlendi.
Orta Vadeli Çözüm: Snapshot Tablo
Rapor sık kullanılacaksa canlı çalıştırmak yerine periyodik snapshot oluşturulmalıdır:
-- Örnek snapshot tablo
CREATE TABLE dbo.CariRiskSnapshot (
cari_kod NVARCHAR(25) PRIMARY KEY,
cari_ad NVARCHAR(200),
temsilci_kodu NVARCHAR(25),
toplam_ciro DECIMAL(18,2),
kredi_toplami DECIMAL(18,2),
acik_siparis DECIMAL(18,2),
faturalasmamis DECIMAL(18,2),
acik_hesap DECIMAL(18,2),
kredi_limiti DECIMAL(18,2),
kendi_ceki DECIMAL(18,2),
musteri_ceki DECIMAL(18,2),
kendi_senedi DECIMAL(18,2),
musteri_senedi DECIMAL(18,2),
odenmeyen_toplam DECIMAL(18,2),
toplam_risk DECIMAL(18,2),
snapshot_tarihi DATETIME DEFAULT GETDATE()
);
Bu tablo SQL Agent job ile doldurulabilir:
- Gece 01:00 — Tüm cariler için hesapla.
- Gün içi — Dashboard bu tabloyu okur. Anında yanıt, sıfır bekleme.
- 30 dakikada bir — Daha güncel veri gerekiyorsa interval kısaltılabilir.
Rapor Parametreleri: SQL Karşılıkları
Mikro 046355 raporunu SQL ile birebir eşleştirmek istiyorsanız, rapor ekranındaki parametreleri SQL değişkenlerine çevirmeniz gerekir. Ayrıca kredi ve risk belirleme kriterleri Firma Tanıtım Kartı (501110) ekranından da kontrol edilmelidir.
| Mikro Parametre | SQL Değişkeni | Varsayılan |
|---|---|---|
| Listeleme yapısı | @CariKodLike | 'M.35%' |
| Ciro başlangıç tarihi | @CiroBaslangicTarihi | '20260101' |
| Cirolanan çek vade risk süresi | @CiroCekRiskSuresiGun | 10 |
| Cirolanan senet vade risk süresi | @CiroSenetRiskSuresiGun | 30 |
| İrsaliye/sipariş KDV dahil | @SiparisIrsaliyeKDVDahil | 0 |
| Vadesi geçmiş teminat raporlansın | @TeminattaVadeKontrol | 0 |
| Döviz cinsi | Fonksiyon içi | Ana döviz |
Edge Cases (İstisnai Durumlar)
- Dövizli siparişler: Açık sipariş hesabında dövizli siparişler
fn_KurBulile güncel kura çevrilir. Kur tanımlanmamışsa tutar 0 gelebilir. - Bağlı cariler:
@BagliCarileriBirlikteHesapla = 1yapılırsa bağlı cari bakiyeleri de ana cariye eklenir. Bu durumda sonuçlar farklılaşır. - Sorumluluk merkezi filtresi:
@SrmMerkezKoduboş bırakılmazsa sadece o sorumluluk merkezinin verileri gelir. - İptal kayıtları: Hem stok hareketlerinde hem siparişlerde
sth_iptal = 0vesip_kapat_fl = 0filtreleri kritiktir.
Bu Bilgiyi Nereden Biliyoruz? (Kaynaklar)
- AstaFlow Case Study: Finans ve Tahsilat Hedeflemesi Modülleri
- Mikro ERP DB API: CARI_HESAPLAR | SIPARISLER | STOK_HAREKETLERI
- İlgili Yazı: Cari Risk Raporu: Bakiye, Açık Sipariş ve Teminat Tek Sorguda — CTE tabanlı basitleştirilmiş risk analizi
- İlgili Yazı: Cari Yaşlandırma SQL Sorgusu — Vade bazlı gecikme analizi
- İlgili Yazı: Açık Sipariş ve Teslimat Raporu
- İlgili Araç: Evrak Tipi Decoder — sth_tip, cha_evrak_tip değerlerini anında çevirin
- İlgili Araç: Fonksiyon Sözlüğü — fn_CariRiskFoyu ve diğer dbo.fn_ referansları