using Azure.Core; using Biskilog_Accounting.Server.POSModels; using Biskilog_Accounting.ServiceRepo; using Biskilog_Accounting.Shared.CustomModels; using Biskilog_Accounting.Shared.Interfaces; using Biskilog_Accounting.Shared.POSModels; using Microsoft.EntityFrameworkCore; using Microsoft.Net.Http.Headers; using System.Data.Entity; using System.Runtime.CompilerServices; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace Biskilog_Accounting.Server.Services { /// /// Gets the KPIs/ Analysis of operations made with the software /// public class AnalyticalService : IAnalytics { private readonly BiskAcdbContext m_context; private readonly ITokenService m_tokenService; private bool m_comparisonMode; private string m_activeBranch; public AnalyticalService(BiskAcdbContext a_context, ITokenService a_tokenService) { m_context = a_context; m_tokenService = a_tokenService; } public IEnumerable GetCancelledSales(DateTime a_start, DateTime a_end) { //If in comparison mode, the list is fetched from all branchid of the business if (m_comparisonMode) { return from cSale in m_context.Tblcancelledtransactions join aSale in m_context.Tblcarts on cSale.Transno equals aSale.Transno into activeSale join cPurchase in m_context.Tblcustomerpurchases on cSale.Transno equals cPurchase.TransactionId into customerSales from c in customerSales.DefaultIfEmpty() join customer in m_context.Tblcustomers on c.CustomerId equals customer.CustomerId into Customers from cc in Customers.DefaultIfEmpty() where cSale.DateCancelled >= a_start && cSale.DateCancelled <= a_end select new CancelledSales { CancelledTransaction = cSale, Value = activeSale.Sum(s => s.Total), Customer = !String.IsNullOrEmpty(cc.CustomerId) ? $"{cc.Firstname} {cc.Surname}" : "Walk-IN Purchase" }; } else { return from cSale in m_context.Tblcancelledtransactions join aSale in m_context.Tblcarts on cSale.Transno equals aSale.Transno into activeSale join cPurchase in m_context.Tblcustomerpurchases on cSale.Transno equals cPurchase.TransactionId into customerSales from c in customerSales.DefaultIfEmpty() join customer in m_context.Tblcustomers on c.CustomerId equals customer.CustomerId into Customers from cc in Customers.DefaultIfEmpty() where cSale.DateCancelled >= a_start && cSale.DateCancelled <= a_end && cSale.BranchId == m_activeBranch select new CancelledSales { CancelledTransaction = cSale, Value = (from a in activeSale where a.BranchId == m_activeBranch select a.Total).Sum(), Customer = !String.IsNullOrEmpty(cc.CustomerId) ? $"{cc.Firstname} {cc.Surname}" : "Walk-IN Purchase" }; } } public Dictionary> GetEmployeeSales(DateTime a_start, DateTime a_end) { Dictionary> sales = new Dictionary>(); if (m_comparisonMode) { var employeeSales = m_context.Tblcarts.Where(c => c.Date >= a_start && c.Date <= a_end).Select(e => e.Cashier).Distinct(); foreach (string employeeName in employeeSales) { var list = (from a in employeeSales join c in m_context.Tblcarts on a equals c.Cashier into Sales from s in Sales group s by s.Transno into saleItem select new SaleItem { Total = saleItem.Sum(c => c.Total), Transno = saleItem.Key, Cashier = employeeName, Date = saleItem.First().Date, Status = saleItem.First().Status, BranchId = saleItem.First().BranchId }).ToList(); sales.Add(employeeName, list); } } else { var employeeSales = m_context.Tblcarts.Where(c => c.Date >= a_start && c.Date <= a_end && c.BranchId == m_activeBranch).Select(e => e.Cashier).Distinct().ToList(); foreach (var employeeName in employeeSales) { var list = (from a in employeeSales join c in m_context.Tblcarts on a equals c.Cashier into Sales from s in Sales group s by s.Transno into saleItem select new SaleItem { Total = saleItem.Sum(c => c.Total), Transno = saleItem.Key, Cashier = employeeName, Date = saleItem.First().Date, Status = saleItem.First().Status, BranchId = saleItem.First().BranchId }).ToList(); sales.Add(employeeName, list); } } return sales; } public IEnumerable GetInDebtCustomers() { if (m_comparisonMode) { var listDebts = m_context.Customeraccounts.Where(t => t.Balance < 0).OrderByDescending(d => d.Date).Select(t => t.CustomerId).Distinct().ToList(); foreach (var customerId in listDebts) { yield return new InDebtCustomers { Customer = m_context.Tblcustomers.FirstOrDefault(i => i.CustomerId == customerId), Debt = m_context.Customeraccounts.OrderByDescending(d => d.Date).FirstOrDefault(t => t.Balance < 0 && t.CustomerId == customerId).Balance, }; } } else { var listDebts = m_context.Customeraccounts.Where(t => t.Balance < 0 && t.BranchId == m_activeBranch).OrderByDescending(d => d.Date).Select(t => t.CustomerId).Distinct().ToList(); foreach (var customerId in listDebts) { yield return new InDebtCustomers { Customer = m_context.Tblcustomers.FirstOrDefault(i => i.CustomerId == customerId), Debt = m_context.Customeraccounts.OrderByDescending(d => d.Date).FirstOrDefault(t => t.Balance < 0 && t.CustomerId == customerId).Balance, }; } } } public IEnumerable GetMostPurchasedItem(DateTime a_start, DateTime a_end) { var items = (from s in m_context.Tblcarts join p in m_context.Tblproducts on s.Id equals p.Pcode where s.Date >= a_start && s.Date <= a_end group s by p into g orderby g.Count() descending select new MostPurchasedItem { ProductId = g.Key.Pcode, ProductName = g.Key.ProductName, NbrTimesSold = g.Count(), Revenue = g.Sum(s => s.Price) }).Take(50).ToList(); return items; } public IEnumerable GetOutOfStockItems() { if (m_comparisonMode) { return (from item in m_context.Tblinventories join p in m_context.Tblproducts on item.Pcode equals p.Pcode join pu in m_context.Productaltunits on item.Pcode equals pu.Pcode into AltUnit from au in AltUnit.DefaultIfEmpty() join rs in m_context.Restocklevels on item.Pcode equals rs.ProductId join un in m_context.Unitofmeasures on p.BaseUnit equals un.UnitCode where p.Status!.ToLower() != "inactive" && ((rs.WarnLevel >= item.Quantity && rs.Unit == p.BaseUnit) || (rs.WarnLevel >= (item.Quantity / au.QuantityUnit) && rs.Unit == au.UnitCode) ) select new ProductItem { Product = p, Stock = item, BaseUnit = un.Unitshort! }); } else { return (from item in m_context.Tblinventories join p in m_context.Tblproducts on item.Pcode equals p.Pcode join pu in m_context.Productaltunits on item.Pcode equals pu.Pcode into AltUnit from au in AltUnit.DefaultIfEmpty() join rs in m_context.Restocklevels on item.Pcode equals rs.ProductId join un in m_context.Unitofmeasures on p.BaseUnit equals un.UnitCode where p.Status!.ToLower() != "inactive" && item.BranchId == m_activeBranch && ((rs.WarnLevel >= item.Quantity && rs.Unit == p.BaseUnit) || (rs.WarnLevel >= (item.Quantity / au.QuantityUnit) && rs.Unit == au.UnitCode) ) select new ProductItem { Product = p, Stock = item, BaseUnit = un.Unitshort! }); } //return null; } public IEnumerable GetPriceChanges(DateTime a_start, DateTime a_end) { if (m_comparisonMode) { return from change in m_context.Tblpricechanges join p in m_context.Tblproducts on change.Pcode equals p.Pcode where change.ChangeDate >= a_start && change.ChangeDate <= a_end select new ProductPriceChange { BranchId = change.BranchId, ChangeDate = change.ChangeDate, Pcode = change.Pcode, CountId = change.CountId, CurrentPrice = change.CurrentPrice, PreviousPrice = change.PreviousPrice, ProductName = p.ProductName }; } else { return from change in m_context.Tblpricechanges join p in m_context.Tblproducts on change.Pcode equals p.Pcode where change.ChangeDate >= a_start && change.ChangeDate <= a_end && change.BranchId == m_activeBranch select new ProductPriceChange { BranchId = change.BranchId, ChangeDate = change.ChangeDate, Pcode = change.Pcode, CountId = change.CountId, CurrentPrice = change.CurrentPrice, PreviousPrice = change.PreviousPrice, ProductName = p.ProductName }; } } public IEnumerable GetSalesTransaction(DateTime a_start, DateTime a_end) { //If in comparison mode, the list is fetched from all branchid of the business if (m_comparisonMode) { return m_context.Tblcarts.Where(t => t.Date >= a_start && t.Date <= a_end); } else { return m_context.Tblcarts.Where(t => t.Date >= a_start && t.Date <= a_end && t.BranchId == m_activeBranch); } } public void SetContraints(string a_token) { m_comparisonMode = m_tokenService.GetComparison(a_token)!.Value; m_activeBranch = m_tokenService.GetBaseBranch(a_token)!; } } }