using System; using System.Collections.Generic; using Tanshu.Accounts.Contracts; using Tanshu.Accounts.Entities; using Tanshu.Common; using Tanshu.Common.Helpers; using System.Linq; using NHibernate.Transform; using NHibernate.Criterion; namespace Tanshu.Accounts.Repository { public class SalesAnalysisBI { public IList GetSaleDetail(DateTime startDate, DateTime finishDate) { startDate = startDate.Date.AddHours(6); finishDate = finishDate.Date.AddDays(1).AddHours(5); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { #region Sale var query = @" select concat(p.Name, ' ', p.Units) as Product, Sum(i.Quantity) as Amount from Voucher v inner join v.Kots k inner join k.Inventories i inner join i.Product p where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff) group by concat(p.Name, ' ', p.Units), p.ProductGroup order by p.ProductGroup, concat(p.Name, ' ', p.Units) "; var list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .SetParameter("unsettled", SettleOption.Unsettled) .SetParameter("amount", SettleOption.Amount) .SetParameter("roundoff", SettleOption.RoundOff) .SetParameter("staff", SettleOption.Staff) .List(); var outList = new OrderedDictionary(); foreach (var item in list) outList.Add((string)item[0], new SalesAnalysisDetail() { Product = (string)item[0], Sale = (decimal)item[1] }); #endregion #region NC query = @" select concat(p.Name, ' ', p.Units) as Product, Sum(i.Quantity) as Amount from Voucher v inner join v.Kots k inner join k.Inventories i inner join i.Product p where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled = :noCharge) group by concat(p.Name, ' ', p.Units), p.ProductGroup order by p.ProductGroup, concat(p.Name, ' ', p.Units) "; list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .List(); foreach (var item in list) if (outList.ContainsKey((string)item[0])) outList[(string)item[0]].NC = (decimal)item[1]; else outList.Add((string)item[0], new SalesAnalysisDetail() { Product = (string)item[0], NC = (decimal)item[1] }); #endregion #region Staff query = @" select concat(p.Name, ' ', p.Units) as Product, Sum(i.Quantity) as Amount from Voucher v inner join v.Kots k inner join k.Inventories i inner join i.Product p where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled = :staff) group by concat(p.Name, ' ', p.Units), p.ProductGroup order by p.ProductGroup, concat(p.Name, ' ', p.Units) "; list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("staff", SettleOption.Staff) .List(); foreach (var item in list) if (outList.ContainsKey((string)item[0])) outList[(string)item[0]].Staff = (decimal)item[1]; else outList.Add((string)item[0], new SalesAnalysisDetail() { Product = (string)item[0], Staff = (decimal)item[1] }); #endregion return outList.Values.ToList(); } } public IList GetSale(DateTime startDate, DateTime finishDate) { startDate = startDate.Date.AddHours(6); finishDate = finishDate.Date.AddDays(1).AddHours(5); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { const string query = @" select g.GroupType as GroupType, Sum(i.Quantity * i.Price * (1 - i.Discount)) as Amount from Voucher v inner join v.Kots k inner join k.Inventories i inner join i.Product p inner join p.ProductGroup g where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff) group by g.GroupType order by g.GroupType "; var list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .SetParameter("unsettled", SettleOption.Unsettled) .SetParameter("amount", SettleOption.Amount) .SetParameter("roundoff", SettleOption.RoundOff) .SetParameter("staff", SettleOption.Staff) .List(); var outList = new List(); decimal amount = 0; foreach (var item in list) { amount += (decimal)item[1]; outList.Add(new SalesAnalysis() { GroupType = (string)item[0], Amount = (decimal)item[1] }); } outList.Add(new SalesAnalysis() { GroupType = "Total Settled", Amount = amount }); return GetSettlement(outList, startDate, finishDate); } } public IList GetBillDetails(DateTime startDate, DateTime finishDate) { startDate = startDate.Date.AddHours(6); finishDate = finishDate.Date.AddDays(1).AddHours(5); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { Voucher vAlias = null; VoucherSettlement vsAlias = null; var list = session.QueryOver(() => vAlias) .Left.JoinAlias(x => x.Settlements, () => vsAlias) .Where(x => x.Date >= startDate && x.Date <= finishDate) .OrderBy(x => x.VoucherType).Asc .ThenBy(x => x.BillID).Asc .TransformUsing(Transformers.DistinctRootEntity) .List(); var outList = new List(); foreach (var item in list) { if (item.Void) outList.Add(new BillDetail() { Date = item.Date, BillID = item.FullBillID, Settlement = string.Format("Void: {0}", item.VoidReason), Amount = Math.Round(item.Settlements.Single(x => x.Settled == SettleOption.Amount).Amount * -1, 2) }); else { foreach (var so in item.Settlements.Where(x => x.Settled.Visible())) { outList.Add(new BillDetail() { Date = item.Date, BillID = item.FullBillID, Settlement = so.Settled.Display(), Amount = Math.Round(so.Amount, 2) }); } } } return outList; } } public IList DiscountReport(DateTime startDate, DateTime finishDate) { startDate = startDate.Date.AddHours(6); finishDate = finishDate.Date.AddDays(1).AddHours(5); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { const string query = @" select pg.GroupType, sum(i.Quantity * i.Price * i.Discount) from Inventory i inner join i.Kot k inner join k.Voucher v inner join i.Product p inner join p.ProductGroup pg where v.Date >= :startDate and v.Date <= :finishDate and i.Discount != 0 and v not in (select Voucher from VoucherSettlement vs where vs.Voucher = v and (vs.Settled = :noCharge or vs.Settled = :staff)) group by pg.GroupType order by pg.GroupType "; var list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .SetParameter("staff", SettleOption.Staff) .List(); return list.Select(item => new SalesAnalysis() { GroupType = (string)item[0], Amount = (decimal)item[1] }).ToList(); } } public IList VoidOrReprintedBillsList(DateTime startDate, DateTime finishDate) { startDate = startDate.Date.AddHours(6); finishDate = finishDate.Date.AddDays(1).AddHours(5); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { Voucher vAlias = null; VoucherSettlement vsAlias = null; ICriterion amount = Restrictions.Where(x => x.Settled == SettleOption.Amount); var listVoids = session.QueryOver(() => vAlias) .Left.JoinAlias(x => x.Settlements, () => vsAlias, amount) .Where(x => x.Date >= startDate && x.Date <= finishDate && x.Void == true) .OrderBy(x => x.VoucherType).Asc .ThenBy(x => x.BillID).Asc .TransformUsing(Transformers.DistinctRootEntity) .List(); var outList = new List(); foreach (var item in listVoids) { outList.Add(new BillDetail() { Date = item.Date, BillID = item.FullBillID, Settlement = string.Format("Void: {0}", item.VoidReason), Amount = Math.Round(item.Settlements.SingleOrDefault().Amount * -1, 2) }); } var listReprint = session.QueryOver() .Where(x => x.Date >= startDate && x.Date <= finishDate) .List(); foreach (var item in listReprint) { outList.Add(new BillDetail() { Date = item.Date, BillID = item.Voucher.FullBillID, Settlement = string.Format("Reprinted by {0}", item.User.Name), Amount = item.Voucher.Settlements.Single(x => x.Settled == SettleOption.Amount).Amount * -1 }); } return outList; } } private static IList GetSettlement(IList outList, DateTime startDate, DateTime finishDate) { outList.Add(new SalesAnalysis() { GroupType = " -- ", Amount = 0 }); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { const string query = @" select s.Settled, Sum(s.Amount) from Voucher v inner join v.Settlements s where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false group by s.Settled order by s.Settled "; var list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .List(); decimal amount = 0; foreach (var item in list) { amount += (decimal)item[1]; outList.Add(new SalesAnalysis() { GroupType = ((SettleOption)item[0]).Display(), Amount = (decimal)item[1] }); } outList.Add(new SalesAnalysis() { GroupType = "Total", Amount = amount }); return GetOtherDetails(outList, startDate, finishDate); } } private static IList GetOtherDetails(IList outList, DateTime startDate, DateTime finishDate) { outList.Add(new SalesAnalysis() { GroupType = " -- ", Amount = 0 }); if (finishDate <= startDate) return new List(); using (var session = SessionManager.Session) { #region Service Charge var query = @" select Sum(i.Quantity * i.Price * (1 - i.Discount) * i.ServiceCharge) from Voucher v inner join v.Kots k inner join k.Inventories i where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff) "; var amt = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .SetParameter("unsettled", SettleOption.Unsettled) .SetParameter("amount", SettleOption.Amount) .SetParameter("roundoff", SettleOption.RoundOff) .SetParameter("staff", SettleOption.Staff) .UniqueResult() ?? 0M; outList.Add(new SalesAnalysis() { GroupType = "Service Charge", Amount = (decimal)amt }); #endregion #region Service Tax query = @" select Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.ServiceTaxRate) from Voucher v inner join v.Kots k inner join k.Inventories i where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff) "; amt = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .SetParameter("unsettled", SettleOption.Unsettled) .SetParameter("amount", SettleOption.Amount) .SetParameter("roundoff", SettleOption.RoundOff) .SetParameter("staff", SettleOption.Staff) .UniqueResult() ?? 0M; outList.Add(new SalesAnalysis() { GroupType = "Service Tax", Amount = (decimal)amt }); #endregion #region Vat query = @" select i.VatRate, Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.VatRate) from Voucher v inner join v.Kots k inner join k.Inventories i where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff) group by i.VatRate "; var list = session .CreateQuery(query) .SetParameter("startDate", startDate) .SetParameter("finishDate", finishDate) .SetParameter("noCharge", SettleOption.NoCharge) .SetParameter("unsettled", SettleOption.Unsettled) .SetParameter("amount", SettleOption.Amount) .SetParameter("roundoff", SettleOption.RoundOff) .SetParameter("staff", SettleOption.Staff) .List(); foreach (var item in list) outList.Add(new SalesAnalysis() { GroupType = string.Format("Tax {0:P}", (decimal)item[0]), Amount = (decimal)item[1] }); #endregion return outList; } } } }