Feature: stock replenishment

This commit is contained in:
Bobbie Hodgetts
2024-05-09 13:23:33 +01:00
committed by GitHub
parent 91ef9acc78
commit 270eebca9a
30 changed files with 721 additions and 249 deletions

View File

@@ -26,29 +26,29 @@ namespace bnhtrade.Core.Logic.Stock
}
/// <summary>
/// Return the avaliable balance of a status at a specified date and time. Useful for checking availability before
/// moving stock/sku retrospectivly
/// Return the avaliable balance of a status, includes datetime that each stockNumber became avaiable.
/// Useful for checking availability before moving stock/sku retrospectivly
/// </summary>
/// <param name="sku">SKU number</param>
/// <param name="skuNumber">SKU number</param>
/// <param name="statusId">Status ID</param>
/// <param name="atDate">Date and time you would like to know the balance at</param>
/// <param name="includeDetails">True, inlcude SKU and StockStatus class. False, supply the SKU Number and StockStatusId instead</param>
/// <returns></returns>
public Model.Stock.StatusBalance GetBySku(string sku, int statusId)
public Model.Stock.StatusBalance GetStatusBalance(string skuNumber, int statusId, bool includeDetails = true)
{
if (string.IsNullOrWhiteSpace(sku))
if (string.IsNullOrWhiteSpace(skuNumber))
{
throw new Exception("SKU number is null, empty, or whitespace");
}
// get list of transactions for availale stock
var stockTransaction = new Data.Database.Stock.ReadStatusTransaction();
var transList = stockTransaction.BySku(statusId, sku);
var readStatusTransaction = new Data.Database.Stock.ReadStatusTransaction();
var statusTransaction = readStatusTransaction.BySku(statusId, skuNumber);
// create quantity list
List<int> qtyList = new List<int>();
for (int i = 0; i < transList.TransactionList.Count; i++)
for (int i = 0; i < statusTransaction.TransactionList.Count; i++)
{
qtyList.Add(transList.TransactionList[i].Quantity);
qtyList.Add(statusTransaction.TransactionList[i].Quantity);
}
// tally list
@@ -57,15 +57,15 @@ namespace bnhtrade.Core.Logic.Stock
{
if (qtyList[iCr] < 0)
{
int crStockNumber = transList.TransactionList[iCr].StockNumber;
DateTime crDate = transList.TransactionList[iCr].EntryDate;
int crStockNumber = statusTransaction.TransactionList[iCr].StockNumber;
DateTime crDate = statusTransaction.TransactionList[iCr].EntryDate;
// loop, in reverse, to find debits
for (int iDr = qtyList.Count - 1; iDr > -1; iDr--)
{
// find debits, last in first out (filter by date)
if (transList.TransactionList[iDr].StockNumber == crStockNumber
&& transList.TransactionList[iDr].EntryDate <= crDate
if (statusTransaction.TransactionList[iDr].StockNumber == crStockNumber
&& statusTransaction.TransactionList[iDr].EntryDate <= crDate
&& qtyList[iDr] > 0)
{
// credit fully assigned
@@ -87,22 +87,49 @@ namespace bnhtrade.Core.Logic.Stock
}
// build result list from tally results
var result = new Model.Stock.StatusBalance();
result.Sku = transList.Sku;
result.StockStatusId = transList.StockStatusId;
var entryList = new List<(DateTime EntryDate, int StockNumber, int Quantity)>();
for (int i = 0; i < qtyList.Count; i++)
{
if (qtyList[i] != 0)
{
result.AddBalanceTransaction(
transList.TransactionList[i].EntryDate,
transList.TransactionList[i].StockNumber,
(DateTime EntryDate, int StockNumber, int Quantity) entryItem = (
statusTransaction.TransactionList[i].EntryDate,
statusTransaction.TransactionList[i].StockNumber,
qtyList[i]);
entryList.Add(entryItem);
}
}
return result;
if (includeDetails)
{
// get the sku obj
var readSku = new Logic.Sku.GetSkuInfo();
readSku.IncludeConditionInfo = true;
readSku.IncludeProductInfo = true;
readSku.IncludeTaxCodeInfo = true;
var sku = readSku.BySkuNumber(statusTransaction.SkuNumber);
// get the status obj
var readStatus = new Data.Database.Stock.Status();
readStatus.StatusIds = new List<int> { statusTransaction.StockStatusId };
var status = readStatus.Read()[0];
return new Model.Stock.StatusBalance(status, sku, entryList);
}
else
{
return new Model.Stock.StatusBalance(statusTransaction.StockStatusId, statusTransaction.SkuNumber, entryList);
}
}
/// <summary>
/// Get a list of SKUs avaliable against a specified statusId
/// </summary>
/// <param name="statusId">The stock status id</param>
/// <returns>Dictionary of SKUs and the repective balance of each</returns>
public Dictionary<string, int> GetSkuQuantity(int statusId)
{
return new Data.Database.Stock.ReadStatusBalance().ByStatusId(statusId);
}
}
}

View File

@@ -58,10 +58,10 @@ namespace bnhtrade.Core.Logic.Stock
var returnList = new List<(int StockJournalId, int Quantity)>();
// get balance of status and check for avaliable quantity
var statusBalance = new Logic.Stock.StatusBalance().GetBySku(skuNumber, creditStatusId);
var statusBalance = new Logic.Stock.StatusBalance().GetStatusBalance(skuNumber, creditStatusId);
if (statusBalance.GetAvaliableQuantity(entryDate) <= 0
|| (statusBalance.CheckAvaliableQuantity(quantity, entryDate) == false && reallocatePartialQuantity == false
|| (statusBalance.IsQuantityAvaliable(quantity, entryDate) == false && reallocatePartialQuantity == false
))
{
return returnList;
@@ -70,7 +70,7 @@ namespace bnhtrade.Core.Logic.Stock
// temp code start
// until use of stockId is designed out of application
var stockIdDictionary = new Dictionary<int, int>();
foreach (var item in statusBalance.ByDateList)
foreach (var item in statusBalance.StockList)
{
if (!stockIdDictionary.ContainsKey(item.StockNumber))
{
@@ -84,7 +84,7 @@ namespace bnhtrade.Core.Logic.Stock
//make the changes
using (TransactionScope scope = new TransactionScope())
{
foreach (var item in statusBalance.ByDateList)
foreach (var item in statusBalance.StockList)
{
if (quantity > item.Quantity)
{

View File

@@ -6,11 +6,11 @@ using System.Threading.Tasks;
namespace bnhtrade.Core.Logic.Stock
{
public class GetStatusTypeBalance
public class StatusTypeBalance
{
private Core.Data.Database.Stock.ReadStatusTypeBalance dbRead;
public GetStatusTypeBalance()
public StatusTypeBalance()
{
dbRead = new Data.Database.Stock.ReadStatusTypeBalance();
}
@@ -20,7 +20,7 @@ namespace bnhtrade.Core.Logic.Stock
/// </summary>
/// <param name="StatusTypeIdList">List of Status Type Ids</param>
/// <returns>Dictionary where SKU number is key and quantity is value</returns>
public Dictionary<string, int> BySku(List<int> StatusTypeIdList)
public Dictionary<string, int> GetByStatusTypeId(List<int> StatusTypeIdList)
{
return dbRead.ReadSku(StatusTypeIdList);
}