Files
bnhtrade/src/bnhtrade.Core/Logic/Stock/SkuTransactionCrud.cs
Bobbie Hodgetts c8689e3bba Amazon inventory ledger testing and implementation
Tested what I can until more data for the Amazon Ledger Detail table comes in
2024-11-21 17:50:18 +00:00

286 lines
11 KiB
C#

using bnhtrade.Core.Data.Database;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Logic.Stock
{
public class SkuTransactionCrud
{
private string err = "Sku Transaction Persistance Error; ";
private Data.Database.Stock.DeleteSkuTransaction dbSkuTransDelete;
private Data.Database.Stock.InsertSkuTransaction dbSkuTransCreate;
private Data.Database.Stock.ReadSkuTransaction dbSkuTransRead;
private Data.Database.Stock.UpdateSkuTransaction dbSkuTransUpdate;
private Logic.Validate.SkuTransaction validateSkuTrans;
private Logic.Log.LogEvent log = new Log.LogEvent();
public SkuTransactionCrud()
{
}
/// <summary>
/// Initialise result filters
/// </summary>
public void Init()
{
IsReconciled = null;
StockTransactionTypeName = null;
StockTransactionTypeCode = null;
}
/// <summary>
/// Read result filter
/// </summary>
public bool? IsReconciled { get; set; }
/// <summary>
/// Read result filter
/// </summary>
public List<string> StockTransactionTypeName { get; set; }
/// <summary>
/// Read result filter
/// </summary>
public List<string> StockTransactionTypeCode { get; set; }
private Data.Database.Stock.DeleteSkuTransaction DatabaseSkuTransDelete(bool forceNew = false)
{
if (dbSkuTransDelete == null || forceNew)
{
dbSkuTransDelete = new Data.Database.Stock.DeleteSkuTransaction();
}
return dbSkuTransDelete;
}
private Data.Database.Stock.InsertSkuTransaction DatabaseSkuTransInsert(bool forceNew = false)
{
if (dbSkuTransCreate == null || forceNew)
{
dbSkuTransCreate = new Data.Database.Stock.InsertSkuTransaction();
}
return dbSkuTransCreate;
}
private Data.Database.Stock.ReadSkuTransaction DatabaseSkuTransRead(bool forceNew = false)
{
if (dbSkuTransRead == null || forceNew)
{
dbSkuTransRead = new Data.Database.Stock.ReadSkuTransaction();
}
return dbSkuTransRead;
}
private Data.Database.Stock.UpdateSkuTransaction DatabaseSkuTransUpdate(bool forceNew = false)
{
if (dbSkuTransUpdate == null || forceNew)
{
dbSkuTransUpdate = new Data.Database.Stock.UpdateSkuTransaction();
}
return dbSkuTransUpdate;
}
private Logic.Validate.SkuTransaction Validate()
{
if (validateSkuTrans == null)
{
validateSkuTrans = new Validate.SkuTransaction();
}
return validateSkuTrans;
}
public void Delete(int skuTransactionId)
{
using (var scope = new TransactionScope())
{
try
{
// is there a journal entry attached?
int? journalId = DatabaseSkuTransRead().GetJournalId(skuTransactionId);
if (journalId != null)
{
new Data.Database.Stock.JournalCrud().StockJournalDelete((int)journalId);
}
DatabaseSkuTransDelete().ByTransactionId(skuTransactionId);
scope.Complete();
}
catch (Exception ex)
{
scope.Dispose();
throw ex;
}
}
}
/// <summary>
/// Creates a Stock SKU Transaction. Implements validation check.
/// </summary>
/// <param name="skuTransaction">Input data/object</param>
/// <returns>Stock SKU Transaction Id of new record</returns>
/// <exception cref="Exception"></exception>
public int Create(Model.Stock.SkuTransactionCreate skuTransaction)
{
if (skuTransaction == null)
{
throw new Exception(err + "Object was null");
}
Validate().Init();
if (!Validate().DatabaseInsert(skuTransaction))
{
log.LogWarning(err + "Validation failed", Validate().ValidationResultListToString());
throw new Exception(err + "Validation failed");
}
// write to database
return DatabaseSkuTransInsert().Insert(skuTransaction);
}
/// <summary>
///
/// </summary>
/// <param name="retriveTransactionTypeInfo">Retrive and include transaction type model class</param>
public List<Model.Stock.SkuTransaction> Read()
{
var dbRead = DatabaseSkuTransRead();
dbRead.Init();
dbRead.IsReconciled = IsReconciled;
dbRead.StockTransactionTypeCode = StockTransactionTypeCode;
dbRead.StockTransactionTypeName = StockTransactionTypeName;
var resultList = dbRead.Read();
dbRead.Init();
return resultList;
}
/// <summary>
/// Updates a transaction quantity (must be less than) and creates a new transaction with the remaining quantity
/// </summary>
/// <param name="skuTransactionId">Stock SKU Transaction Id of the transaction to split</param>
/// <param name="newQuantity">Required quantity of the existing transaction</param>
/// <returns>Stock SKU Transaction Id of the newly created transaction</returns>
/// <exception cref="ArgumentException">Incorrect parameters passed to function</exception>
/// <exception cref="InvalidOperationException">transaction isProcessed error</exception>
public int SplitTransaction(int skuTransactionId, int newQuantity)
{
using (var scope = new TransactionScope())
{
try
{
// get transaction
var transList = DatabaseSkuTransRead().Read(new List<int> { skuTransactionId });
if (!transList.Any())
throw new ArgumentException("sku transaction id:" + skuTransactionId + "does appear to exist");
// Checks and new quanatity calculation
int quantity2 = 0;
var trans = transList[0];
if (trans.IsProcessed)
throw new InvalidOperationException("Invalid operation: SKU Transaction is set to IsProcessed");
if (newQuantity == 0)
throw new ArgumentException("Quantity parameter cannot be zero");
if (trans.Quantity == newQuantity)
throw new ArgumentException("The new quanity is equal to the existing quantity");
if (trans.Quantity < 0 )
{
// -ve <------ no transaction is less than 0, negative number are converted to posistive before entry to the table
throw new Exception("sku transaction quantity cannot be negative");
if (newQuantity > 0)
throw new ArgumentException("Quantity parameter is +ve when it should be -ve");
if (newQuantity < trans.Quantity)
throw new ArgumentException("Quantity parameter is greater than transaction quantity");
quantity2 = trans.Quantity - newQuantity;
}
else if (trans.Quantity > 0)
{
// +ve
if (newQuantity < 0)
throw new ArgumentException("Quantity parameter is -ve when it should be +ve");
if (newQuantity > trans.Quantity)
throw new ArgumentException("Quantity parameter is greater than transaction quantity");
quantity2 = trans.Quantity - newQuantity;
}
else
{
throw new ArgumentException("sku transaction quantity is zero");
}
// clone transaction, add to database and update quantities
var newTrans = trans.Clone();
int NewTransId = DatabaseSkuTransInsert().Insert(newTrans);
UpdateQuanitity(skuTransactionId, newQuantity);
UpdateQuanitity(NewTransId, quantity2);
scope.Complete();
return NewTransId;
}
catch (Exception ex)
{
scope.Dispose();
throw ex;
}
}
}
/// <summary>
/// Retrive SKU Transaction by ID
/// </summary>
/// <param name="SkuTransactionId">SKU Transaction ID</param>
/// <param name="retriveTransactionTypeInfo"></param>
/// <returns></returns>
public List<Model.Stock.SkuTransaction> Read(List<int> SkuTransactionId)
{
var dbRead = DatabaseSkuTransRead();
dbRead.Init();
var resultList = dbRead.Read(SkuTransactionId);
dbRead.Init();
return resultList;
}
/// <summary>
/// Validates and then updates a Stock SKU Tranaction
/// </summary>
/// <param name="skuTransaction">'Stock SKU Transaction' model</param>
public void Update(Model.Stock.SkuTransaction skuTransaction)
{
if (skuTransaction == null)
{
throw new Exception(err + "Object was null");
}
Validate().Init();
if (!Validate().DatabaseUpdate(skuTransaction))
{
log.LogWarning(err + "Validation failed", Validate().ValidationResultListToString());
throw new Exception(err + "Validation failed");
}
DatabaseSkuTransUpdate().Update(skuTransaction);
}
public void UpdateIsProcessed(int skuTransactionId, bool isProcessed, int? stockJournalId, bool enableJournalDelete = false)
{
// consistancy logic done on data level
DatabaseSkuTransUpdate().UpdateIsProcessed(skuTransactionId, isProcessed, stockJournalId, enableJournalDelete);
}
public void UpdateQuanitity(int skuTransactionId, int quantity)
{
// consistancy logic done on data level
DatabaseSkuTransUpdate().UpdateQuanitity(skuTransactionId, quantity);
}
}
}