ERP Asistanı Dal Net
SAP SQL

SAP B1 Açık Sipariş SQL: RDR1 OpenQty ve Geciken Sevkiyat

RDR1.OpenQty, LineStatus ve ShipDate ile SAP Business One açık sipariş raporu: bekleyen miktar, geciken sevkiyat günü, müşteri ve ürün bazında açık tutar SQL'i.

Erp Asistanı Erp Asistanı Editör ekibi 9 dk okuma
SAP B1 Açık Sipariş SQL: RDR1 OpenQty ve Geciken Sevkiyat

SAP Business One'da açık sipariş raporu istendiğinde ilk akla gelen ORDR tablosunu DocStatus = 'O' ile süzmek oluyor. Bu filtre kısmen sevk edilmiş siparişleri de açık gösterir, kalan miktarı ise hiç söylemez: kalan miktar başlıkta değil satırda, RDR1.OpenQty kolonunda durur. Bu yazıda açık sipariş raporunu satır düzeyinde kuruyoruz: bekleyen miktar, geciken sevkiyat günü, kısmi teslim oranı ve müşteri ile ürün bazında bekleyen tutar. Sorgular Microsoft SQL Server (T-SQL) içindir, tek başına çalışır ve yalnız okuma yapar.

Açık sipariş nerede durur: başlık ORDR, satır RDR1

Satış siparişi iki tabloya yazılır: başlık ORDR (sipariş başına tek satır), kalemler RDR1. Satır başlığa DocEntry ile bağlanır, satır kimliği (DocEntry, LineNum) çiftidir. DocNum kullanıcının gördüğü numaradır ve seriye göre tekrar edebilir, bu yüzden JOIN'de kullanılmaz. Tablo adlarının mantığını bilmiyorsanız önce SAP Business One tablo yapısı rehberine bakın.

Kolon Yeri Ne söyler Tuzak
DocEntry ORDR / RDR1 Başlık ile satırın bağı DocNum ile JOIN etmeyin
CANCELED ORDR N normal, Y iptal, C iptal belgesi Her sorguda CANCELED = 'N'
DocStatus ORDR O açık, C kapalı Başlık açıkken satırların bir kısmı kapanmış olabilir
LineStatus RDR1 Satır durumu O / C Açıklık kararını bu kolon verir
OpenQty RDR1 Sevk ya da faturalanmamış kalan miktar Sipariş miktarı değildir
ShipDate RDR1 Satır teslim tarihi Başlıktaki DocDueDate ile karıştırmayın
Price RDR1 İndirim sonrası birim fiyat Belge para birimindedir
WhsCode RDR1 Depo kodu Metindir: '01', 1 değil

Teslim tarihi iki yerde tutulur: başlıkta DocDueDate, satırda ShipDate. Sevkiyat takibi satır bazında yapıldığı için gecikme hesabında ShipDate esas alınır. ShipDate boş bırakılmış satırlar tarih karşılaştırmasına girmez, bu yüzden gecikme listesinde görünmezler; bu satırları ayrı bir kontrol listesinde tutmak gerekir.

1. Temel liste: açık ve kısmen sevk edilmiş kalemler

Raporun çekirdeği iki filtre: LineStatus = 'O' ve OpenQty > 0. İkisi birlikte kullanılmazsa ya tamamen kapanmış satırlar listede kalır ya da sıfır kalanlı satırlar boşuna satır üretir.

SELECT o.DocNum      AS SiparisNo,
       o.DocDate     AS SiparisTarihi,
       o.DocDueDate  AS BaslikTeslimTarihi,
       o.CardCode    AS CariKod,
       c.CardName    AS CariAd,
       l.LineNum     AS SatirNo,
       l.ItemCode    AS StokKod,
       l.Dscription   AS StokAdi,
       l.Quantity    AS SiparisMiktari,
       l.OpenQty     AS KalanMiktar,
       l.WhsCode     AS Depo,
       l.ShipDate    AS SatirTeslimTarihi
FROM ORDR o
JOIN RDR1 l ON l.DocEntry = o.DocEntry
LEFT JOIN OCRD c ON c.CardCode = o.CardCode
WHERE o.CANCELED = 'N'
  AND l.LineStatus = 'O'
  AND l.OpenQty > 0
ORDER BY l.ShipDate, o.DocNum, l.LineNum;

Bu raporu SQL yazmadan, Türkçe sorarak alın: SAP Business One raporlama

2. Geciken sevkiyatlar ve gecikme günü

Teslim tarihi geçmiş, hala açık olan satırlar. DATEDIFF iki tarih arasındaki gün farkını verir; ShipDate datetime olduğu için GETDATE() ile doğrudan karşılaştırılabilir, saat kısmını kırpmak için bugünün tarihini CAST(GETDATE() AS date) ile alıyoruz.

