Mikro ERP Açık Sipariş Raporu: Hangi Sipariş Ne Kadar Teslim Edildi?
Mikro ERP'de açık siparişler nasıl hatasız bulunur? İşletmelerin sip_kapat_fl tuzağına düşmeden teslimat takibi, sipariş karşılama oranı hesaplaması ve...
İş Problemi: “Hangi Sipariş Neden Kapanmadı?”
Mikro ERP kullanan işletmelerin en kronik sorunlarından biri teslimat takibidir. Satış ekibi siparişi girer, depo kısmi sevkiyat yapar, siparişin kalan kısmı ya iptal edilir ya da haftalarca açık unutulur.
Geleneksel raporlamada sadece sip_kapat_fl = 0 (Sipariş Açık) filtresi kullanılır. Neden Standart Yaklaşım Çalışmaz?
Çünkü sahadaki gerçek hayat veritabanına şöyle yansır:
- Müşteri 100 adet mal ister, 98 adet sevk edilir, kalan 2 adetten vazgeçilir ama depocu siparişi manuel olarak kapatmayı unutur (Sipariş açık kalır).
- Siparişin tamamı sevk edilmesine rağmen irsaliye-sipariş eşleştirmesinde evrak referansları (cha_srmrkkodu vb.) hatalı bağlandığı için sistem siparişi kapalı saymaz.
- Sipariş iptal edilmiştir (
sip_iptal = 1) ama kapatılmamıştır.
Bu yüzden 200+ açık siparişi olan bir işletmenin aslında sadece 40 adet gerçekten sevk edilmeyi bekleyen “hazır” siparişi olabilir.
Somut Hata ve Karşılaşılan Manzara
Eğer standart program arayüzünden (View: Siparişler Föyü) bakarsanız, aşağıdaki gibi yanıltıcı bir tabloyla karşılaşırsınız:
SQL Log Analizi:
sip_evrakno: SP-1234|sip_miktar: 100|sip_teslim_miktar: 100|sip_kapat_fl: 0Sonuç: Sistem bu siparişi açık gösteriyor ama verilecek mal kalmamış!
Çözüm: Kapsamlı ve Hatasız SQL Sorgusu
Doğru bir açık sipariş raporu hem flag (sip_kapat_fl), hem iptal durumu (sip_iptal), hem de miktar farkını (sip_miktar > sip_teslim_miktar) aynı anda kontrol etmelidir.
Aşağıdaki sorgu, AstaFlow gibi kurumsal projelerin dashboard’larında kullanılan production-ready (canlı ortama hazır) koddur:
SELECT
SIP.sip_evrakno_seri + '-' +
CAST(SIP.sip_evrakno_sira AS VARCHAR) AS [Sipariş No],
CONVERT(VARCHAR(10), SIP.sip_tarih, 104) AS [Sipariş Tarihi],
CONVERT(VARCHAR(10), SIP.sip_teslim_tarih, 104) AS [PLANLANAN Teslim Tarihi],
SIP.sip_musteri_kod AS [Müşteri Kodu],
C.cari_unvan1 AS [Müşteri Ünvanı],
SIP.sip_stok_kod AS [Stok Kodu],
S.sto_isim AS [Ürün Adı],
SIP.sip_miktar AS [Sipariş Miktar],
SIP.sip_teslim_miktar AS [Sevk Edilen],
(SIP.sip_miktar - SIP.sip_teslim_miktar) AS [Bekleyen Miktar],
-- Karşılama oranı matematiği (Sıfıra bölünme hatasını önler)
CAST(ROUND(
(SIP.sip_teslim_miktar / NULLIF(SIP.sip_miktar, 0)) * 100, 1
) AS VARCHAR) + '%' AS [Karşılama Oranı],
-- Gecikme hesaplaması
CASE
WHEN SIP.sip_teslim_tarih < CAST(GETDATE() AS DATE)
THEN DATEDIFF(DAY, SIP.sip_teslim_tarih, GETDATE())
ELSE 0
END AS [Geciken Gün Sayısı],
-- SLA Durum Bildirgesi
CASE
WHEN DATEDIFF(DAY, SIP.sip_teslim_tarih, GETDATE()) > 15 THEN '🔴 Kritik Gecikme'
WHEN DATEDIFF(DAY, SIP.sip_teslim_tarih, GETDATE()) > 3 THEN '🟡 Gecikti'
ELSE '🟢 Zamanında'
END AS [SLA Durumu]
FROM SIPARISLER SIP WITH (NOLOCK)
LEFT JOIN CARI_HESAPLAR C WITH (NOLOCK) ON SIP.sip_musteri_kod = C.cari_kod
LEFT JOIN STOKLAR S WITH (NOLOCK) ON SIP.sip_stok_kod = S.sto_kod
-- KRİTİK FİLTRELER:
WHERE SIP.sip_iptal = 0 -- 1. Kural: İptal edilmemiş olacak
-- 2. Kural: Kapatılmamış VEYA (nadiren kapalı olsa da) eksik teslimat var
AND (SIP.sip_kapat_fl = 0 OR SIP.sip_miktar > SIP.sip_teslim_miktar)
-- 3. Kural: Sevk edilecek miktar sıfırdan büyük olmalı
AND (SIP.sip_miktar - SIP.sip_teslim_miktar) > 0
AND SIP.sip_tip = 1 -- 1=Satış Siparişi, 0=Alış Siparişi
ORDER BY [Geciken Gün Sayısı] DESC, SIP.sip_teslim_tarih ASC;
Kodun Anatomisi: Neden Bu Şekilde Yazıldı?
WITH (NOLOCK): Sipariş tablosu çok hareketlidir. Depo irsaliye keserken sipariş tablosuna kilit (lock) konur. Rapor çekerkenNOLOCKkullanmazsanız sistemde kilitlenmelere (deadlock) neden olabilirsiniz.NULLIF(SIP.sip_miktar, 0): Veritabanında hatalı bir sipariş kaydı (0 miktarlı) varsa, “Divide by zero” hatasını engeller. Modüler mimaride hatalar tolere edilmelidir.SIP.sip_tip = 1: Mikro’da hem alınan siparişler hem verilen (satınalma) siparişleri aynı tabloda tutulur. Bu filtre unutulursa müşteriye gidecek ürünlerle tedarikçiden beklenen ürünler birbirine karışır.
Edge Cases (İstisnai Durumlar) ve Püf Noktaları
SQL’i yazdık ve çalıştı. Ancak production (canlı) ortamında şu istisnalara dikkat etmelisiniz:
- Konsinye Siparişler: Konsinye olarak girilen siparişlerin teslimat takibi farklıdır.
sip_evrak_tipfiltresi ile normal siparişleri (Evrak Tip=1) filtrelemek gerekebilir. - Kısmi Kapanışlar (Manuel Müdahale): Müşteri 100 adet istedi, 50 yolladık, “kalana gerek yok” dedi. Personel faturadan siparişi manuel olarak “Kapalı” işaretler. Ancak bizim
(SIP.sip_miktar - SIP.sip_teslim_miktar) > 0şartımız bunu yakalar. Eğer personel siparişi kapatmışsa bunu rapordan düşmeliyiz. O yüzden şu bloğu:AND (SIP.sip_kapat_fl = 0)şeklinde sıkılaştırmak, siparişi gerçekten kapatılmış saymak demektir. İşletmenizin süreç prensibine göre karar vermelisiniz.
Performans / Ölçekleme Testi
AstaFlow projesinde 1.2 Milyon sipariş satırı olan bir firmada bu sorgunun performans ölçümü yapıldı:
- Filtresiz (Tüm Tarihler): Table Scan nedeniyle sorgu 12.4 saniye sürdü.
- Optimizasyon (Index):
sip_kapat_fl,sip_iptalvesip_tipüzerinde non-clustered index tanımlandığında. - Sonuç: Execution Plan “Index Seek”e döndü, süre 0.2 saniyeye (%98 iyileşme) düştü.
Eğer veritabanınız büyükse, bu alanlarda bir indeks olduğundan veya son 2 yılı filtrelediğinizden (sip_tarih >= '2022-01-01') emin olun.
Bu Bilgiyi Nereden Biliyoruz? (Kaynaklar)
- AstaFlow Case Study: Çok Şubeli Kurumsal Entegrasyon Deneyimleri
- Mikro ERP DB API: SIPARISLER Tablosu Resmi Referansı
- İlgili Çözüm: Fatura ve Sipariş Eşleştirme İz Sürme