New source control repo for Biskilog POS - secure hub to store & manage source code. Streamlines dev process, tracks changes, & improves collaboration. Ensures reliable software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

388 lines
18 KiB

using Biskilog_Accounting.Server.POSModels;
using Biskilog_Accounting.Shared.CustomModels;
using Biskilog_Accounting.Shared.Enums;
using Biskilog_Accounting.Shared.Interfaces;
using Biskilog_Accounting.Shared.POSModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Net.Http.Headers;
using MySqlConnector;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Drawing.Drawing2D;
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 readonly HttpContext m_httpContext;
public AnalyticalService(BiskAcdbContext a_context, ITokenService a_tokenService, IHttpContextAccessor a_httpContextAccessor)
{
m_context = a_context;
m_tokenService = a_tokenService;
m_httpContext = a_httpContextAccessor?.HttpContext;
}
public IEnumerable<CancelledSales> GetCancelledSales(DateTime a_start, DateTime a_end)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
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 && accessiblebranches.Contains(cSale.BranchId)
select new CancelledSales
{
CancelledTransaction = cSale,
Value = (from a in activeSale where accessiblebranches.Contains(a.BranchId) 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)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
Dictionary<string, List<SaleItem>> sales = new Dictionary<string, List<SaleItem>>();
var employeeSales = m_context.Tblcarts.Where(c => c.Date >= a_start && c.Date <= a_end
&& accessiblebranches.Contains(c.BranchId)).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<CustomerAccounts> GetInDebtCustomers()
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
var listDebts = m_context.Customeraccounts.Where(t => t.Balance < 0 && accessiblebranches.Contains(t.BranchId)).OrderByDescending(d => d.Date).Select(t => t.CustomerId).Distinct().ToList();
foreach (var customerId in listDebts)
{
yield return new CustomerAccounts
{
Customer = m_context.Tblcustomers.FirstOrDefault(i => i.CustomerId == customerId),
Debt = m_context.Customeraccounts.AsEnumerable().OrderByDescending(d => d.Date).FirstOrDefault(t => t.Balance < 0 && t.CustomerId == customerId).Balance,
};
}
}
public IEnumerable<MostPurchasedItem> GetMostPurchasedItem(DateTime a_start, DateTime a_end)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
if (AuthEnums.Valid == m_tokenService.ValidateToken(token))
{
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
using (var command = m_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "CALL GetMostPurchasedItems(@p0, @p1, @p2, @p3)";
command.Parameters.Add(new MySqlParameter("@p0", a_start));
command.Parameters.Add(new MySqlParameter("@p1", a_end));
command.Parameters.Add(new MySqlParameter("@p2", string.Join(", ", accessiblebranches.ToArray())));
command.Parameters.Add(new MySqlParameter("@p3", 50));
m_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
List<MostPurchasedItem> result = new List<MostPurchasedItem>();
while (reader.Read())
{
MostPurchasedItem item = new MostPurchasedItem
{
ProductId = reader.GetString(0),
ProductName = reader.GetString(1),
NbrTimesSold = reader.GetInt32(2),
Revenue = reader.GetDecimal(3)
};
result.Add(item);
}
return result;
}
}
}
return new List<MostPurchasedItem>();
}
public IEnumerable<ProductItem> GetOutOfStockItems()
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
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
orderby item.Quantity
where p.Status!.ToLower() != "inactive" && accessiblebranches.Contains(item.BranchId) &&
((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!
});
}
public IEnumerable<ProductPriceChange> GetPriceChanges(DateTime a_start, DateTime a_end)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
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 && accessiblebranches.Contains(change.BranchId)
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<ProductPriceChange> GetProductPriceChangeHistory(int a_limit)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
if (AuthEnums.Valid == m_tokenService.ValidateToken(token))
{
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
using (var command = m_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "CALL GetProductPriceChangeHistory(@p0,@p1)";
command.Parameters.Add(new MySqlParameter("@p0", string.Join(", ", accessiblebranches.ToArray())));
command.Parameters.Add(new MySqlParameter("@p1", a_limit));
m_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return new ProductPriceChange
{
Pcode = reader.GetString(0),
ProductName = reader.GetString(1),
PreviousPrice = reader.GetDecimal(2),
CurrentPrice = reader.GetDecimal(3),
ChangeDate = reader.GetDateTime(4),
BranchId = reader.GetString(5),
CountId = reader.GetString(6),
};
}
}
}
}
}
public IEnumerable<ProductPriceChange> GetRecentPriceChanges(int a_limit)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
return (from change in m_context.Tblpricechanges
join p in m_context.Tblproducts on change.Pcode equals p.Pcode
where accessiblebranches.Contains(change.BranchId)
orderby change.ChangeDate descending
select new ProductPriceChange
{
BranchId = change.BranchId,
ChangeDate = change.ChangeDate,
Pcode = change.Pcode,
CountId = change.CountId,
CurrentPrice = change.CurrentPrice,
PreviousPrice = change.PreviousPrice,
ProductName = p.ProductName
}).Take(a_limit);
}
public IEnumerable<SaleItem> GetRecentSales(int a_limit)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
if (AuthEnums.Valid == m_tokenService.ValidateToken(token))
{
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
using (var command = m_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "CALL GetRecentTransactions(@p0,@p1)";
command.Parameters.Add(new MySqlParameter("@p0", string.Join(", ", accessiblebranches.ToArray())));
command.Parameters.Add(new MySqlParameter("@p1", a_limit));
m_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return new SaleItem
{
Transno = reader.GetString(0),
Total = (decimal)reader.GetDouble(1),
Date = reader.GetDateTime(2),
Cashier = reader.GetString(3),
BranchId = reader.GetString(4),
Customer = reader.GetString(5),
Status = reader.GetString(6),
};
}
}
}
}
}
public IEnumerable<Tblcart> GetSalesTransaction(DateTime a_start, DateTime a_end)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
return m_context.Tblcarts.Where(t => t.Date >= a_start && t.Date <= a_end && accessiblebranches.Contains(t.BranchId));
}
public TradeSummary GetTradeSummary()
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
if (AuthEnums.Valid == m_tokenService.ValidateToken(token))
{
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
using (var command = m_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "CALL GetTradeSummary(@p0,@p1)";
command.Parameters.Add(new MySqlParameter("@p0", string.Join(", ", accessiblebranches.ToArray())));
command.Parameters.Add(new MySqlParameter("@p1", 2));
m_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
int i = 0;
TradeSummary result = new TradeSummary();
while (reader.Read())
{
if (i == 0)
{
result.CurrentTradeDate = reader.GetDateTime(0);
result.CurrentTradeSales = reader.GetDouble(1);
}
else if (i == 1)
{
result.LastTradeDate = reader.GetDateTime(0);
result.LastTradeSales = reader.GetDouble(1);
}
i++;
}
return result;
}
}
}
return new TradeSummary();
}
public IEnumerable<WeeklyCategorySummary> GetWeeklySalesCategoryTransaction(int a_limit)
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
if (AuthEnums.Valid == m_tokenService.ValidateToken(token))
{
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
using (var command = m_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "CALL GetCategoryTradeSummary(@p0,@p1)";
command.Parameters.Add(new MySqlParameter("@p1", a_limit));
command.Parameters.Add(new MySqlParameter("@p0", string.Join(", ", accessiblebranches.ToArray())));
m_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return new WeeklyCategorySummary
{
Category = reader.GetString(0),
Total = reader.GetDecimal(1),
};
}
}
}
}
}
public IEnumerable<WeeklySaleItem> GetWeeklySalesTransaction()
{
string token = m_httpContext.Request.Headers[HeaderNames.Authorization]!;
if (AuthEnums.Valid == m_tokenService.ValidateToken(token))
{
IEnumerable<string> accessiblebranches = m_tokenService.BranchIds(token);
using (var command = m_context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "CALL GetTradeSummary(@p0,@p1)";
command.Parameters.Add(new MySqlParameter("@p0", string.Join(", ", accessiblebranches.ToArray())));
command.Parameters.Add(new MySqlParameter("@p1", 7));
m_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return new WeeklySaleItem()
{
Date = reader.GetDateTime(0),
Total = reader.GetDecimal(1)
};
}
}
}
}
}
}
}