Erp Asistanı Erp Asistanı
Netsis SQL

Netsis Sipariş Teslimat Performansı ve Termin Sapması SQL

Netsis TBLSIPATRA ve TBLSTHAR ile sipariş teslimat performansı, termin sapması ve OTIF hesaplama SQL sorguları. Kısmi sevkiyat ve kapatma analizi.

Erp Asistanı Erp Asistanı Editör ekibi 8 dk okuma
Netsis Sipariş Teslimat Performansı ve Termin Sapması SQL

Müşteri memnuniyetini ve tedarik zinciri verimliliğini ölçmenin en nesnel yolu, siparişlerin taahhüt edilen tarihte ve eksiksiz ulaştırılıp ulaştırılmadığını takip etmektir. Kurumsal raporlamada OTIF (On-Time In-Full / Zamanında ve Eksiksiz Teslimat) olarak adlandırılan bu performans metriği, Netsis ERP üzerinde sipariş başlığındaki termin tarihi ile fiili sevk hareketlerinin karşılaştırılmasıyla hesaplanır. Netsis açık siparişler SQL rehberi ve Netsis stok hareketleri rehberi yapılarından yararlanarak, kısmi teslimatları ve erken kapatılan kalemleri ayrıştıran T-SQL sorgularını bu yazıda bulabilirsiniz.

Netsis mimarisinde sipariş kabulü ile depo çıkışı iki ayrı süreç olarak yürütülür. Sipariş satırları TBLSIPATRA tablosunda yaşarken, irsaliye ve fatura ile gerçekleşen fiziksel çıkışlar TBLSTHAR tablosuna yazılır. Teslimat performansını doğru analiz edebilmek için bu iki tablonun doğru anahtarlarla birbirine bağlanması şarttır.

Sipariş ve sevkiyat tabloları eşleştirme mantığı

Netsis'te müşteri siparişi girildiğinde başlık bilgisi TBLSIPAMAS tablosuna (FTIRSIP = '6'), kalem detayları ise TBLSIPATRA tablosuna (STHAR_FTIRSIP = '6') kaydedilir. Taahhüt edilen teslimat tarihi başlık seviyesinde SIPARIS_TEST alanında tutulur.

Siparişten irsaliye veya fatura oluşturulduğunda sevk satırları TBLSTHAR tablosuna aktarılır. Bu hareketlerin siparişle bağı TBLSTHAR.STHAR_SIPNUM kolonu üzerinden kurulur. STHAR_SIPNUM, ilgili siparişin FATIRS_NO bilgisini taşır.

Veri Türü Tablo Kritik Kolonlar Eşleme / Filtre Koşulu
Sipariş Başlığı TBLSIPAMAS FATIRS_NO, SIPARIS_TEST, KAPATILMIS FTIRSIP = '6' (Müşteri Siparişi)
Sipariş Kalemi TBLSIPATRA FISNO, STOK_KODU, STHAR_GCMIK FISNO = TBLSIPAMAS.FATIRS_NO
Sevk / Hareket TBLSTHAR STHAR_SIPNUM, STHAR_TARIH, STHAR_GCMIK STHAR_FTIRSIP IN ('1','3','A') AND STHAR_GCKOD = 'C'

Netsis tablo yapısı rehberi yazımızda belirtildiği gibi, SUBE_KODU filtresi çok şubeli yapılarda veri güvenliği için tüm tablolarda ortak kullanılmalıdır.

1. Kalem bazında termin sapması ve gecikme günü

Bu sorgu, sipariş kalemlerinin taahhüt edilen termin tarihi (SIPARIS_TEST) ile gerçekleşen en son sevk tarihi (MAX(STHAR_TARIH)) arasındaki gün farkını hesaplar. Kısmi sevk durumunda son hareket tarihi baz alınır.

SELECT
    s.SUBE_KODU,
    s.FATIRS_NO AS SiparisNo,
    s.CARI_KODU AS CariKodu,
    s.TARIH AS SiparisTarihi,
    s.SIPARIS_TEST AS TerminTarihi,
    tra.STOK_KODU AS StokKodu,
    tra.STHAR_GCMIK AS SiparisMiktar,
    ISNULL(SUM(sth.STHAR_GCMIK), 0) AS SevkEdilenMiktar,
    tra.STHAR_GCMIK - ISNULL(SUM(sth.STHAR_GCMIK), 0) AS KalanMiktar,
    MAX(sth.STHAR_TARIH) AS SonSevkTarihi,
    CASE 
        WHEN MAX(sth.STHAR_TARIH) IS NULL THEN DATEDIFF(day, s.SIPARIS_TEST, GETDATE())
        ELSE DATEDIFF(day, s.SIPARIS_TEST, MAX(sth.STHAR_TARIH))
    END AS SapmaGunu,
    s.KAPATILMIS AS SiparisDurum