SELECT o.DocNum     AS SiparisNo,
       o.CardCode   AS CariKod,
       c.CardName   AS CariAd,
       l.ItemCode   AS StokKod,
       l.Dscription AS StokAdi,
       l.OpenQty    AS KalanMiktar,
       l.ShipDate   AS SatirTeslimTarihi,
       DATEDIFF(DAY, l.ShipDate, CAST(GETDATE() AS date)) AS GecikmeGunu,
       CAST(l.OpenQty * l.Price AS decimal(18,2)) AS BekleyenTutar
FROM ORDR o
JOIN RDR1 l ON l.DocEntry = o.DocEntry
LEFT JOIN OCRD c ON c.CardCode = o.CardCode
WHERE o.CANCELED = 'N'
  AND l.LineStatus = 'O'
  AND l.OpenQty > 0
  AND l.ShipDate < CAST(GETDATE() AS date)
ORDER BY GecikmeGunu DESC, BekleyenTutar DESC;

3. Kısmi teslim: sevk edilen miktarı OpenQty'den türetmek

Raporda kısmi teslimi göstermenin en tutarlı yolu, sipariş miktarından kalan miktarı çıkarmaktır. Böylece Quantity ile OpenQty aynı satırdan okunur ve iki ayrı alan arasında tutarsızlık doğmaz.

SELECT o.DocNum     AS SiparisNo,
       o.CardCode   AS CariKod,
       l.ItemCode   AS StokKod,
       l.Quantity   AS SiparisMiktari,
       l.Quantity - l.OpenQty AS SevkEdilenMiktar,
       l.OpenQty    AS KalanMiktar,
       CAST(100.0 * (l.Quantity - l.OpenQty) / NULLIF(l.Quantity, 0) AS decimal(5,1)) AS KarsilamaYuzde
FROM ORDR o
JOIN RDR1 l ON l.DocEntry = o.DocEntry
WHERE o.CANCELED = 'N'
  AND l.OpenQty > 0
  AND l.Quantity > l.OpenQty
ORDER BY KarsilamaYuzde DESC, o.DocNum;

NULLIF(l.Quantity, 0) sıfır miktarlı satırda bölme hatasını engeller. Yüzde 100'e yakın satırlar sevkiyatı bitmek üzere olan, düşük yüzdeli satırlar hiç başlamamış kalemlerdir.

4. Müşteri bazında bekleyen miktar ve tutar

Bekleyen tutar için satırdaki OpenQty ile Price çarpılır. Price indirim sonrası birim fiyattır ve satırın belge para birimindedir; tek para birimli kurulumda doğrudan yerel tutardır, dövizli belgede yerel karşılık için satırdaki Rate ile çarpmak gerekir.

SELECT o.CardCode AS CariKod,
       c.CardName AS CariAd,
       COUNT(DISTINCT o.DocEntry) AS AcikSiparisSayisi,
       SUM(l.OpenQty) AS BekleyenMiktar,
       CAST(SUM(l.OpenQty * l.Price) AS decimal(18,2)) AS BekleyenTutar,
       MIN(l.ShipDate) AS IlkTeslimTarihi,
       SUM(CASE WHEN l.ShipDate < CAST(GETDATE() AS date) THEN 1 ELSE 0 END) AS GecikenSatir
FROM ORDR o
JOIN RDR1 l ON l.DocEntry = o.DocEntry
LEFT JOIN OCRD c ON c.CardCode = o.CardCode
WHERE o.CANCELED = 'N'
  AND l.LineStatus = 'O'
  AND l.OpenQty > 0
GROUP BY o.CardCode, c.CardName
ORDER BY BekleyenTutar DESC;

COUNT(DISTINCT o.DocEntry) satır sayısını değil sipariş sayısını verir; tek siparişte on kalem olan müşteri "10 sipariş" gibi görünmez.

5. Ürün bazında bekleyen miktar: tedarik planı

Aynı kırılımı ürün tarafından kurmak, satınalma ve üretim planına doğrudan girdi verir. Ürün adını belge satırından (Dscription) değil karttan (OITM.ItemName) almak, elle değiştirilmiş açıklamaların listeyi bölmesini engeller.

SELECT TOP 10
       l.ItemCode AS StokKod,
       i.ItemName AS StokAd,
       SUM(l.OpenQty) AS BekleyenMiktar,
       CAST(SUM(l.OpenQty * l.Price) AS decimal(18,2)) AS BekleyenTutar,
       COUNT(DISTINCT o.CardCode) AS CariSayisi
FROM ORDR o
JOIN RDR1 l ON l.DocEntry = o.DocEntry
LEFT JOIN OITM i ON i.ItemCode = l.ItemCode
WHERE o.CANCELED = 'N'
  AND l.LineStatus = 'O'
  AND l.OpenQty > 0
GROUP BY l.ItemCode, i.ItemName
ORDER BY BekleyenMiktar DESC;

6. Gecikme kovaları: tek bakışta özet

Yönetim raporu satır listesi değil özet ister. Aşağıdaki sorgu açık satırları gecikme kovalarına böler; kova adları Türkçe metin olduğu için N'...' önekiyle yazılır.

SELECT k.Kova,
       COUNT(*) AS SatirSayisi,
       SUM(k.OpenQty) AS BekleyenMiktar,
       CAST(SUM(k.Tutar) AS decimal(18,2)) AS BekleyenTutar
