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

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
namespace bnhtrade.Core.Model.Account
{
public class Account
{
public Account(uint id, uint accountCode, string accountName, string description, string type, string basicType, int multiplier)
{
Id = id;
AccountCode = accountCode;
AccountName = accountName;
Description = description;
Type = type;
BasicType = basicType;
Multiplier = multiplier;
}
/// <summary>
/// Database record id
/// </summary>
public uint Id { get; private set; }
public uint AccountCode { get; private set; }
public string AccountName { get; private set; }
public string Description { get; private set; }
public string Type { get; private set; }
public string BasicType { get; private set; }
public int Multiplier { get; private set; }
}
}

View File

@@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Account
{
public class AccountCode : IValidatableObject
{
private int? accountCodeId;
[Required(), Range(1, int.MaxValue)]
public int AccountCodeId
{
get { return (int)accountCodeId; }
set { accountCodeId = value; }
}
[Required(), MaxLength(150)]
public string Title
{
get;
set;
}
[MaxLength(500)]
public string Description
{
get;
set;
}
[Required(), MaxLength(50)]
public string Type
{
get;
set;
}
[Required(), MaxLength(50)]
public string BasicType
{
get;
set;
}
public bool IsSetAccountCodeId
{
get { return accountCodeId != null; }
}
public bool IsSetTitle
{
get { return Title != null; }
}
public bool IsSetDescription
{
get { return Description != null; }
}
public bool IsSetType
{
get { return Type != null; }
}
public bool IsSetBasicType
{
get { return BasicType != null; }
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var resultList = new List<ValidationResult>();
if (!IsSetAccountCodeId)
{
resultList.Add(new ValidationResult("Account Code is not set"));
}
return resultList;
}
}
}

View File

