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
{
/// <summary>
/// Gets the KPIs/ Analysis of operations made with the software
/// </summary>
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 < CancelledSales > 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 < string , List < SaleItem > > GetEmployeeSales ( DateTime a_start , DateTime a_end )
{
Dictionary < string , List < SaleItem > > sales = new Dictionary < string , List < SaleItem > > ( ) ;
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 < InDebtCustomers > 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 < MostPurchasedItem > 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 ( 5 0 ) . ToList ( ) ;
return items ;
}
public IEnumerable < ProductItem > 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 < ProductPriceChange > 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 < Tblcart > 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 ) ! ;
}
}
}