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)!;
}
}
}