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