FROM TBLSIPAMAS s
INNER JOIN TBLSIPATRA tra
    ON tra.FISNO = s.FATIRS_NO
    AND tra.SUBE_KODU = s.SUBE_KODU
    AND tra.STHAR_FTIRSIP = '6'
LEFT JOIN TBLSTHAR sth
    ON sth.STHAR_SIPNUM = s.FATIRS_NO
    AND sth.STOK_KODU = tra.STOK_KODU
    AND sth.SUBE_KODU = s.SUBE_KODU
    AND sth.STHAR_GCKOD = 'C'
    AND sth.STHAR_FTIRSIP IN ('1', '3', 'A')
WHERE s.FTIRSIP = '6'
  AND s.TARIH >= '20260101'
GROUP BY
    s.SUBE_KODU,
    s.FATIRS_NO,
    s.CARI_KODU,
    s.TARIH,
    s.SIPARIS_TEST,
    tra.STOK_KODU,
    tra.STHAR_GCMIK,
    s.KAPATILMIS;

2. Kısmi teslimat ve OTIF başarı sınıflandırması

Bir sipariş satırının OTIF standardına uygun sayılması için iki şart aynı anda sağlanmalıdır:

  1. On-Time (Zamanında): Son sevk tarihi, termin tarihine eşit veya termin tarihinden önce olmalıdır.
  2. In-Full (Eksiksiz): Sevk edilen toplam miktar, sipariş edilen miktara eşit veya büyük olmalıdır.

Sipariş zorla kapatılmışsa (KAPATILMIS = 'K') ve miktar tamamlanmamışsa işlem eksik teslimat olarak etiketlenir.

WITH SiparisSevkDetay AS (
    SELECT
        s.SUBE_KODU,
        s.FATIRS_NO AS SiparisNo,
        s.CARI_KODU AS CariKodu,
        s.SIPARIS_TEST AS TerminTarihi,
        s.KAPATILMIS AS SiparisDurumu,
        tra.STOK_KODU AS StokKodu,
        tra.STHAR_GCMIK AS SiparisMiktar,
        ISNULL(SUM(sth.STHAR_GCMIK), 0) AS SevkMiktar,
        MAX(sth.STHAR_TARIH) AS SonSevkTarihi
    FROM TBLSIPAMAS s
    INNER JOIN TBLSIPATRA tra
        ON tra.FISNO = s.FATIRS_NO
        AND tra.SUBE_KODU = s.SUBE_KODU
        AND tra.STHAR_FTIRSIP = '6'
    LEFT JOIN TBLSTHAR sth
        ON sth.STHAR_SIPNUM = s.FATIRS_NO
        AND sth.STOK_KODU = tra.STOK_KODU
        AND sth.SUBE_KODU = s.SUBE_KODU
        AND sth.STHAR_GCKOD = 'C'
        AND sth.STHAR_FTIRSIP IN ('1', '3', 'A')
    WHERE s.FTIRSIP = '6'
      AND s.SIPARIS_TEST IS NOT NULL
      AND s.TARIH >= '20260101'
    GROUP BY
        s.SUBE_KODU,
        s.FATIRS_NO,
        s.CARI_KODU,
        s.SIPARIS_TEST,
        s.KAPATILMIS,
        tra.STOK_KODU,
        tra.STHAR_GCMIK
)
SELECT
    SiparisNo,
    CariKodu,
    StokKodu,
    TerminTarihi,
    SonSevkTarihi,
    SiparisMiktar,
    SevkMiktar,
    CASE 
        WHEN SevkMiktar >= SiparisMiktar AND SonSevkTarihi <= TerminTarihi THEN 'OTIF Basarili'
        WHEN SevkMiktar >= SiparisMiktar AND SonSevkTarihi > TerminTarihi THEN 'Gecikmeli Tam Teslimat'
        WHEN SevkMiktar < SiparisMiktar AND SiparisDurumu = 'K' THEN 'Eksik Kapatilmis'
        WHEN SevkMiktar < SiparisMiktar AND TerminTarihi < GETDATE() THEN 'Geciken Kismi Teslimat'
        ELSE 'Islemde / Bekliyor'
    END AS TeslimatDurumu
FROM SiparisSevkDetay;

3. Müşteri bazında OTIF ve zamanında teslimat performans özeti

Müşteri bazında sipariş kalem adedi, zamanında teslim oranı ve genel OTIF başarı oranını hesaplayan yönetimsel KPI tablosu:

