Sambapos içerisinde bulunan gün sonu raporunu sql olarak almak mümkün müdür acaba? Forum sayfalarinda konu ile ilgili tam gün sonu raporunu alabileceğim bir alan bulamadım ne yazikki
sanki kendi kendime cevap vermiş gibi olacak ama belki başkalarına faydalı olur diye uğraş çabala geliştirdiğim sql gün sonu raparunda neler ver aşağıda paylaşıyorum
SambaPOS “Gün Sonu Raporu” (End of Day) Detaylı Açıklaması
Bu SQL raporu, hiçbir ara yazılıma ihtiyaç duymadan doğrudan MS SQL veritabanı üzerinde çalıştırır.
SQL komut dosyamız (script), raporu 10 Ana Bölüm üzerinden kategorize edip, tüm kalemleri Adisyon Tiplerine (TicketType) göre sınıflandırarak çalışmaktadır:
[!NOTE]
Tüm filtrelemeler, ödemesi gün aşırı bile olsa o gün sonu kapanışına doğru yansımasını sağlamak üzere SambaPOS’un asıl standartı olanLastPaymentDateparametresi ve “Aktif (Açık)” çalışma dönemi verilerine göre yapılmaktadır.
BÖLÜM 1: Adisyon Tipine Göre Satışlar
SambaPOS Karşılığı: Genel Satış Özeti
- Yaptığı İşlem: Belirtilen tarihteki başarılı (
CalculatePrice = 1yani fiyata dahil) siparişleri tarar. - Detay: Bu bölüm, satış işlemlerini “Paket Servis” veya “Adisyon” gibi tiplere ayırır. Her bir adisyon tipindeki Brüt Satışları, uygulanan İskonto Miktarını (
Calculationstablosundaki kesintileri) yakalayıp Net Satışlarınızı hatasız gösterir.
BÖLÜM 1.1: Adisyon Tipine Göre İadeler
SambaPOS Karşılığı: İade Özeti (Satışlar’ın Alt Kategorisi)
- Yaptığı İşlem: Geri alınmış veya “İade” olarak işaretlenmiş, hesaba dahil olmayan (
CalculatePrice = 0) sipariş gruplarını hesaplar. Tutarın brüt kasadan eksilecek kısmını yansıtır.
BÖLÜM 2: Gelirler (Tahsilatlar)
- Yaptığı İşlem: Gerçekleşmiş Nakit, Kredi Kartı, Yemek Çeki gibi tüm adisyon ödemelerini (Kasaya giren parayı) gruplar.
- Detay: Toplam net satışlarınızla bu bölümdeki tahsilatların birbirini tutması kasanızın doğru verdiğini gösterir.
BÖLÜM 3: İade Ödemeleri (Refunds)
- Yaptığı İşlem: Kasadan para çıkışı yapılarak müşteriye fiilen iade edilmiş (
Amount < 0) ödemeleri takip eder.
BÖLÜM 4: Genel Bilgi
SambaPOS Karşılığı: General Information
- Yaptığı İşlem: Satışların maliyetinden ziyade metrik performansını gösterir.
- Detay: Açılan toplam adisyonları, satılan toplam porsiyon sayısını (Sipariş Kalemi) ve bir masanın (adisyonun) ortalama kaç TL’lik harcama yaptığını (“Satış/Adisyon (Ortalama)”) gösterir.
BÖLÜM 5: İskonto ve Hesaplamalar
SambaPOS Karşılığı: Hesaplamalar / Yuvarlamalar
- Yaptığı İşlem: Kasa toplamını etkileyen indirimleri, kupon değerlerini, sisteme işlenmiş ekstra komisyon ya da servis ücretlerini (örneğin %10 İskonto) sayısıyla beraber net olarak yansıtır.
BÖLÜM 6: Garson / Kullanıcı Satışları
SambaPOS Karşılığı: User Sales (Sorumlu Satışları)
- Yaptığı İşlem: Personelinizin bireysel satış gücünü ve getirdikleri ciroyu hesaplar.
- Detay: İkram ve iadeler hariç tutularak, garsonunuzun fiilen faturaya yansıttığı tüm satırların “Sipariş Sayısı” ve “Toplam Tutarını” oluşturur. Personel primi hesaplamasında kullanılır.
BÖLÜM 7 & BÖLÜM 7.1: Garson İadeleri (Genel ve Detay)
SambaPOS Karşılığı: User Returns
- Yaptığı İşlem: Hangi garsonun gün içinde ne kadarlık iade aldığı tespit edilir (Bölüm 7).
- Detay (Bölüm 7.1): Özellikle sizin isteğiniz doğrultusunda eklenen kısımdır. Hangi garsonun tam olarak hangi ürünü, kaç adet iade aldığını kalem kalem açıklar. Gelişmiş güvenlik takibi sağlar.
BÖLÜM 8: Ürün Grubu (Departman/Kategori) Satışları
SambaPOS Karşılığı: Item Sales / Menu Groups
- Yaptığı İşlem: Yüksek Alkol Kadehler, Evrensel Kokteyller, Burgerler gibi menü departmanlarını tarar.
- Detay: Hangi menü kategorisinden toplam kaç porsiyon satıldığını ve ne kadarlık ciro getirdiğini detaylandırır. Stok/Alım planlamasında hayat kurtarır.
BÖLÜM 9: Adisyon Etiketleri (Ticket Tags)
SambaPOS Karşılığı: Ticket Tags / Etiket Ciro Takibi
- Yaptığı İşlem: JSON formatında gizlenip kaydedilmiş “qrsifreli”, “Müşteri İsmi”, “Teslimatçi Kurye” gibi etiketlerinizin SQL üzerinden kırılarak analiz edilmesidir. Hangi müşterinizin ya da etiketinizin ne kadar ciro oluşturduğuna tek bir yerden varmanızı sağlar.
-- ============================================================
-- SAMBAPOS - GÜN SONU RAPORU
-- GitHub Kaynak Koduna Göre Uyumlu Hale Getirilmiştir
-- ============================================================
USE VERİTABANI ADI;
GO
-- ─────────────────────────────────────────────────────────────
-- TARİH ARALIĞINI BELİRLE (SambaPOS C# Koduna Göre)
-- WorkPeriod.EndDate = StartDate ise (açık) → Bitiş ZAMANINI Şimdi al
-- ─────────────────────────────────────────────────────────────
DECLARE @WorkPeriodId INT;
DECLARE @WP_StartDate DATETIME;
DECLARE @WP_EndDate DATETIME;
DECLARE @StartDate DATETIME;
DECLARE @EndDate DATETIME;
SET @WorkPeriodId = (SELECT MAX(Id) FROM WorkPeriods);
SET @WP_StartDate = (SELECT StartDate FROM WorkPeriods WHERE Id = @WorkPeriodId);
SET @WP_EndDate = (SELECT EndDate FROM WorkPeriods WHERE Id = @WorkPeriodId);
SET @StartDate = @WP_StartDate;
-- SambaPOS 3 ReportContext.cs mantığı: Eger StartDate == EndDate ise donem aciktir, rapor "Şimdi"ye kadar çekilir
SET @EndDate = CASE
WHEN @WP_EndDate IS NULL OR @WP_EndDate = @WP_StartDate
THEN GETDATE()
ELSE @WP_EndDate
END;
PRINT '============================================================';
PRINT 'SAMBAPOS 3 GÜN SONU RAPORU (KAYNAK KOD BİREBİR UYUMLU)';
PRINT 'İş Günü ID : ' + ISNULL(CAST(@WorkPeriodId AS VARCHAR), '-');
PRINT 'Başlangıç : ' + CONVERT(VARCHAR, @StartDate, 120);
PRINT 'Bitiş : ' + CONVERT(VARCHAR, @EndDate, 120);
PRINT '============================================================';
-- Bazı tablolardaki veri filtrelemesi SambaPOS 3 kaynak kodundaki gibi "LastPaymentDate" uzerinden yapilir.
PRINT '';
PRINT '--- BÖLÜM 1: ADİSYON TİPİNE GÖRE SATIŞLAR ---';
WITH TicketTotals AS (
SELECT
t.Id AS TicketId,
t.TicketTypeId,
(SELECT ISNULL(SUM(o.Price * o.Quantity), 0)
FROM Orders o
WHERE o.TicketId = t.Id AND o.CalculatePrice = 1) AS BrutTutar,
(SELECT ABS(ISNULL(SUM(c.CalculationAmount), 0))
FROM Calculations c
WHERE c.TicketId = t.Id AND c.DecreaseAmount = 1) AS IskontoTutar
FROM Tickets t
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
)
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
COUNT(DISTINCT t.TicketId) AS AdisyonSayisi,
ISNULL(SUM(t.BrutTutar), 0) AS BrutTutar,
ISNULL(SUM(t.IskontoTutar), 0) AS IskontoMiktari,
ISNULL(SUM(t.BrutTutar), 0) - ISNULL(SUM(t.IskontoTutar), 0) AS NetTutar
FROM TicketTotals t
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.BrutTutar > 0
GROUP BY tt.Name
ORDER BY tt.Name;
PRINT '';
PRINT '--- BÖLÜM 1.1: ADİSYON TİPİNE GÖRE İADELER ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
COUNT(DISTINCT t.Id) AS AdisyonSayisi,
ISNULL(SUM(o.Price * o.Quantity), 0) AS ToplamTutar
FROM Orders o
INNER JOIN Tickets t ON t.Id = o.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND o.OrderStates LIKE '%ade%' AND o.CalculatePrice = 0
GROUP BY tt.Name
ORDER BY tt.Name;
PRINT '';
PRINT '--- BÖLÜM 2: GELİRLER (INCOMES) ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(p.Name, 'Tanımsız Ödeme') AS OdemeTipi,
COUNT(p.Id) AS IslemSayisi,
ISNULL(SUM(p.Amount), 0) AS ToplamTutar
FROM Payments p
INNER JOIN Tickets t ON t.Id = p.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND p.Amount >= 0
GROUP BY tt.Name, p.Name
ORDER BY tt.Name, ToplamTutar DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Gelir Kaydi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 3: İADE ÖDEMELERİ (REFUNDS) ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(p.Name, 'Tanımsız Ödeme') AS OdemeTipi,
COUNT(p.Id) AS IslemSayisi,
ISNULL(SUM(p.Amount), 0) AS ToplamTutar
FROM Payments p
INNER JOIN Tickets t ON t.Id = p.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND p.Amount < 0
GROUP BY tt.Name, p.Name
ORDER BY tt.Name, ToplamTutar DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Iade Kaydi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 4: GENEL BİLGİ (GENERAL INFORMATION) ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
'Toplam Sipariş Kalemi' AS Bilgi,
CAST(COUNT(o.Id) AS VARCHAR) AS Deger
FROM Orders o
INNER JOIN Tickets t ON t.Id = o.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
GROUP BY tt.Name
UNION ALL
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
'Toplam Adisyon Sayısı' AS Bilgi,
CAST(COUNT(t.Id) AS VARCHAR) AS Deger
FROM Tickets t
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
GROUP BY tt.Name
UNION ALL
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
'Satış / Adisyon (Ortalama)' AS Bilgi,
CAST(CASE WHEN COUNT(t.Id) > 0 THEN ROUND(SUM(t.TotalAmount)/COUNT(t.Id), 2) ELSE 0 END AS VARCHAR) AS Deger
FROM Tickets t
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
GROUP BY tt.Name;
PRINT '';
PRINT '--- BÖLÜM 5: İSKONTO VE HESAPLAMALAR ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
c.Name AS HesaplamaAdi,
COUNT(c.Id) AS Adet,
ISNULL(SUM(c.CalculationAmount), 0) AS ToplamTutar
FROM Calculations c
INNER JOIN Tickets t ON t.Id = c.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
GROUP BY tt.Name, c.Name
ORDER BY tt.Name, ToplamTutar DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Hesaplama (Iskonto/Ikram) Kaydi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 6: GARSON / KULLANICI SATIŞLARI ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(o.CreatingUserName, 'Tanımsız') AS Garson,
COUNT(o.Id) AS SiparisGirdisi,
ISNULL(SUM(o.Price * o.Quantity), 0) AS SatisToplami
FROM Orders o
INNER JOIN Tickets t ON t.Id = o.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND o.CalculatePrice = 1
GROUP BY tt.Name, o.CreatingUserName
ORDER BY tt.Name, SatisToplami DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Garson Satisi Kaydi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 7: GARSON İADELERİ ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(o.CreatingUserName, 'Tanımsız') AS Garson,
COUNT(o.Id) AS IadeAdedi,
ISNULL(SUM(o.Price * o.Quantity), 0) AS IadeToplami
FROM Orders o
INNER JOIN Tickets t ON t.Id = o.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND o.OrderStates LIKE '%ade%' AND o.CalculatePrice = 0
GROUP BY tt.Name, o.CreatingUserName
ORDER BY tt.Name, IadeToplami ASC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Garson Iadesi Kaydi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 7.1: İADE EDİLEN ÜRÜNLER (DETAY) ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(o.CreatingUserName, 'Tanımsız') AS Garson,
ISNULL(o.MenuItemName, 'Tanımsız') AS UrunAdi,
SUM(o.Quantity) AS Adet,
ISNULL(SUM(o.Price * o.Quantity), 0) AS IadeToplami
FROM Orders o
INNER JOIN Tickets t ON t.Id = o.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND o.OrderStates LIKE '%ade%' AND o.CalculatePrice = 0
GROUP BY tt.Name, o.CreatingUserName, o.MenuItemName
ORDER BY tt.Name, IadeToplami DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Iade Edilen Urun Detayi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 8: ÜRÜN GRUBU (DEPARTMAN/KATEGORİ) SATIŞLARI ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(m.GroupCode, 'Tanımsız Kategori') AS UrunGrubu,
SUM(o.Quantity) AS ToplamPorsiyon,
ISNULL(SUM(o.Price * o.Quantity), 0) AS ToplamTutar
FROM Orders o
INNER JOIN Tickets t ON t.Id = o.TicketId
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
LEFT JOIN MenuItems m ON m.Id = o.MenuItemId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND o.CalculatePrice = 1
GROUP BY tt.Name, m.GroupCode
ORDER BY tt.Name, ToplamTutar DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Grup Satisi Kaydi Bulunamadi.';
PRINT '';
PRINT '--- BÖLÜM 9: ADİSYON ETİKETLERİ (TICKET TAGS) ---';
SELECT
ISNULL(tt.Name, 'Tanımsız') AS AdisyonTipi,
ISNULL(JSON_VALUE(value, '$.TN'), 'Tanımsız Etiket') AS EtiketTipi,
ISNULL(JSON_VALUE(value, '$.TV'), 'Tanımsız Değer') AS EtiketDegeri,
COUNT(t.Id) AS AdisyonSayisi,
ISNULL(SUM(t.TotalAmount), 0) AS ToplamTutar
FROM Tickets t
CROSS APPLY OPENJSON(t.TicketTags)
LEFT JOIN TicketTypes tt ON tt.Id = t.TicketTypeId
WHERE t.LastPaymentDate >= @StartDate AND t.LastPaymentDate <= @EndDate
AND t.TicketTags IS NOT NULL AND t.TicketTags != '' AND t.TicketTags != '[]'
GROUP BY tt.Name, JSON_VALUE(value, '$.TN'), JSON_VALUE(value, '$.TV')
ORDER BY tt.Name, EtiketTipi, ToplamTutar DESC;
IF @@ROWCOUNT = 0 PRINT 'Bu Donemde Adisyon Etiketi Kaydi Bulunamadi.';
GO