SAP B1 Satış Raporu SQL: OINV ve ORIN ile Net Ciro ve KDV
SAP Business One'da OINV ve ORIN ile net ciro, KDV ve iade analizi SQL sorguları: aylık-çeyreklik kırılım, KDV oranı VatPrcnt, dövizli belge notu.
Erp Asistanı
Editör ekibi
10 dk okuma
İçindekiler
SAP Business One'da satış raporu almak isteyenlerin ilk sorusu hep aynıdır: ciro hangi tablodan okunur? Cevap iki parçalıdır: satış faturası OINV, iade faturası ORIN. İkisinin farkı net ciroyu verir; irsaliye (ODLN) bu hesaba hiç girmez, çünkü faturası irsaliyeden kopyalanan bir satış iki kez sayılır. Bu yazıda CANCELED = 'N' filtresini hiç düşürmeyen, KDV tutarını belge başlığından ve satırındaki VatPrcnt üzerinden okuyan yedi SQL sorgusu var: aylık net ciro, çeyreklik kırılım, cari bazında ciro ve iade oranı, KDV oranı bazında matrah, ürün bazında net satış, dövizli belge kontrolü ve iade faturasının kaynak faturayla eşleşmesi. Tabloları ilk kez görüyorsanız önce SAP Business One tablo yapısı rehberine bakın.
Net ciro formülü: hangi tablodan ne okunur
Rapordaki üç sayı birbirine karıştırıldığında sonuç SAP ekranındaki rakamla tutmaz. Aşağıdaki tablo hangi ihtiyacın hangi kolondan karşılandığını özetler.
| İhtiyaç | Tablo | Kolon | Not |
|---|---|---|---|
| Satış faturası tutarı | OINV |
DocTotal, VatSum |
DocTotal KDV dahildir |
| İade faturası tutarı | ORIN |
DocTotal, VatSum |
satıştan düşülür |
| KDV hariç ciro | OINV / ORIN |
DocTotal - VatSum |
yerel para birimi |
| Satır bazlı matrah | INV1 / RIN1 |
LineTotal |
KDV hariç, satır iskontosu düşülmüş |
| KDV oranı | INV1 / RIN1 |
VatPrcnt |
belge anındaki oran; OVTG'den sabit oran yazmayın |
| Döviz tutarı | OINV |
DocTotalFC, DocCur, DocRate |
yalnız dövizli belgede anlamlı |
| İrsaliye | ODLN |
- | ciroya EKLENMEZ |
Net ciro = OINV toplamı eksi ORIN toplamı. Tutarlar yerel para birimindedir; belge dövizliyse DocTotal yine yerel karşılığı taşır, döviz tutarı DocTotalFC kolonundadır.
1. Aylık net ciro ve KDV
İki tabloyu UNION ALL ile alt alta koyup iade dalını negatif yazmak en okunur kalıptır. Böylece aynı GROUP BY hem satışı hem iadeyi tek geçişte toplar.
SELECT x.Yil, x.Ay,
SUM(x.KdvHaric) AS NetCiro,
SUM(x.Kdv) AS Kdv,
SUM(x.KdvDahil) AS BrutCiro
FROM (
SELECT YEAR(DocDate) AS Yil, MONTH(DocDate) AS Ay,
DocTotal - VatSum AS KdvHaric, VatSum AS Kdv, DocTotal AS KdvDahil
FROM OINV
WHERE CANCELED = 'N'
AND DocDate >= DATEADD(MONTH, -12, CAST(GETDATE() AS date))
UNION ALL
SELECT YEAR(DocDate), MONTH(DocDate),
-(DocTotal - VatSum), -VatSum, -DocTotal
FROM ORIN
WHERE CANCELED = 'N'
AND DocDate >= DATEADD(MONTH, -12, CAST(GETDATE() AS date))
) x
GROUP BY x.Yil, x.Ay
ORDER BY x.Yil, x.Ay;
Rapor tarihi DocDate kolonudur. Vergi tarihine göre rapor isteniyorsa aynı sorguda TaxDate kullanılır; iki tarih farklı aylara düşebilir, bu yüzden SAP ekranıyla fark çıkarsa ilk bakılacak yer burasıdır.
2. Çeyreklik kırılım
Aynı kalıbın çeyrek versiyonu DATEPART(QUARTER, ...) ile kurulur ve yönetim sunumlarında aylık dalgalanmayı yumuşatır.
SELECT YEAR(x.DocDate) AS Yil,
DATEPART(QUARTER, x.DocDate) AS Ceyrek,
SUM(x.KdvHaric) AS NetCiro,
SUM(x.Kdv) AS Kdv
FROM (
SELECT DocDate, DocTotal - VatSum AS KdvHaric, VatSum AS Kdv
FROM OINV
WHERE CANCELED = 'N'
UNION ALL
SELECT DocDate, -(DocTotal - VatSum), -VatSum
FROM ORIN
WHERE CANCELED = 'N'
) x
GROUP BY YEAR(x.DocDate), DATEPART(QUARTER, x.DocDate)
ORDER BY Yil, Ceyrek;
3. Cari bazında net ciro ve iade oranı
Satış ve iadeyi ayrı kolonlarda göstermek, iadeyi sürekli yapan müşteriyi ciro sıralamasında yanlış okumayı engeller.
SELECT s.CardCode AS CariKod,
c.CardName AS CariAd,
SUM(s.Satis) AS SatisKdvHaric,
SUM(s.Iade) AS IadeKdvHaric,
SUM(s.Satis + s.Iade) AS NetCiro,
SUM(s.Kdv) AS Kdv
FROM (
SELECT CardCode, DocTotal - VatSum AS Satis, 0 AS Iade, VatSum AS Kdv
FROM OINV
WHERE CANCELED = 'N'
AND DocDate >= DATEFROMPARTS(YEAR(GETDATE()), 1, 1)
UNION ALL
SELECT CardCode, 0, DocTotal - VatSum, -VatSum
FROM ORIN
WHERE CANCELED = 'N'
AND DocDate >= DATEFROMPARTS(YEAR(GETDATE()), 1, 1)
) s
JOIN OCRD c ON c.CardCode = s.CardCode
GROUP BY s.CardCode, c.CardName
ORDER BY NetCiro DESC;
Cari adını belgedeki CardName kopyasından değil OCRD kartından okuyoruz; unvan sonradan değiştiyse belgedeki kopya eski kalır ve aynı müşteri iki satıra bölünür.
4. KDV oranı bazında matrah ve KDV
KDV kırılımını belge başlığından üretmek mümkün değildir; başlıkta yalnız toplam VatSum vardır. Oran kırılımı için satıra (INV1, RIN1) inmek ve oranı VatPrcnt kolonundan okumak gerekir.
| Okuma yeri | Kolon | Ne verir |
|---|---|---|
| Belge başlığı | OINV.DocTotal, OINV.VatSum |
belge geneli; başlık iskontosu düşülmüş |
| Belge satırı | INV1.LineTotal, INV1.VatPrcnt |
satır bazlı matrah ve oran; başlık iskontosu satıra yansımaz |
SELECT l.VatGroup AS KdvKodu,
l.VatPrcnt AS KdvOrani,
SUM(l.LineTotal) AS Matrah,
SUM(l.VatSum) AS KdvTutar
FROM (
SELECT i.VatGroup, i.VatPrcnt, i.LineTotal, i.VatSum
FROM INV1 i
JOIN OINV f ON f.DocEntry = i.DocEntry
WHERE f.CANCELED = 'N'
UNION ALL
SELECT r.VatGroup, r.VatPrcnt, -r.LineTotal, -r.VatSum
FROM RIN1 r
JOIN ORIN n ON n.DocEntry = r.DocEntry
WHERE n.CANCELED = 'N'
) l
GROUP BY l.VatGroup, l.VatPrcnt
ORDER BY l.VatPrcnt;
Burada OVTG tablosundan sabit bir oran yazmak en sık yapılan hatadır: oran belge kesildiği andaki değeriyle satırda saklanır, OVTG'de sonradan değişmiş olabilir. Tarihsel rapor için doğru kaynak satırdaki VatPrcnt kolonudur.
5. Ürün bazında net satış (son 12 ay)
SELECT s.ItemCode AS StokKod,
i.ItemName AS StokAd,
SUM(s.Miktar) AS NetMiktar,
SUM(s.Net) AS NetCiro,
SUM(s.Kdv) AS Kdv
FROM (
SELECT l.ItemCode, l.Quantity AS Miktar, l.LineTotal AS Net, l.VatSum AS Kdv
FROM INV1 l
JOIN OINV f ON f.DocEntry = l.DocEntry
WHERE f.CANCELED = 'N'
AND f.DocDate >= DATEADD(MONTH, -12, CAST(GETDATE() AS date))
UNION ALL
SELECT r.ItemCode, -r.Quantity, -r.LineTotal, -r.VatSum
FROM RIN1 r
JOIN ORIN n ON n.DocEntry = r.DocEntry
WHERE n.CANCELED = 'N'
AND n.DocDate >= DATEADD(MONTH, -12, CAST(GETDATE() AS date))
) s
JOIN OITM i ON i.ItemCode = s.ItemCode
GROUP BY s.ItemCode, i.ItemName
ORDER BY NetCiro DESC;
Ürün adını satırdaki Dscription yerine karttan (OITM.ItemName) alıyoruz: satır açıklaması belgede elle değiştirilmişse aynı ürün raporda iki satıra bölünür.
6. Dövizli belgelerde ciro karşılaştırması
DocTotal her zaman yerel para karşılığıdır. Dövizle kesilen faturaları ayırmak için para birimi kolonuna bakın.
SELECT f.DocNum AS FaturaNo,
f.CardCode AS CariKod,
f.DocCur AS ParaBirimi,
f.DocRate AS Kur,
f.DocTotal - f.VatSum AS YerelKdvHaric,
f.DocTotalFC AS DovizKdvDahil
FROM OINV f
WHERE f.CANCELED = 'N'
AND f.DocCur <> N'TRY'
ORDER BY f.DocDate DESC;
Yerel para kodunuz kurulumda farklı yazılmışsa (bazı şirketlerde kısaltma değişebilir) N'TRY' değerini güncelleyin. DocTotalFC döviz toplamı, DocRate belge kuru, DocCur belge para birimidir.
7. İade faturası hangi faturayı düzeltiyor?
İade satırları kaynak faturaya BaseType = 13 ve BaseEntry ile bağlanır. Bu bağ, hangi faturanın ne kadar geri döndüğünü gösterir.
SELECT r.DocNum AS IadeNo,
r.DocDate AS Tarih,
r.CardCode AS CariKod,
c.CardName AS CariAd,
r.DocTotal - r.VatSum AS IadeKdvHaric,
r.VatSum AS IadeKdv,
MAX(f.DocNum) AS KaynakFaturaNo
FROM ORIN r
JOIN OCRD c ON c.CardCode = r.CardCode
LEFT JOIN RIN1 rl ON rl.DocEntry = r.DocEntry AND rl.BaseType = 13
LEFT JOIN OINV f ON f.DocEntry = rl.BaseEntry
WHERE r.CANCELED = 'N'
GROUP BY r.DocNum, r.DocDate, r.CardCode, c.CardName, r.DocTotal, r.VatSum
ORDER BY r.DocDate DESC;
İade irsaliyesi (ORDN) ayrı bir belgedir ve ciro hesabına girmez; cirodan düşen belge ORIN iade faturasıdır. Demo şirketlerde iade tabloları boş olabilir, bu sorgunun iade dalının gereksiz olduğu anlamına gelmez.
Sık yapılan hatalar
- İrsaliyeyi ciroya eklemek:
ODLNsatışa eklenirse faturası kesilmiş sevkiyatlar iki kez sayılır. Kaynak daimaOINVeksiORIN. DocTotal'ı KDV hariç sanmak:DocTotalKDV dahildir; KDV hariç tutarDocTotal - VatSumile bulunur.- KDV oranını
OVTG'den yazmak: oran satırdaVatPrcntolarak saklanır,OVTGgüncel değer taşır ve tarihsel raporu bozar. - Başlık iskontosunu satırda aramak:
OINV.DiscPrcntsatırlara yansımaz; bu yüzdenSUM(LineTotal)ileDocTotal - VatSumbazen eşit çıkmaz. Belge toplamı için başlık, kalem kırılımı için satır okunur. CANCELEDfiltresini unutmak: iptal edilen belge ile onu ters çeviren iptal belgesi birlikte toplanınca tutar ikiye katlanır.- JOIN'i
DocNumile kurmak: belge numarası seriye göre tekrar edebilir; bağlama daimaDocEntryile yapılır. - Türkçe metni
Nöneksiz aramak:LIKE N'%...%'kullanın, aksi halde ş, ğ, İ harfleri sessizce bozulur.
Sık sorulanlar
Net ciro ile brüt ciro arasındaki fark nedir? Brüt ciro OINV toplamıdır, iade düşülmemiştir. Net ciro aynı toplamdan ORIN tutarının çıkarılmasıyla bulunur. İkisini aynı raporda ayrı kolonlarda göstermek, iade oranı yüksek müşteriyi erken fark etmeyi sağlar.
Ciro raporum SAP ekranındaki rakamla tutmuyor, nereden başlamalıyım? Sırayla şu üçünü kontrol edin: iadeler (ORIN) düşülüyor mu, DocTotal ile DocTotal - VatSum karıştırılmış mı, CANCELED = 'N' filtresi var mı. Dördüncü olasılık tarih seçimidir; SAP bazı raporlarda DocDate yerine TaxDate kullanır.
Satırdaki VatPrcnt boş ya da sıfır görünüyor, neden? Hizmet belgelerinde (DocType = 'S') satırda mal kodu yerine hesap kodu bulunur ve KDV bilgisi tanıma göre değişebilir. Ayrıca KDV istisnası uygulanan satırlarda oran sıfır olabilir; bu satırları VatGroup kolonuyla ayrı okuyup rapora not düşmek gerekir.
Bu sorgular HANA sürümünde de çalışır mı? Hayır. Buradaki sorgular SQL Server (T-SQL) sözdizimiyle yazıldı; DATEADD, DATEFROMPARTS ve DATEPART çağrıları HANA'da karşılıksızdır ve tablo adları çift tırnakla yazılır. HANA tarafında sorguların uyarlanması gerekir.
Bu yedi sorgu satış raporunuzun çekirdeğini kurar: OINV eksi ORIN ile net ciro, satırdaki VatPrcnt ile KDV kırılımı, DocCur ile döviz kontrolü. Bakiyeyi ve vade tarafını da eklemek isterseniz SAP Business One cari bakiye ve yaşlandırma SQL yazısı JDT1 tarafını anlatıyor; daha fazla kopyala-çalıştır örnek için SAP Business One hazır SQL sorguları listesine bakabilirsiniz.
Sorguyu her rapor için elle uyarlamak yerine sorunuzu Türkçe yazabilirsiniz: Erp Asistanı SAP Business One şemanıza uygun, doğrulanmış SQL'i saniyeler içinde üretir.
SAP Business One'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.
