Benjamin Arhen
2 years ago
15 changed files with 433 additions and 8 deletions
@ -0,0 +1,96 @@ |
|||
using Biskilog_Accounting.Server.POSModels; |
|||
using Biskilog_Accounting.Server.Services; |
|||
using Biskilog_Accounting.Shared.CustomModels; |
|||
using Biskilog_Accounting.Shared.Interfaces; |
|||
using Biskilog_Accounting.Shared.POSModels; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.Net.Http.Headers; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Data.Entity; |
|||
|
|||
namespace Biskilog_Accounting.Server.Controllers |
|||
{ |
|||
[Route("api/[controller]")]
|
|||
[ApiController] |
|||
public class AnalyticsController : ControllerBase |
|||
{ |
|||
private readonly IConnectionService m_connection; |
|||
private readonly ITokenService m_tokenService; |
|||
public AnalyticsController(ITokenService tokenService, IConnectionService connection) |
|||
{ |
|||
m_tokenService = tokenService; |
|||
m_connection = connection; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Endpoint to return analysis on CancelledSales within a specified period
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
[Authorize] |
|||
[HttpGet, Route("cancelledsales/{a_start}/{a_end}")] |
|||
public IEnumerable<CancelledSales> GetCancelledSalesAsync(DateTime a_start, DateTime a_end) |
|||
{ |
|||
string token = Request.Headers[HeaderNames.Authorization]!; |
|||
int? databaseId = m_tokenService.GetDatabaseIdFromToken(token); |
|||
string connectionString = m_connection.GetClientConnectionString(databaseId!.Value); |
|||
bool? comparisonMode = m_tokenService.GetComparison(token); |
|||
string? currentBranch = m_tokenService.GetBaseBranch(token); |
|||
|
|||
//Creates a new db context
|
|||
BiskAcdbContext newContext = (BiskAcdbContext)m_connection.PrepareDBContext(connectionString); |
|||
|
|||
AnalyticalService analysis = new(newContext, comparisonMode!.Value, currentBranch!); |
|||
var result = analysis.GetCancelledSales(a_start, a_end); |
|||
|
|||
return result; |
|||
} |
|||
/// <summary>
|
|||
/// Endpoint to return analysis on Sales within a specified period
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
[Authorize] |
|||
[HttpGet, Route("sales/{a_start}/{a_end}")] |
|||
public IEnumerable<Tblcart> GetSalesAsync(DateTime a_start, DateTime a_end) |
|||
{ |
|||
string token = Request.Headers[HeaderNames.Authorization]!; |
|||
int? databaseId = m_tokenService.GetDatabaseIdFromToken(token); |
|||
string connectionString = m_connection.GetClientConnectionString(databaseId!.Value); |
|||
bool? comparisonMode = m_tokenService.GetComparison(token); |
|||
string? currentBranch = m_tokenService.GetBaseBranch(token); |
|||
|
|||
//Creates a new db context
|
|||
BiskAcdbContext newContext = (BiskAcdbContext)m_connection.PrepareDBContext(connectionString); |
|||
|
|||
AnalyticalService analysis = new(newContext, comparisonMode!.Value, currentBranch!); |
|||
return analysis.GetSalesTransaction(a_start, a_end); |
|||
} |
|||
/// <summary>
|
|||
/// Endpoint to return analysis on in-debt customers
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
[Authorize] |
|||
[HttpGet, Route("debtors")] |
|||
public IEnumerable<InDebtCustomers> GetInDebtCustomers() |
|||
{ |
|||
string token = Request.Headers[HeaderNames.Authorization]!; |
|||
int? databaseId = m_tokenService.GetDatabaseIdFromToken(token); |
|||
string connectionString = m_connection.GetClientConnectionString(databaseId!.Value); |
|||
bool? comparisonMode = m_tokenService.GetComparison(token); |
|||
string? currentBranch = m_tokenService.GetBaseBranch(token); |
|||
|
|||
//Creates a new db context
|
|||
BiskAcdbContext newContext = (BiskAcdbContext)m_connection.PrepareDBContext(connectionString); |
|||
|
|||
AnalyticalService analysis = new(newContext, comparisonMode!.Value, currentBranch!); |
|||
return analysis.GetInDebtCustomers(); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,165 @@ |
|||
using Biskilog_Accounting.Server.POSModels; |
|||
using Biskilog_Accounting.Shared.CustomModels; |
|||
using Biskilog_Accounting.Shared.Interfaces; |
|||
using Biskilog_Accounting.Shared.POSModels; |
|||
using Microsoft.EntityFrameworkCore; |
|||
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 bool m_comparisonMode; |
|||
private string m_activeBranch; |
|||
public AnalyticalService(BiskAcdbContext a_context, bool a_comparisonMode, string a_activeBranchId) |
|||
{ |
|||
m_context = a_context; |
|||
m_comparisonMode = a_comparisonMode; |
|||
m_activeBranch = a_activeBranchId; |
|||
} |
|||
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 IEnumerable<Dictionary<string, List<Tblcart>>> GetEmployeeSales(DateTime a_start, DateTime a_end) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public IEnumerable<InDebtCustomers> GetInDebtCustomers() |
|||
{ |
|||
if (m_comparisonMode) |
|||
{ |
|||
return from c in m_context.Tblcustomers |
|||
join a in m_context.Customeraccounts on c.CustomerId equals a.CustomerId into CustomerAccounts |
|||
from ac in CustomerAccounts.OrderByDescending(ac => ac.Date).Take(1).DefaultIfEmpty() |
|||
where ac.Balance < 0 |
|||
orderby ac.Date descending |
|||
select new InDebtCustomers |
|||
{ |
|||
Customer = c, |
|||
Debt = ac != null ? ac.Balance : 0 |
|||
}; |
|||
|
|||
} |
|||
else |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
public IEnumerable<ProductItem> GetMostPurchasedItem(DateTime a_start, DateTime a_end) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public IEnumerable<ProductItem> GetOutOfStockItems() |
|||
{ |
|||
//if (m_comparisonMode)
|
|||
//{
|
|||
// return from r in m_context.Restocklevels
|
|||
// join i in m_context.Tblinventories on r.ProductId equals i.Pcode
|
|||
// join p in m_context.Tblproducts on i.Pcode equals p.Pcode
|
|||
// where i.Quantity == r.WarnLevel
|
|||
// select new ProductItem
|
|||
// {
|
|||
// Product = p,
|
|||
// Stock = i,
|
|||
// Unitofmeasure =
|
|||
// }
|
|||
//}
|
|||
//else {
|
|||
//}
|
|||
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); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
using Biskilog_Accounting.Shared.POSModels; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Biskilog_Accounting.Shared.CustomModels |
|||
{ |
|||
public class CancelledSales |
|||
{ |
|||
public Tblcancelledtransaction? CancelledTransaction { get; set; } |
|||
public string Customer { get; set; } = "WALK-IN Purchase"; |
|||
public decimal? Value { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
using Biskilog_Accounting.Shared.POSModels; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Biskilog_Accounting.Shared.CustomModels |
|||
{ |
|||
public class InDebtCustomers |
|||
{ |
|||
public Tblcustomer Customer { get; set; } |
|||
public decimal Debt { get; set; } = 0; |
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
using Biskilog_Accounting.Shared.POSModels; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Biskilog_Accounting.Shared.CustomModels |
|||
{ |
|||
public class ProductItem |
|||
{ |
|||
public Tblproduct? Product { get; set; } |
|||
public Tblinventory? Stock { get; set; } |
|||
public List<Unitofmeasure> Unitofmeasure { get; set; } = new List<Unitofmeasure>(); |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Biskilog_Accounting.Shared.CustomModels |
|||
{ |
|||
public class ProductPriceChange |
|||
{ |
|||
public string? Pcode { get; set; } |
|||
public string? ProductName { get; set; } |
|||
public decimal? PreviousPrice { get; set; } |
|||
|
|||
public decimal? CurrentPrice { get; set; } |
|||
|
|||
public DateTime? ChangeDate { get; set; } |
|||
|
|||
public string BranchId { get; set; } = null!; |
|||
|
|||
public string CountId { get; set; } = null!; |
|||
} |
|||
} |
@ -0,0 +1,53 @@ |
|||
using Biskilog_Accounting.Shared.CustomModels; |
|||
using Biskilog_Accounting.Shared.POSModels; |
|||
|
|||
namespace Biskilog_Accounting.Shared.Interfaces |
|||
{ |
|||
public interface IAnalytics |
|||
{ |
|||
/// <summary>
|
|||
/// Fetches a collection of sales transaction made from the specified start date to the end date
|
|||
/// </summary>
|
|||
/// <param name="a_start">Specified Start Date</param>
|
|||
/// <param name="a_end">Specified end Date</param>
|
|||
/// <returns></returns>
|
|||
IEnumerable<Tblcart> GetSalesTransaction(DateTime a_start, DateTime a_end); |
|||
/// <summary>
|
|||
/// Fetches a collection of in-debt customers
|
|||
/// <returns></returns>
|
|||
IEnumerable<InDebtCustomers> GetInDebtCustomers(); |
|||
/// <summary>
|
|||
/// Fetches a collection of Product Items which are currently out of stock
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
IEnumerable<ProductItem> GetOutOfStockItems(); |
|||
/// <summary>
|
|||
/// Fetches a collection of the most purchased Product Items within a specified date range
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
/// <returns></returns>
|
|||
IEnumerable<ProductItem> GetMostPurchasedItem(DateTime a_start, DateTime a_end); |
|||
/// <summary>
|
|||
/// Fetches a collection of cancelled transaction within a specified date range
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
/// <returns></returns>
|
|||
IEnumerable<CancelledSales> GetCancelledSales(DateTime a_start, DateTime a_end); |
|||
/// <summary>
|
|||
/// Fetches a collection of transaction made by employees within a specified date range
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
/// <returns>A dictionary of transactions made by employees with employee name as key</returns>
|
|||
IEnumerable<Dictionary<string, List<Tblcart>>> GetEmployeeSales(DateTime a_start, DateTime a_end); |
|||
/// <summary>
|
|||
/// Fetches a collection of product price changes with a specified date range
|
|||
/// </summary>
|
|||
/// <param name="a_start"></param>
|
|||
/// <param name="a_end"></param>
|
|||
/// <returns></returns>
|
|||
IEnumerable<ProductPriceChange> GetPriceChanges(DateTime a_start, DateTime a_end); |
|||
} |
|||
} |
Loading…
Reference in new issue