WITH KalemHesap AS (
    SELECT
        s.CARI_KODU AS CariKodu,
        tra.INCKEYNO,
        tra.STHAR_GCMIK AS SiparisMiktar,
        ISNULL(SUM(sth.STHAR_GCMIK), 0) AS SevkMiktar,
        s.SIPARIS_TEST AS TerminTarihi,
        MAX(sth.STHAR_TARIH) AS SonSevkTarihi,
        s.KAPATILMIS AS KapatilmisDurumu
    FROM TBLSIPAMAS s
    INNER JOIN TBLSIPATRA tra
        ON tra.FISNO = s.FATIRS_NO
        AND tra.SUBE_KODU = s.SUBE_KODU
        AND tra.STHAR_FTIRSIP = '6'
    LEFT JOIN TBLSTHAR sth
        ON sth.STHAR_SIPNUM = s.FATIRS_NO
        AND sth.STOK_KODU = tra.STOK_KODU
        AND sth.SUBE_KODU = s.SUBE_KODU
        AND sth.STHAR_GCKOD = 'C'
        AND sth.STHAR_FTIRSIP IN ('1', '3', 'A')
    WHERE s.FTIRSIP = '6'
      AND s.TARIH >= '20260101'
      AND s.SIPARIS_TEST IS NOT NULL
    GROUP BY
        s.CARI_KODU,
        tra.INCKEYNO,
        tra.STHAR_GCMIK,
        s.SIPARIS_TEST,
        s.KAPATILMIS
)
SELECT
    CariKodu,
    COUNT(INCKEYNO) AS ToplamSiparisKalemi,
    SUM(CASE WHEN SevkMiktar >= SiparisMiktar THEN 1 ELSE 0 END) AS TamTeslimKalemSayisi,
    SUM(CASE WHEN SonSevkTarihi <= TerminTarihi THEN 1 ELSE 0 END) AS ZamanindaKalemSayisi,
    SUM(CASE WHEN SevkMiktar >= SiparisMiktar AND SonSevkTarihi <= TerminTarihi THEN 1 ELSE 0 END) AS OTIFKalemSayisi,
    CAST(ROUND(100.0 * SUM(CASE WHEN SonSevkTarihi <= TerminTarihi THEN 1 ELSE 0 END) / COUNT(INCKEYNO), 2) AS decimal(5,2)) AS ZamanindaTeslimatYuzdesi,
    CAST(ROUND(100.0 * SUM(CASE WHEN SevkMiktar >= SiparisMiktar AND SonSevkTarihi <= TerminTarihi THEN 1 ELSE 0 END) / COUNT(INCKEYNO), 2) AS decimal(5,2)) AS OTIFYuzdesi
FROM KalemHesap
GROUP BY CariKodu
HAVING COUNT(INCKEYNO) >= 5
ORDER BY ToplamSiparisKalemi DESC;

4. Geciken ve açık bekleyen riskli siparişler

Henüz kapatılmamış (KAPATILMIS = 'S'), teslim tarihi geçmiş ve sevk bekleyen sipariş kalemleri anlık operasyonel risk oluşturur. Depo ve sevkiyat planlama ekipleri bu listeyi günlük takip etmelidir:

SELECT
    s.SUBE_KODU,
    s.FATIRS_NO AS SiparisNo,
    s.CARI_KODU AS CariKodu,
    s.TARIH AS SiparisTarihi,
    s.SIPARIS_TEST AS TerminTarihi,
    DATEDIFF(day, s.SIPARIS_TEST, GETDATE()) AS GecikmeGunu,
    tra.STOK_KODU AS StokKodu,
    tra.STHAR_GCMIK AS SiparisMiktar,
    ISNULL(SUM(sth.STHAR_GCMIK), 0) AS SevkEdilenMiktar,
    tra.STHAR_GCMIK - ISNULL(SUM(sth.STHAR_GCMIK), 0) AS BekleyenMiktar
FROM TBLSIPAMAS s
INNER JOIN TBLSIPATRA tra
    ON tra.FISNO = s.FATIRS_NO
    AND tra.SUBE_KODU = s.SUBE_KODU
    AND tra.STHAR_FTIRSIP = '6'
LEFT JOIN TBLSTHAR sth
    ON sth.STHAR_SIPNUM = s.FATIRS_NO
    AND sth.STOK_KODU = tra.STOK_KODU
    AND sth.SUBE_KODU = s.SUBE_KODU
    AND sth.STHAR_GCKOD = 'C'
    AND sth.STHAR_FTIRSIP IN ('1', '3', 'A')