FROM (
    SELECT CASE
             WHEN l.ShipDate IS NULL THEN N'Tarih girilmemis'
             WHEN l.ShipDate < DATEADD(DAY, -30, CAST(GETDATE() AS date)) THEN N'30+ gun geciken'
             WHEN l.ShipDate < CAST(GETDATE() AS date) THEN N'1-30 gun geciken'
             WHEN l.ShipDate <= DATEADD(DAY, 7, CAST(GETDATE() AS date)) THEN N'Bu hafta'
             ELSE N'Sonraki haftalar'
           END AS Kova,
           l.OpenQty,
           l.OpenQty * l.Price AS Tutar
    FROM ORDR o
    JOIN RDR1 l ON l.DocEntry = o.DocEntry
    WHERE o.CANCELED = 'N'
      AND l.LineStatus = 'O'
      AND l.OpenQty > 0
) k
GROUP BY k.Kova
ORDER BY BekleyenTutar DESC;
Rapor kalemi Doğru kaynak Yaygın yanlış
Kalan miktar RDR1.OpenQty RDR1.Quantity
Açıklık RDR1.LineStatus = 'O' + OpenQty > 0 Yalnız ORDR.DocStatus = 'O'
Gecikme tarihi RDR1.ShipDate ORDR.DocDueDate
Bekleyen tutar OpenQty * Price ORDR.DocTotal

Sık yapılan hatalar

  • Sadece DocStatus = 'O' ile süzmek: başlık açıkken satırların bir kısmı kapanmış olabilir. Açıklık satır düzeyindedir, LineStatus ve OpenQty birlikte filtrelenir.
  • Kalan miktarı Quantity sanmak: Quantity sipariş miktarıdır, sevk edilen düşülmüş hali OpenQty'dir. İkisini aynı kolon gibi kullanmak miktarı şişirir.
  • DocNum ile JOIN etmek: DocNum seriye göre tekrar edebilir. Başlık ile satır daima DocEntry ile bağlanır.
  • CANCELED filtresini atlamak: iptal edilen sipariş ve onu ters çeviren iptal belgesi (CANCELED = 'C') listeye girer, bekleyen miktar olduğundan fazla görünür.
  • ShipDate boş satırları unutmak: tarih karşılaştırması NULL satırı dışarı atar. Tarihi girilmemiş siparişler gecikme listesinde görünmez, kova sorgusundaki gibi ayrı ele alınmalıdır.
  • Açık siparişi ciro saymak: sipariş satış değildir, fatura (OINV) ve iade (ORIN) üzerinden ciro hesaplanır. Sipariş raporunu ciro raporuyla toplamak çift sayma üretir.

Sık sorulanlar

Açık sipariş ile geciken sevkiyat arasındaki fark ne? Açık sipariş, henüz sevk ya da faturalanmamış kalan miktarı olan her satırdır; teslim tarihi ileride de olabilir. Geciken sevkiyat bunun alt kümesidir: ShipDate bugünden küçük ve satır hala açık. İlk rapor iş yükünü, ikincisi riski gösterir.

Kısmen sevk edilmiş sipariş neden tamamen açık görünüyor? Çünkü başlıktaki DocStatus tüm satırlar kapanınca C olur. Bir satır sevk edilip diğeri bekliyorsa başlık açık kalır. Doğru cevap satırdadır: sevk edilen miktar Quantity - OpenQty, kalan OpenQty.

Bekleyen tutar neden fatura toplamıyla tutmuyor? İki ayrı şey ölçülür. ORDR.DocTotal siparişin tamamının KDV dahil toplamıdır, OpenQty * Price ise yalnız kalan miktarın KDV hariç tutarıdır. Kısmi sevk edilmiş siparişte ikisi hiçbir zaman eşit olmaz.

Bu sorgular HANA sürümünde çalışır mı? Doğrudan çalışmaz. GETDATE, DATEDIFF, DATEADD, NULLIF gibi ifadeler ve tırnak kuralları farklıdır; tablo ve kolon adları çift tırnakla yazılır. Buradaki sorgular SQL Server sürümü içindir. Hazır sorgu kalıplarının tamamı için SAP Business One hazır SQL sorguları yazısına, açık sipariş mantığının diğer ERP'lerdeki karşılığı için Mikro açık sipariş raporu SQL yazısına bakabilirsiniz.


Her ay yeni bir rapor sorgusu yazmak yerine sorunuzu Türkçe sorabilirsiniz: Erp Asistanı SAP Business One şemanıza uygun, doğrulanmış SQL'i üretir ve açık sipariş listesini sabah raporunuza ekler. Günlük takip listesini kurmak için patronun her sabah bakması gereken 10 rapor yazısı iyi bir başlangıçtır.

Ücretsiz üye olun, açık sipariş sorgunuzu doğal dille üretin →

Bu yazıyı paylaş
SAP Business One raporlama

Bu raporu SQL yazmadan, Türkçe sorarak 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.