@@ -28,7 +28,7 @@ namespace bnhtrade.Core.Model.Account
decimal? UnitAmount { get; set; }
Model.Account.AccountCode AccountCode { get; set; }
Model.Account.Account AccountCode { get; set; }
Model.Account.TaxCodeInfo TaxCode { get; set; }
@@ -116,7 +116,7 @@ namespace bnhtrade.Core.Model.Account
public bool UnitAmountIsTaxExclusive { get; set; }
[Required()]
public Model.Account.AccountCode AccountCode
public Model.Account.Account AccountCode
{
get;
set;

View File

@@ -44,7 +44,7 @@ namespace bnhtrade.Core.Model.Account
}
[Required()]
public Model.Account.AccountCode DefaultAccountCode
public Model.Account.Account DefaultAccountCode
{
get;
set;
@@ -61,7 +61,6 @@ namespace bnhtrade.Core.Model.Account
{
var resultList = new List<ValidationResult>();
resultList.AddRange(DefaultAccountCode.Validate(validationContext));
resultList.AddRange(DefaultTaxCode.Validate(validationContext));
return resultList;

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Stock
{
public class Status
{
public Status(int statusId, int? statusCode, string title, Model.Stock.StatusType type, string reference, int? foreignKeyId, bool isCreditOnly, bool isClosed, DateTime recordCreated)
{
StatusId = statusId;
StatusCode = statusCode;
StatusTitle = title;
StatusType = type;
Reference = reference;
ForeignKeyID = foreignKeyId;
IsCreditOnly = isCreditOnly;
IsClosed = isClosed;
RecordCreated = recordCreated;
}
public int StatusId { get; private set; }
public int? StatusCode { get; private set; }
public string StatusTitle { get; private set; }
public Model.Stock.StatusType StatusType { get; private set; }
public string Reference { get; private set; }
public int? ForeignKeyID { get; private set; }
public bool IsCreditOnly { get; private set; }
public bool IsClosed { get; private set; }
public DateTime RecordCreated { get; private set; }
}
}

View File

@@ -1,60 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static bnhtrade.Core.Data.Database.Constants;
namespace bnhtrade.Core.Model.Stock
{
public class StatusBalance
{
public int StockStatusId { get; set; }
public string Sku { get; set; }
public List<ByDate> ByDateList { get; private set; } = new List<ByDate>();
public class ByDate
internal StatusBalance(int stockStatusId, string skuNumber, List<(DateTime EntryDate, int StockNumber, int Quantity)> stockList)
{
public DateTime EntryDate { get; set; }
public int StockNumber { get; set; }
public int Quantity { get; set; }
StockStatusId = stockStatusId;
SkuNumber = skuNumber;
AddStockList(stockList);
}
public void AddBalanceTransaction(DateTime entryDate, int stockNumber, int quantity)
internal StatusBalance(Model.Stock.Status status, Model.Sku.Sku sku, List<(DateTime EntryDate, int StockNumber, int Quantity)> stockList)
{
if (entryDate == new DateTime())
StockStatusId = status.StatusId;
Status = status;
SkuNumber = sku.SkuNumber;
Sku = sku;
AddStockList(stockList);
}
public int StockStatusId { get; private set; }
public Model.Stock.Status Status { get; private set; }
public bool IsSetStatus
{
get
{
throw new Exception("Entry date set to default value");
return Status != null;
}
}
public string SkuNumber { get; private set; }
public Model.Sku.Sku Sku { get; private set; }
public bool IsSetSku
{
get
{
return Sku != null;
}
}
/// <summary>
/// A list of when each stock item(s) became available and the quanitity (which is not a running total).
/// </summary>
public List<Stock> StockList { get; private set; } = new List<Stock>();
public class Stock
{
public Stock(DateTime entryDate, int stockNumber, int quantity)
{
EntryDate = entryDate;
StockNumber = stockNumber;
Quantity = quantity;
}
var item = new ByDate();
item.EntryDate = entryDate;
item.StockNumber = stockNumber;
item.Quantity = quantity;
public DateTime EntryDate { get; private set; }
if (ByDateList == null) { ByDateList = new List<ByDate>(); }
public int StockNumber { get; private set; }
if (ByDateList.Count == 0 || ByDateList.Last().EntryDate <= item.EntryDate)
public int Quantity { get; private set; }
}
internal void AddDetail(Model.Stock.Status status, Model.Sku.Sku sku)
{
if (sku.SkuNumber != SkuNumber || status.StatusId != StockStatusId)
{
ByDateList.Add(item);
throw new ArgumentException("Invalid SKU or Status applied to class");
}
else
SkuNumber = sku.SkuNumber;
Sku = sku;
}
private void AddStockList(List<(DateTime EntryDate, int StockNumber, int Quantity)> stockList)
{
foreach (var stockItem in stockList)
{
for (int i = 0; i < ByDateList.Count; i++)
if (stockItem.EntryDate == new DateTime())
{
if (entryDate <= ByDateList[i].EntryDate)
throw new Exception("Entry date set to default value");
}
var item = new Stock(stockItem.EntryDate, stockItem.StockNumber, stockItem.Quantity);
if (StockList.Count == 0 || StockList.Last().EntryDate <= item.EntryDate)
{
StockList.Add(item);
}
else
{
for (int i = 0; i < StockList.Count; i++)
{
i++;
ByDateList.Insert(i, item);
if (stockItem.EntryDate <= StockList[i].EntryDate)
{
i++;
StockList.Insert(i, item);
}
}
}
}
}
public bool CheckAvaliableQuantity(int quantity, DateTime onDateTime)
public int GetAvaliableQuantity()
{
if (!StockList.Any())
{
return 0;
}
int qty = 0;
for (int i = 0; i < StockList.Count; i++)
{
qty += StockList[i].Quantity;
}
return qty;
}
public int GetAvaliableQuantity(DateTime onDateTime)
{
if (!StockList.Any())
{
return 0;
}
int qty = 0;
for (int i = 0; i < StockList.Count; i++)
{
if (StockList[i].EntryDate <= onDateTime)
{
qty += StockList[i].Quantity;
}
}
return qty;
}
public bool IsQuantityAvaliable(int quantity, DateTime onDateTime)
{
if (GetAvaliableQuantity(onDateTime) < quantity)
{
@@ -65,42 +155,5 @@ namespace bnhtrade.Core.Model.Stock
return true;
}
}
public int GetAvaliableQuantity()
{
if (!ByDateList.Any())
{
return 0;
}
int qty = 0;
for (int i = 0; i < ByDateList.Count; i++)
{
qty += ByDateList[i].Quantity;
}
return qty;
}
public int GetAvaliableQuantity(DateTime onDateTime)
{
if (!ByDateList.Any())
{
return 0;
}
int qty = 0;
for (int i = 0; i < ByDateList.Count; i++)
{
if (ByDateList[i].EntryDate <= onDateTime)
{
qty += ByDateList[i].Quantity;
}
}
return qty;
}
}
}

View File

@@ -10,7 +10,7 @@ namespace bnhtrade.Core.Model.Stock
{
public int StockStatusId { get; set; }
public string Sku { get; set; }
public string SkuNumber { get; set; }
public int Balance
{

View File

@@ -0,0 +1,26 @@
using bnhtrade.Core.Data.Database.Stock;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Stock
{
public class StatusType
{
public StatusType(int stockStatusTypeId, string name, string foreignKeyType, string referenceType, Model.Account.Account account)
{
StockStatusTypeID = stockStatusTypeId;
StatusTypeName = name;
ForeignKeyType = foreignKeyType;
ReferenceType = referenceType;
Account = account;
}
public int StockStatusTypeID { get; private set; }
public string StatusTypeName { get; private set; }
public string ForeignKeyType { get; private set; }
public string ReferenceType { get; private set; }
public Model.Account.Account Account { get; private set; }
}
}