WHERE s.FTIRSIP = '6'
  AND s.KAPATILMIS = 'S'
  AND s.SIPARIS_TEST < CAST(GETDATE() AS date)
GROUP BY
    s.SUBE_KODU,
    s.FATIRS_NO,
    s.CARI_KODU,
    s.TARIH,
    s.SIPARIS_TEST,
    tra.STOK_KODU,
    tra.STHAR_GCMIK
HAVING tra.STHAR_GCMIK > ISNULL(SUM(sth.STHAR_GCMIK), 0)
ORDER BY GecikmeGunu DESC;

Sık yapılan hatalar

  • Tekilleştirme yapmadan doğrudan JOIN kurmak: TBLSIPATRA ile TBLSTHAR tabloları çoktan-çoğa ilişkilenme riski taşır (tek sipariş satırına birden fazla sevk hareketi). STHAR_SIPNUM ile bağlanırken TBLSTHAR tarafı mutlaka SUM/MAX ile gruplanmalı, aksi takdirde sipariş tutarları ve miktarları mükerrer katlanır.
  • STHAR_FTIRSIP ve yön filtresi koymamak: TBLSTHAR tablosunda alış, transfer ve iade hareketleri de yer alır. Sevkiyat çıkışları filtrelenirken STHAR_GCKOD = 'C' ve STHAR_FTIRSIP IN ('1', '3', 'A') şartları zorunludur.
  • Kapatılmış siparişleri (KAPATILMIS = 'K') başarılı saymak: Sipariş sevk edilmeden müşteri veya kullanıcı tarafından manuel kapatılmış olabilir. Kapatılmış ama sevk miktarı sipariş miktarından küçük satırlar OTIF başarısızlığıdır.
  • SUBE_KODU eşlemesini atlamak: Farklı şubelerde aynı sipariş numarası kullanılabilmektedir. TBLSIPAMAS, TBLSIPATRA ve TBLSTHAR arasındaki tüm JOIN koşullarında SUBE_KODU eşitliği aranmalıdır.
  • Boş termin tarihlerini hesaba katmamak: SIPARIS_TEST alanı girilmemiş kayıtlar DATEDIFF hesaplarında NULL döner veya hatalı gün farkı üretir. Sorgularda WHERE SIPARIS_TEST IS NOT NULL veya ISNULL kontrolleri bulunmalıdır.

Sık sorulanlar

Netsis'te termin tarihi kalem bazında mı başlıkta mı tutulur? Standart Netsis yapısında taahhüt edilen teslim tarihi TBLSIPAMAS.SIPARIS_TEST başlık kolonunda tutulur. Kalem bazlı farklı termin takibi gerekiyorsa ek alanlar veya modül özelleştirmeleri kullanılır.

Sipariş faturalaştığında veya sevk edildiğinde TBLSIPATRA'dan silinir mi? Hayır, silinmez. Netsis sipariş hareketlerini TBLSIPATRA tablosunda kalıcı olarak saklar. Sevkiyat hareketleri TBLSTHAR tablosuna yazılır ve STHAR_SIPNUM kolonu üzerinden kaynak sipariş numarasına referans verir.

Kısmi teslimatlarda termin sapması nasıl değerlendirilmelidir? Kısmi teslimatlarda genelde iki yaklaşım uygulanır: İlki operasyonel açıdan son sevk tarihini (MAX(STHAR_TARIH)) alarak siparişin bütünüyle ne zaman tamamlandığını ölçmektir. İkincisi ise ilk sevk tarihini (MIN(STHAR_TARIH)) alarak ilk yanıt hızını takip etmektir. OTIF standardı genellikle siparişin tam tamamlanma tarihini esas alır.

Kapatılmış (KAPATILMIS='K') açık miktarlı siparişler performansı nasıl etkiler? Kullanıcı tarafından bakiyesi silinerek kapatılan sipariş satırları, tedarik zincirinde karşılanamayan talebi (kayıp satışı) temsil eder. OTIF analizinde bu satırlar 'Eksik Kapatılmış' olarak işaretlenmeli ve teslimat başarı yüzdesini düşürmelidir.


Sipariş teslimat performansını ve termin sapmalarını SQL üzerinden manuel analiz etmek yerine canlı gösterge panelleriyle anlık izleyebilirsiniz. Erp Asistanı'na ücretsiz üye olarak Netsis veritabanınıza bağlanabilir, doğal dilde sorular sorarak OTIF ve gecikme raporlarınızı saniyeler içinde alabilirsiniz.

Ücretsiz üye olun, Netsis raporlarınızı hemen oluşturun →

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.