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()
{
}
///
/// Initialise result filters
///
public void Init()
{
IsReconciled = null;
StockTransactionTypeName = null;
StockTransactionTypeCode = null;
}
///
/// Read result filter
///
public bool? IsReconciled { get; set; }
///
/// Read result filter
///
public List StockTransactionTypeName { get; set; }
///
/// Read result filter
///
public List 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;
}
}
}
///
/// Creates a Stock SKU Transaction. Implements validation check.
///
/// Input data/object
/// Stock SKU Transaction Id of new record
///
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);
}
///
///
///
/// Retrive and include transaction type model class
public List Read()
{
var dbRead = DatabaseSkuTransRead();
dbRead.Init();
dbRead.IsReconciled = IsReconciled;
dbRead.StockTransactionTypeCode = StockTransactionTypeCode;
dbRead.StockTransactionTypeName = StockTransactionTypeName;
var resultList = dbRead.Read();
dbRead.Init();
return resultList;
}
///
/// Updates a transaction quantity (must be less than) and creates a new transaction with the remaining quantity
///
/// Stock SKU Transaction Id of the transaction to split
/// Required quantity of the existing transaction
/// Stock SKU Transaction Id of the newly created transaction
/// Incorrect parameters passed to function
/// transaction isProcessed error
public int SplitTransaction(int skuTransactionId, int newQuantity)
{
using (var scope = new TransactionScope())
{
try
{
// get transaction
var transList = DatabaseSkuTransRead().Read(new List { 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;
}
}
}
///
/// Retrive SKU Transaction by ID
///
/// SKU Transaction ID
///
///
public List Read(List SkuTransactionId)
{
var dbRead = DatabaseSkuTransRead();
dbRead.Init();
var resultList = dbRead.Read(SkuTransactionId);
dbRead.Init();
return resultList;
}
///
/// Validates and then updates a Stock SKU Tranaction
///
/// 'Stock SKU Transaction' model
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);
}
}
}