mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-03-19 06:27:15 +00:00
wip
This commit is contained in:
@@ -70,7 +70,7 @@ namespace bnhtrade.ComTypeLib
|
||||
|
||||
public void StockJournalDelete(ConnectionCredential sqlConnCred, int stockJournalId)
|
||||
{
|
||||
Core.Stock.StockJournal.StockJournalDelete(sqlConnCred.ConnectionString, stockJournalId);
|
||||
new Core.Logic.Inventory.StockJournalService().StockJournalDelete(stockJournalId);
|
||||
}
|
||||
|
||||
public object ReconcileStockTransactions(ConnectionCredential sqlConnCred)
|
||||
@@ -128,7 +128,7 @@ namespace bnhtrade.ComTypeLib
|
||||
|
||||
public bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId)
|
||||
{
|
||||
return Core.Stock.StockJournal.WIP_StockJournalConsistencyCheck(sqlConnCred.ConnectionString, stockId, null);
|
||||
return new Core.Logic.Inventory.StockJournalService().WIP_StockJournalConsistencyCheck(stockId, null);
|
||||
}
|
||||
|
||||
public void SkuTransactionAdd(ConnectionCredential sqlConnCred, int quantity, string skuNumber, string transactionTypeCode, DateTime transactionDate)
|
||||
|
||||
@@ -383,12 +383,47 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public DateTime ReadJournalEntryDate(int journalId)
|
||||
{
|
||||
if (journalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(journalId));
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT tblAccountJournal.EntryDate
|
||||
FROM tblAccountJournal
|
||||
WHERE (((tblAccountJournal.AccountJournalID)=@accountJournalId));";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("Journal entry not found for AccountJournalID=" + journalId);
|
||||
}
|
||||
|
||||
return DateTime.SpecifyKind((DateTime)obj, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for locked journal entry
|
||||
/// </summary>
|
||||
/// <returns>False on locked journal entry</returns>
|
||||
public bool ReadJournalIsLocked(int journalId)
|
||||
{
|
||||
if (journalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(journalId));
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT
|
||||
tblAccountJournal.IsLocked
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
using static bnhtrade.Core.Data.Database.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
@@ -118,7 +119,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
|
||||
// insert journal posts into database
|
||||
//new Data.Database.Stock
|
||||
Core.Stock.StockJournal.StockJournalPostInsert(conn, stockId, stockJournalId, journalPosts, isNewStock);
|
||||
StockJournalPostInsert(stockId, stockJournalId, journalPosts, isNewStock);
|
||||
|
||||
// consistency check
|
||||
bool consistencyResult = true;
|
||||
@@ -158,6 +159,30 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
// Read
|
||||
//
|
||||
|
||||
public int ReadJournalTypeIdByStockId(int stockId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT tblStockJournal.StockJournalTypeID
|
||||
FROM tblStock INNER JOIN
|
||||
tblStockJournal ON tblStock.StockJournalID = tblStockJournal.StockJournalID
|
||||
WHERE (tblStock.StockID = @stockId);";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("No stock journal type found for StockID=" + stockId);
|
||||
}
|
||||
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
public int ReadStatusBalanceBySku(string sku, int statusId)
|
||||
{
|
||||
int statusBalance = new int();
|
||||
@@ -255,6 +280,22 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
return statusBalance;
|
||||
}
|
||||
|
||||
public int ReadJournalEntryCountByStockId(int stockId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT Count(tblStockJournal.StockJournalID) AS CountOfStockJournalID
|
||||
FROM tblStockJournal
|
||||
WHERE (((tblStockJournal.StockID)=@stockId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// update
|
||||
//
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
using static System.Formats.Asn1.AsnWriter;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
@@ -16,126 +17,424 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
}
|
||||
|
||||
public List<Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null)
|
||||
{
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
var returnList = new List<Model.Stock.Status>();
|
||||
//
|
||||
// create
|
||||
//
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT [StockStatusID]
|
||||
,[StatusCode]
|
||||
,[StockStatus]
|
||||
,[StockStatusTypeID]
|
||||
,[Reference]
|
||||
,[ForeignKeyID]
|
||||
,[IsCreditOnly]
|
||||
,[IsClosed]
|
||||
,[RecordCreated]
|
||||
FROM [e2A].[dbo].[tblStockStatus]
|
||||
WHERE 1=1 ";
|
||||
public int WIP_StockInsertSub(int productId, int conditionId, int accountTaxCodeId,
|
||||
int accountJournalId, int stockJournalTypeId, DateTime stockJournalEntryDate, int quantity, int statusDebitId)
|
||||
{
|
||||
stockJournalEntryDate = DateTime.SpecifyKind(stockJournalEntryDate, DateTimeKind.Utc);
|
||||
|
||||
// build the where statments
|
||||
if (statusIds.Any())
|
||||
// ensure account journal id hasn't already been added to stock table
|
||||
int count = 0;
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT Count(tblStock.StockID) AS CountOfID
|
||||
FROM tblStock
|
||||
WHERE (((tblStock.AccountJournalID)=@accountJouranlId));
|
||||
", conn))
|
||||
{
|
||||
sqlBuilder.In("StockStatusID", statusIds, "AND");
|
||||
}
|
||||
if (statusTypeIds.Any())
|
||||
{
|
||||
sqlBuilder.In("StockStatusTypeID", statusTypeIds, "AND");
|
||||
cmd.Parameters.AddWithValue("@accountJouranlId", accountJournalId);
|
||||
|
||||
count = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
if (count == 1)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
throw new Exception("Add account journal entry already assigned to stock line.");
|
||||
}
|
||||
else if (count > 1)
|
||||
{
|
||||
throw new Exception("Houston we have a problem! An account journal entry is assigned to " + count + " stock lines.");
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
// ensure the debit for the account journal transaction is to an 'Asset' account type
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
|
||||
FROM
|
||||
(tblAccountJournalPost
|
||||
INNER JOIN tblAccountChartOf
|
||||
ON tblAccountJournalPost.AccountChartOfID = tblAccountChartOf.AccountChartOfID)
|
||||
INNER JOIN tblAccountChartOfType
|
||||
ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
|
||||
WHERE
|
||||
tblAccountJournalPost.AmountGbp>=0
|
||||
AND tblAccountChartOfType.BasicType='Asset'
|
||||
AND tblAccountJournalPost.AccountJournalID=@accountJournalId;
|
||||
", conn))
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
if (sqlBuilder.ParameterListIsSet)
|
||||
if ((int)cmd.ExecuteScalar() < 1)
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
throw new Exception("Supplied AccountJournal entry must debit an 'Asset' account type.");
|
||||
}
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
// get statusCreditId for stock journal type
|
||||
int statusCreditId;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockJournalType.StockStatusID_Credit
|
||||
FROM
|
||||
tblStockJournalType
|
||||
WHERE
|
||||
tblStockJournalType.StockJournalTypeID=@stockJournalTypeId
|
||||
AND tblStockJournalType.StockStatusID_Credit Is Not Null;
|
||||
", conn))
|
||||
{
|
||||
var typeDict = new StockRepository(_connection, _transaction).ReadStatusType();
|
||||
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
|
||||
|
||||
while (reader.Read())
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
int statusId = reader.GetInt32(0);
|
||||
int? statusCode = null;
|
||||
if (!reader.IsDBNull(1)) { statusCode = reader.GetInt32(1); }
|
||||
string stockStatus = reader.GetString(2);
|
||||
int typeId = reader.GetInt32(3);
|
||||
string reference = null;
|
||||
if (!reader.IsDBNull(4)) { reference = reader.GetString(4); }
|
||||
int? foreignKeyId = null;
|
||||
if (!reader.IsDBNull(5)) { foreignKeyId = reader.GetInt32(5); }
|
||||
bool isCreditOnly = reader.GetBoolean(6);
|
||||
bool isClosed = reader.GetBoolean(7);
|
||||
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc);
|
||||
throw new Exception("Default credit status not set for StockJournalTypeID=" + stockJournalTypeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
statusCreditId = (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
var newItem = new Model.Stock.Status(statusId
|
||||
, statusCode
|
||||
, stockStatus
|
||||
, typeDict[typeId]
|
||||
, reference
|
||||
, foreignKeyId
|
||||
, isCreditOnly
|
||||
, isClosed
|
||||
, recordCreated
|
||||
);
|
||||
// get/set an skuId
|
||||
int skuId = new Logic.Inventory.SkuService().GetSkuId(productId, conditionId, accountTaxCodeId, true);
|
||||
|
||||
returnList.Add(newItem);
|
||||
// add the entry to the stock table (minus stockJournalId)
|
||||
int stockId = 0;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblStock
|
||||
(SkuID, AccountJournalID)
|
||||
OUTPUT INSERTED.StockID
|
||||
VALUES
|
||||
(@skuId, @accountJournalId);
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@skuId", skuId);
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
stockId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
// insert stock journal entry
|
||||
var journalPosts = new List<(int statusId, int quantity)>();
|
||||
journalPosts.Add((statusDebitId, quantity));
|
||||
journalPosts.Add((statusCreditId, (quantity * -1)));
|
||||
int stockJournalId = Stock.StockJournal.StockJournalInsert(sqlConnectionString, stockJournalTypeId, stockId, journalPosts, stockJournalEntryDate, true);
|
||||
|
||||
// update the stock table
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblStock
|
||||
SET StockJournalID=@stockJournalId
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count < 1)
|
||||
{
|
||||
throw new Exception("New stock insert cancelled, failed to update StockJournalID");
|
||||
}
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
return stockId;
|
||||
}
|
||||
|
||||
public int WIP_StockInsertPurchase(int productId, int conditionId, int accountTaxCodeId, int accountJournalId, int quantity, int statusDebitId)
|
||||
{
|
||||
DateTime stockJournalEntryDate;
|
||||
int stockJournalTypeId = 1;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// retrive info from purchase invoice line/transaction
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT tblAccountJournal.EntryDate
|
||||
FROM tblAccountJournal
|
||||
WHERE (((tblAccountJournal.AccountJournalID)=@accountJournalId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
stockJournalEntryDate = DateTime.SpecifyKind((DateTime)cmd.ExecuteScalar(), DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
return WIP_StockInsertSub(productId, conditionId, accountTaxCodeId, accountJournalId, stockJournalTypeId, stockJournalEntryDate, quantity, statusDebitId);
|
||||
}
|
||||
|
||||
public int WIP_StockInsertOwnerIntroduced(decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId)
|
||||
{
|
||||
int accountJournalType = 3;
|
||||
int stockJournalType = 2;
|
||||
string currencyCode = "GBP";
|
||||
|
||||
return WIP_StockInsert(accountJournalType, stockJournalType, currencyCode, amount, quantity, productId, conditionId, accountTaxCodeId, entryDate, debitStatusId);
|
||||
}
|
||||
|
||||
//
|
||||
// read
|
||||
//
|
||||
|
||||
//
|
||||
// update
|
||||
//
|
||||
|
||||
//
|
||||
// delete
|
||||
//
|
||||
|
||||
private void WIP_StockDelete(int stockId)
|
||||
{
|
||||
int accountJournalType = 0;
|
||||
int stockJournalType = 0;
|
||||
|
||||
// get stock and account types
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// ensure stockId is owner-introduced
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockJournal.StockJournalTypeID, tblAccountJournal.AccountJournalTypeID
|
||||
FROM
|
||||
(tblStock INNER JOIN tblAccountJournal
|
||||
ON tblStock.AccountJournalID = tblAccountJournal.AccountJournalID)
|
||||
INNER JOIN tblStockJournal
|
||||
ON tblStock.StockJournalID = tblStockJournal.StockJournalID
|
||||
WHERE
|
||||
(((tblStock.StockID)=@stockId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
accountJournalType = reader.GetInt32(1);
|
||||
stockJournalType = reader.GetInt32(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Integrity check failed, cancelling StockDeleteOwnerIntroduced");
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
|
||||
// check stock journal type is not restricted
|
||||
// owner inventory introduced
|
||||
if (stockJournalType == 2)
|
||||
{
|
||||
// no dramas
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Manual delete of this stock type is not supported, use the method that created it!");
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Stock.StatusType> ReadStatusType()
|
||||
// check there is only one stock journal entry for stock item
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT Count(tblStockJournal.StockJournalID) AS CountOfStockJournalID
|
||||
FROM tblStockJournal
|
||||
WHERE (((tblStockJournal.StockID)=@stockId));
|
||||
", conn))
|
||||
{
|
||||
var returnDict = new Dictionary<int, Model.Stock.StatusType>();
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
// get all account info before we start
|
||||
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode();
|
||||
int count = (int)cmd.ExecuteScalar();
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
if (count > 1)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
SELECT [StockStatusTypeID]
|
||||
,[StatusTypeName]
|
||||
,[ForeignKeyType]
|
||||
,[ReferenceType]
|
||||
,[AccountChartOfID]
|
||||
FROM [e2A].[dbo].[tblStockStatusType]";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
throw new Exception("Delete " + count + " stock journal entries (other than source entry), before peforming this operation.");
|
||||
}
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
// remove account journal entry
|
||||
WIP_StockDeleteSubAccountJournalEntry(sqlConnectionString, stockId);
|
||||
|
||||
// remove stock
|
||||
WIP_StockDeleteSub(sqlConnectionString, stockId);
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private void WIP_StockDeleteSub(int stockId)
|
||||
{
|
||||
var accountIdDict = new Dictionary<int, int>();
|
||||
|
||||
while (reader.Read())
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
int statusTypeId = reader.GetInt32(0);
|
||||
string name = reader.GetString(1);
|
||||
string foreignKey = null;
|
||||
if (!reader.IsDBNull(2)) { foreignKey = reader.GetString(2); }
|
||||
string reference = null;
|
||||
if (!reader.IsDBNull(3)) { reference = reader.GetString(3); }
|
||||
uint accountId = (uint)reader.GetInt32(4);
|
||||
conn.Open();
|
||||
|
||||
var statusType = new Model.Stock.StatusType(statusTypeId, name, foreignKey, reference, accountDict[(int)accountId]);
|
||||
returnDict.Add(statusTypeId, statusType);
|
||||
// check for accountJournalId on stock table
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT AccountJournalID
|
||||
FROM tblStock
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("StockID=" + stockId + " does not exist.");
|
||||
}
|
||||
else if (obj == DBNull.Value)
|
||||
{
|
||||
// nothing to do all is good
|
||||
}
|
||||
else
|
||||
{
|
||||
int id = (int)obj;
|
||||
if (id > 0)
|
||||
{
|
||||
throw new Exception("StockID=" + stockId + " remove account journal entry using method that created it first.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnDict;
|
||||
|
||||
// get stockJournalId
|
||||
int stockJournalId;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT StockJournalID
|
||||
FROM tblStock
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
try
|
||||
{
|
||||
stockJournalId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("Could not retrive StockJournalID for StockID=" + stockId);
|
||||
}
|
||||
}
|
||||
|
||||
// remove stockJournalId from stock table
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblStock
|
||||
SET StockJournalID=NULL
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 2) // we need to count the LastUpdated trigger!
|
||||
{
|
||||
throw new Exception("Failed to remove StockJournalID from stock table StockID=" + stockId);
|
||||
}
|
||||
}
|
||||
|
||||
// delete stock journal entry
|
||||
new Core.Logic.Inventory.StockJournalService().StockJournalDelete(stockJournalId);
|
||||
|
||||
// delete stock table entry
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM tblStock
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
throw new Exception("StockID = " + stockId + " delete failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// to be used by other methods within a transaction scope
|
||||
private void WIP_StockDeleteSubAccountJournalEntry(int stockId)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
var trans = conn.BeginTransaction();
|
||||
|
||||
// get the account journal id
|
||||
int accountJournalId = 0;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT AccountJournalID
|
||||
FROM tblStock
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Transaction = trans;
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("StockID=" + stockId + " does not exist.");
|
||||
}
|
||||
else if (obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("AccountJournalID not found for StockID=" + stockId);
|
||||
}
|
||||
else
|
||||
{
|
||||
accountJournalId = (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
// remove entry from stock table
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblStock
|
||||
SET AccountJournalID=NULL
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Transaction = trans;
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 2) // must include last modified trigger
|
||||
{
|
||||
throw new Exception("Failed to set AccountJournalID to NULL on stock table for StockID=" + stockId);
|
||||
}
|
||||
}
|
||||
|
||||
// delete account journal entry
|
||||
new Data.Database.Repository.Implementation.AccountJournalRepository(conn, trans).DeleteJournal(accountJournalId);
|
||||
|
||||
trans.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void WIP_StockDeletePurchase(int stockId)
|
||||
{
|
||||
WIP_StockDeleteSub(sqlConnectionString, stockId);
|
||||
}
|
||||
|
||||
public void WIP_StockDeleteOwnerIntroduced(int stockId)
|
||||
{
|
||||
WIP_StockDelete(sqlConnectionString, stockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class StockStatusRepository : _Base, IStockStatusRepository
|
||||
{
|
||||
public StockStatusRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public List<Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null)
|
||||
{
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
var returnList = new List<Model.Stock.Status>();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT [StockStatusID]
|
||||
,[StatusCode]
|
||||
,[StockStatus]
|
||||
,[StockStatusTypeID]
|
||||
,[Reference]
|
||||
,[ForeignKeyID]
|
||||
,[IsCreditOnly]
|
||||
,[IsClosed]
|
||||
,[RecordCreated]
|
||||
FROM [e2A].[dbo].[tblStockStatus]
|
||||
WHERE 1=1 ";
|
||||
|
||||
// build the where statments
|
||||
if (statusIds.Any())
|
||||
{
|
||||
sqlBuilder.In("StockStatusID", statusIds, "AND");
|
||||
}
|
||||
if (statusTypeIds.Any())
|
||||
{
|
||||
sqlBuilder.In("StockStatusTypeID", statusTypeIds, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (sqlBuilder.ParameterListIsSet)
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
var typeDict = new StockStatusRepository(_connection, _transaction).ReadStatusType();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
int statusId = reader.GetInt32(0);
|
||||
int? statusCode = null;
|
||||
if (!reader.IsDBNull(1)) { statusCode = reader.GetInt32(1); }
|
||||
string stockStatus = reader.GetString(2);
|
||||
int typeId = reader.GetInt32(3);
|
||||
string reference = null;
|
||||
if (!reader.IsDBNull(4)) { reference = reader.GetString(4); }
|
||||
int? foreignKeyId = null;
|
||||
if (!reader.IsDBNull(5)) { foreignKeyId = reader.GetInt32(5); }
|
||||
bool isCreditOnly = reader.GetBoolean(6);
|
||||
bool isClosed = reader.GetBoolean(7);
|
||||
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc);
|
||||
|
||||
var newItem = new Model.Stock.Status(statusId
|
||||
, statusCode
|
||||
, stockStatus
|
||||
, typeDict[typeId]
|
||||
, reference
|
||||
, foreignKeyId
|
||||
, isCreditOnly
|
||||
, isClosed
|
||||
, recordCreated
|
||||
);
|
||||
|
||||
returnList.Add(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Stock.StatusType> ReadStatusType()
|
||||
{
|
||||
var returnDict = new Dictionary<int, Model.Stock.StatusType>();
|
||||
|
||||
// get all account info before we start
|
||||
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode();
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
SELECT [StockStatusTypeID]
|
||||
,[StatusTypeName]
|
||||
,[ForeignKeyType]
|
||||
,[ReferenceType]
|
||||
,[AccountChartOfID]
|
||||
FROM [e2A].[dbo].[tblStockStatusType]";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
var accountIdDict = new Dictionary<int, int>();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
int statusTypeId = reader.GetInt32(0);
|
||||
string name = reader.GetString(1);
|
||||
string foreignKey = null;
|
||||
if (!reader.IsDBNull(2)) { foreignKey = reader.GetString(2); }
|
||||
string reference = null;
|
||||
if (!reader.IsDBNull(3)) { reference = reader.GetString(3); }
|
||||
uint accountId = (uint)reader.GetInt32(4);
|
||||
|
||||
var statusType = new Model.Stock.StatusType(statusTypeId, name, foreignKey, reference, accountDict[(int)accountId]);
|
||||
returnDict.Add(statusTypeId, statusType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnDict;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
int AccountJournalInsert(int journalTypeId, DateTime entryDate, string currencyCode, decimal amount, int debitAccountId = 0, int creditAccountId = 0, bool lockEntry = false);
|
||||
bool AccountJournalPostInsert(int journalId, DateTime entryDate, string currencyCode, decimal amount, int debitAccountId = 0, int creditAccountId = 0);
|
||||
Dictionary<int, Core.Model.Account.Journal> ReadJournal(List<int> journalIdList);
|
||||
DateTime ReadJournalEntryDate(int journalId);
|
||||
bool ReadJournalIsLocked(int journalId);
|
||||
Dictionary<int, Model.Account.JournalType> ReadJournalType(List<int> journalTypeIds = null, List<string> typeTitles = null);
|
||||
bool DeleteJournal(int accountJournalId);
|
||||
|
||||
@@ -8,9 +8,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IStockJournalRepository
|
||||
{
|
||||
int ReadJournalTypeIdByStockId(int stockId);
|
||||
int ReadStatusBalanceBySku(string sku, int statusId);
|
||||
int ReadStatusBalanceByStockNumber(int stockNumber, int statusId);
|
||||
int ReadStatusBalanceByStockId(int stockId, int statusId);
|
||||
int ReadJournalEntryCountByStockId(int stockId);
|
||||
Dictionary<string, int> ReadStatusBalanceByStatusId(int statusId);
|
||||
void StockJournalDelete(int stockJournalId);
|
||||
void StockJournalPostInsert(int stockId, int stockJournalId, List<(int statusId, int quantity)> journalPosts, bool isNewStock = false);
|
||||
|
||||
@@ -8,7 +8,14 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IStockRepository
|
||||
{
|
||||
List<Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null);
|
||||
Dictionary<int, Model.Stock.StatusType> ReadStatusType();
|
||||
int WIP_StockInsertSub(int productId, int conditionId, int accountTaxCodeId,
|
||||
int accountJournalId, int stockJournalTypeId, DateTime stockJournalEntryDate, int quantity, int statusDebitId);
|
||||
int WIP_StockInsertPurchase(int productId, int conditionId, int accountTaxCodeId, int accountJournalId, int quantity, int statusDebitId);
|
||||
int WIP_StockInsertOwnerIntroduced(decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId);
|
||||
void WIP_StockDelete(int stockId);
|
||||
void WIP_StockDeleteSub(int stockId);
|
||||
void WIP_StockDeleteSubAccountJournalEntry(int stockId);
|
||||
void WIP_StockDeletePurchase(int stockId);
|
||||
void WIP_StockDeleteOwnerIntroduced(int stockId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IStockStatusRepository
|
||||
{
|
||||
List<Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null);
|
||||
Dictionary<int, Model.Stock.StatusType> ReadStatusType();
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,9 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
|
||||
IAccountJournalRepository JournalRepository { get; }
|
||||
ISequenceGenerator SequenceGenerator { get; }
|
||||
ISkuRepository SkuRepository { get; }
|
||||
IStockJournalRepository StockJournalRepository { get; }
|
||||
IStockRepository StockRepository { get; }
|
||||
IStockJournalRepository StockJournalRepository { get; }
|
||||
IStockStatusRepository StockStatusRepository { get; }
|
||||
|
||||
// Methods to manage the transaction
|
||||
void Commit();
|
||||
|
||||
@@ -28,8 +28,9 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
|
||||
private IAccountJournalRepository _journalRepository;
|
||||
private ISequenceGenerator _sequenceGenerator;
|
||||
private ISkuRepository _skuRepository;
|
||||
private IStockJournalRepository _stockJournalRespository;
|
||||
private IStockRepository _stockRepository;
|
||||
private IStockJournalRepository _stockJournalRespository;
|
||||
private IStockStatusRepository _stockStatusRepository;
|
||||
|
||||
internal UnitOfWork()
|
||||
{
|
||||
@@ -158,6 +159,18 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
|
||||
}
|
||||
}
|
||||
|
||||
public IStockRepository StockRepository
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_stockRepository == null)
|
||||
{
|
||||
_stockRepository = new StockRepository(_connection, _transaction);
|
||||
}
|
||||
return _stockRepository;
|
||||
}
|
||||
}
|
||||
|
||||
public IStockJournalRepository StockJournalRepository
|
||||
{
|
||||
get
|
||||
@@ -170,15 +183,15 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
|
||||
}
|
||||
}
|
||||
|
||||
public IStockRepository StockRepository
|
||||
public IStockStatusRepository StockStatusRepository
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_stockRepository == null)
|
||||
if (_stockStatusRepository == null)
|
||||
{
|
||||
_stockRepository = new StockRepository(_connection, _transaction);
|
||||
_stockStatusRepository = new StockStatusRepository(_connection, _transaction);
|
||||
}
|
||||
return _stockRepository;
|
||||
return _stockStatusRepository;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,15 +21,14 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
{
|
||||
throw new ArgumentException("Stock journal ID must be greater than zero", nameof(stockJournalId));
|
||||
}
|
||||
bool result = uow.StockJournalRepository.DeleteStockJournal(stockJournalId);
|
||||
uow.StockJournalRepository.StockJournalDelete(stockJournalId);
|
||||
CommitIfOwned(uow);
|
||||
if (!result)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to delete stock journal with ID {stockJournalId}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// can be used before commiting an sql insert, update or delete to the stock journal to ensure a status does not fall below 0
|
||||
// (unless the status is enabled to do so)
|
||||
// set empty list or statusIdEffected to null to check entier stock entries for consistency
|
||||
public bool WIP_StockJournalConsistencyCheck(int stockId, List<int> statusIdEffected = null)
|
||||
{
|
||||
return WithUnitOfWork(uow =>
|
||||
|
||||
@@ -18,187 +18,30 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
private int WIP_StockInsert(int accountJournalType, int stockJournalType, string currencyCode, decimal amount,
|
||||
int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId)
|
||||
{
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
return WithUnitOfWork(uow =>
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// add account journal entry
|
||||
int accountJournalId = new Logic.Account.JournalService().JournalInsert(accountJournalType, entryDate, currencyCode, amount);
|
||||
int accountJournalId = new Logic.Account.JournalService(uow).JournalInsert(accountJournalType, entryDate, currencyCode, amount);
|
||||
|
||||
// make the stock insert
|
||||
int stockId = WIP_StockInsertSub(sqlConnectionString, productId, conditionId, accountTaxCodeId,
|
||||
int stockId = uow.StockRepository.WIP_StockInsertSub(productId, conditionId, accountTaxCodeId,
|
||||
accountJournalId, stockJournalType, entryDate, quantity, debitStatusId);
|
||||
|
||||
scope.Complete();
|
||||
CommitIfOwned(uow);
|
||||
|
||||
return stockId;
|
||||
}
|
||||
}
|
||||
|
||||
private int WIP_StockInsertSub(int productId, int conditionId, int accountTaxCodeId,
|
||||
int accountJournalId, int stockJournalTypeId, DateTime stockJournalEntryDate, int quantity, int statusDebitId)
|
||||
{
|
||||
stockJournalEntryDate = DateTime.SpecifyKind(stockJournalEntryDate, DateTimeKind.Utc);
|
||||
|
||||
// ensure account journal id hasn't already been added to stock table
|
||||
int count = 0;
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT Count(tblStock.StockID) AS CountOfID
|
||||
FROM tblStock
|
||||
WHERE (((tblStock.AccountJournalID)=@accountJouranlId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountJouranlId", accountJournalId);
|
||||
|
||||
count = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
throw new Exception("Add account journal entry already assigned to stock line.");
|
||||
}
|
||||
else if (count > 1)
|
||||
{
|
||||
throw new Exception("Houston we have a problem! An account journal entry is assigned to " + count + " stock lines.");
|
||||
}
|
||||
|
||||
// ensure the debit for the account journal transaction is to an 'Asset' account type
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
|
||||
FROM
|
||||
(tblAccountJournalPost
|
||||
INNER JOIN tblAccountChartOf
|
||||
ON tblAccountJournalPost.AccountChartOfID = tblAccountChartOf.AccountChartOfID)
|
||||
INNER JOIN tblAccountChartOfType
|
||||
ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
|
||||
WHERE
|
||||
tblAccountJournalPost.AmountGbp>=0
|
||||
AND tblAccountChartOfType.BasicType='Asset'
|
||||
AND tblAccountJournalPost.AccountJournalID=@accountJournalId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
if ((int)cmd.ExecuteScalar() < 1)
|
||||
{
|
||||
throw new Exception("Supplied AccountJournal entry must debit an 'Asset' account type.");
|
||||
}
|
||||
}
|
||||
|
||||
// get statusCreditId for stock journal type
|
||||
int statusCreditId;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockJournalType.StockStatusID_Credit
|
||||
FROM
|
||||
tblStockJournalType
|
||||
WHERE
|
||||
tblStockJournalType.StockJournalTypeID=@stockJournalTypeId
|
||||
AND tblStockJournalType.StockStatusID_Credit Is Not Null;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("Default credit status not set for StockJournalTypeID=" + stockJournalTypeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
statusCreditId = (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
// get/set an skuId
|
||||
int skuId = new Logic.Inventory.SkuService().GetSkuId(productId, conditionId, accountTaxCodeId, true);
|
||||
|
||||
// add the entry to the stock table (minus stockJournalId)
|
||||
int stockId = 0;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblStock
|
||||
(SkuID, AccountJournalID)
|
||||
OUTPUT INSERTED.StockID
|
||||
VALUES
|
||||
(@skuId, @accountJournalId);
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@skuId", skuId);
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
stockId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
// insert stock journal entry
|
||||
var journalPosts = new List<(int statusId, int quantity)>();
|
||||
journalPosts.Add((statusDebitId, quantity));
|
||||
journalPosts.Add((statusCreditId, (quantity * -1)));
|
||||
int stockJournalId = Stock.StockJournal.StockJournalInsert(sqlConnectionString, stockJournalTypeId, stockId, journalPosts, stockJournalEntryDate, true);
|
||||
|
||||
// update the stock table
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblStock
|
||||
SET StockJournalID=@stockJournalId
|
||||
WHERE StockID=@stockId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count < 1)
|
||||
{
|
||||
throw new Exception("New stock insert cancelled, failed to update StockJournalID");
|
||||
}
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
return stockId;
|
||||
});
|
||||
}
|
||||
|
||||
private void WIP_StockDelete(int stockId)
|
||||
{
|
||||
int accountJournalType = 0;
|
||||
int stockJournalType = 0;
|
||||
|
||||
// get stock and account types
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
WithUnitOfWork(uow =>
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// ensure stockId is owner-introduced
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockJournal.StockJournalTypeID, tblAccountJournal.AccountJournalTypeID
|
||||
FROM
|
||||
(tblStock INNER JOIN tblAccountJournal
|
||||
ON tblStock.AccountJournalID = tblAccountJournal.AccountJournalID)
|
||||
INNER JOIN tblStockJournal
|
||||
ON tblStock.StockJournalID = tblStockJournal.StockJournalID
|
||||
WHERE
|
||||
(((tblStock.StockID)=@stockId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
accountJournalType = reader.GetInt32(1);
|
||||
stockJournalType = reader.GetInt32(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Integrity check failed, cancelling StockDeleteOwnerIntroduced");
|
||||
}
|
||||
}
|
||||
}
|
||||
stockJournalType = uow.StockJournalRepository.ReadJournalTypeIdByStockId(stockId);
|
||||
|
||||
// check stock journal type is not restricted
|
||||
// owner inventory introduced
|
||||
@@ -211,22 +54,13 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
throw new Exception("Manual delete of this stock type is not supported, use the method that created it!");
|
||||
}
|
||||
|
||||
// check there is only one stock journal entry for stock item
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT Count(tblStockJournal.StockJournalID) AS CountOfStockJournalID
|
||||
FROM tblStockJournal
|
||||
WHERE (((tblStockJournal.StockID)=@stockId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
int count = (int)cmd.ExecuteScalar();
|
||||
// check there is only one stock journal entry for stock item (i.e. the source entry)
|
||||
int count = uow.StockJournalRepository.ReadJournalEntryCountByStockId(stockId);
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
throw new Exception("Delete " + count + " stock journal entries (other than source entry), before peforming this operation.");
|
||||
}
|
||||
}
|
||||
|
||||
// remove account journal entry
|
||||
WIP_StockDeleteSubAccountJournalEntry(sqlConnectionString, stockId);
|
||||
@@ -235,7 +69,23 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
WIP_StockDeleteSub(sqlConnectionString, stockId);
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void WIP_StockDeleteSub(int stockId)
|
||||
@@ -312,7 +162,7 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
}
|
||||
|
||||
// delete stock journal entry
|
||||
Core.Stock.StockJournal.StockJournalDelete(sqlConnectionString, stockJournalId);
|
||||
new Core.Logic.Inventory.StockJournalService().StockJournalDelete(stockJournalId);
|
||||
|
||||
// delete stock table entry
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
@@ -401,23 +251,14 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
DateTime stockJournalEntryDate;
|
||||
int stockJournalTypeId = 1;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
return WithUnitOfWork(uow =>
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// retrive info from purchase invoice line/transaction
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT tblAccountJournal.EntryDate
|
||||
FROM tblAccountJournal
|
||||
WHERE (((tblAccountJournal.AccountJournalID)=@accountJournalId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
stockJournalEntryDate = DateTime.SpecifyKind((DateTime)cmd.ExecuteScalar(), DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
return WIP_StockInsertSub(productId, conditionId, accountTaxCodeId, accountJournalId, stockJournalTypeId, stockJournalEntryDate, quantity, statusDebitId);
|
||||
stockJournalEntryDate = uow.JournalRepository.ReadJournalEntryDate(accountJournalId);
|
||||
int result = uow.StockRepository.WIP_StockInsertSub(
|
||||
productId, conditionId, accountTaxCodeId, accountJournalId, stockJournalTypeId, stockJournalEntryDate, quantity, statusDebitId);
|
||||
CommitIfOwned(uow);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
public int WIP_StockInsertOwnerIntroduced(decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId)
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace bnhtrade.Core.Logic.Stock
|
||||
var sku = readSku.BySkuNumber(statusTransaction.SkuNumber);
|
||||
|
||||
// get the status obj
|
||||
var status = uow.StockRepository.ReadStatus(new List<int> { statusTransaction.StockStatusId })[0];
|
||||
var status = uow.StockStatusRepository.ReadStatus(new List<int> { statusTransaction.StockStatusId })[0];
|
||||
|
||||
return new Model.Stock.StatusBalance(status, sku, entryList);
|
||||
}
|
||||
|
||||
@@ -233,532 +233,6 @@ namespace bnhtrade.Core
|
||||
}
|
||||
}
|
||||
|
||||
namespace Stock
|
||||
{
|
||||
public class StockJournal : UnitOfWorkBase
|
||||
{
|
||||
public static void StockJournalDelete(string sqlConnectionString, int stockJournalId)
|
||||
{
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// get date for journal entry
|
||||
DateTime entryDate;
|
||||
int stockId;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT tblStockJournal.EntryDate, StockID
|
||||
FROM tblStockJournal
|
||||
WHERE (((tblStockJournal.StockJournalID)=@stockJournalId));
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
entryDate = DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc);
|
||||
stockId = reader.GetInt32(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("StockJournalID=" + stockJournalId + " does not exist!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// is consistancy check required
|
||||
bool consistancyCheck;
|
||||
// build list of debits that are to be deleted
|
||||
var debitList = new List<int>();
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT tblStockJournalPost.StockStatusID
|
||||
FROM tblStockJournalPost
|
||||
WHERE (((tblStockJournalPost.StockJournalID)=@stockJournalId) AND ((tblStockJournalPost.Quantity)>0));
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
debitList.Add(reader.GetInt32(0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("StockJournalID=" + stockJournalId + " has no debits with quantity greater than zero!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check no credits for stockId & debit combination have been made since delete entry
|
||||
string stringSql = @"
|
||||
SELECT
|
||||
tblStockJournal.EntryDate
|
||||
FROM
|
||||
tblStockJournal
|
||||
INNER JOIN tblStockJournalPost
|
||||
ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID
|
||||
WHERE
|
||||
tblStockJournal.StockID=@stockId
|
||||
AND tblStockJournalPost.Quantity<0
|
||||
AND EntryDate>=@entryDate
|
||||
AND (";
|
||||
|
||||
bool firstDone = false;
|
||||
foreach (var item in debitList)
|
||||
{
|
||||
if (firstDone)
|
||||
{
|
||||
stringSql = stringSql + " OR ";
|
||||
}
|
||||
stringSql = stringSql + "tblStockJournalPost.StockStatusID=" + item;
|
||||
firstDone = true;
|
||||
}
|
||||
stringSql = stringSql + ");";
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(stringSql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
cmd.Parameters.AddWithValue("@entryDate", entryDate.ToUniversalTime());
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
consistancyCheck = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
consistancyCheck = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete the posts
|
||||
StockJournalPostDelete(conn, stockJournalId);
|
||||
|
||||
// delete journal entry
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM tblStockJournal
|
||||
WHERE StockJournalID=@stockJournalId;
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
throw new Exception("Failed to delete stock journal header.");
|
||||
}
|
||||
}
|
||||
|
||||
// consistanct check
|
||||
bool consistencyResult = true;
|
||||
if (consistancyCheck)
|
||||
{
|
||||
// run check
|
||||
consistencyResult = Stock.StockJournal.WIP_StockJournalConsistencyCheck(sqlConnectionString, stockId, debitList);
|
||||
}
|
||||
|
||||
if (consistencyResult)
|
||||
{
|
||||
// commit
|
||||
scope.Complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unable to delete stock journal entry, consistancy check failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void StockJournalPostInsert(SqlConnection conn, int stockId, int stockJournalId,
|
||||
List<(int statusId, int quantity)> journalPosts, bool isNewStock = false)
|
||||
{
|
||||
//checks
|
||||
if (journalPosts.Count > 2)
|
||||
{
|
||||
// I have purposely made the code to accept split transaction incase of future requirements, however, db design is simpler this way.
|
||||
throw new Exception("Stock journal does not currently support split transactions (greater than two posts)." + journalPosts.Count + " number posts attempted.");
|
||||
}
|
||||
else if (journalPosts.Count < 2)
|
||||
{
|
||||
// list not long enough
|
||||
throw new Exception("Stock journal entry requires minium of two posts, entry of " + journalPosts.Count + " number posts attempted.");
|
||||
}
|
||||
|
||||
if (journalPosts.Sum(item => item.quantity) != 0)
|
||||
{
|
||||
// credits and debits do not match
|
||||
throw new Exception("Sum of credits and debits do not resolve to zero.");
|
||||
}
|
||||
|
||||
// group credits and debits by status
|
||||
var dicStatusQty = new Dictionary<int, int>();
|
||||
foreach (var post in journalPosts)
|
||||
{
|
||||
if (dicStatusQty.ContainsKey(post.statusId) == false)
|
||||
{
|
||||
dicStatusQty.Add(post.statusId, post.quantity);
|
||||
}
|
||||
else
|
||||
{
|
||||
dicStatusQty[post.statusId] = dicStatusQty[post.statusId] + post.quantity;
|
||||
}
|
||||
}
|
||||
|
||||
// get isCreditOnly for each status
|
||||
var dicStatusIsCreditOnly = new Dictionary<int, bool>();
|
||||
foreach (var item in dicStatusQty)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT IsCreditOnly FROM tblStockStatus WHERE StockStatusID=@statusId;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@statusId", item.Key);
|
||||
|
||||
dicStatusIsCreditOnly.Add(item.Key, (bool)cmd.ExecuteScalar());
|
||||
}
|
||||
}
|
||||
|
||||
// check there is only one IsCreditOnly in list and it is allowed in this instance
|
||||
int isCreditOnlyCount = 0;
|
||||
foreach (var item in dicStatusIsCreditOnly)
|
||||
{
|
||||
if (item.Value)
|
||||
{
|
||||
isCreditOnlyCount = isCreditOnlyCount + 1;
|
||||
}
|
||||
}
|
||||
if (isNewStock == false && isCreditOnlyCount > 0)
|
||||
{
|
||||
throw new Exception("Attempted credit or debit to 'Is Credit Only' status not allowed, in this instance.");
|
||||
}
|
||||
if (isNewStock == true && isCreditOnlyCount != 1)
|
||||
{
|
||||
throw new Exception("StockID=" + stockId + ", each stock line must have only have one IsCreditOnly=True status assigned to it.");
|
||||
}
|
||||
|
||||
// ensure debit (or zero credit) isn't made to credit only status
|
||||
// need to do this check via original post list (i.e. journalPosts)
|
||||
foreach (var post in journalPosts)
|
||||
{
|
||||
// debit check
|
||||
if (post.quantity >= 0)
|
||||
{
|
||||
if (dicStatusIsCreditOnly[post.statusId] == true)
|
||||
{
|
||||
throw new Exception("Cannot make debit, or zero quantity credit, to credit only status. StatusID=" + post.statusId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// balance check for any credits (that are not isCreditOnly=true)
|
||||
foreach (var item in dicStatusQty)
|
||||
{
|
||||
if (item.Value < 0 && dicStatusIsCreditOnly[item.Key] == false)
|
||||
{
|
||||
int quantity = new Data.Database.Stock.ReadStatusBalance().ReadStatusBalanceByStockId(stockId, item.Key);
|
||||
|
||||
if (quantity + item.Value < 0)
|
||||
{
|
||||
throw new Exception("Credit status balance check failed. Available balance " + quantity + ", attempted credit " + item.Value * -1 + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get this far...
|
||||
// insert journal posts into database
|
||||
foreach (var post in journalPosts)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblStockJournalPost ( StockJournalID, StockStatusID, Quantity )
|
||||
VALUES ( @StockJournalId, @stockStatudId, @quantity );
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@StockJournalId", stockJournalId);
|
||||
cmd.Parameters.AddWithValue("@stockStatudId", post.statusId);
|
||||
cmd.Parameters.AddWithValue("@quantity", post.quantity);
|
||||
|
||||
// execute
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void StockJournalPostDelete(SqlConnection conn, int stockJournalId)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM tblStockJournalPost
|
||||
WHERE StockJournalID=@stockJournalId
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@StockJournalId", stockJournalId);
|
||||
|
||||
// execute
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
// the calling method must compete any transaction-scope on the connection
|
||||
}
|
||||
}
|
||||
|
||||
// can be used before commiting an sql insert, update or delete to the stock journal to ensure a status does not fall below 0
|
||||
// (unless the status is enabled to do so)
|
||||
// set empty list or statusIdEffected to null to check entier stock entries for consistency
|
||||
public static bool WIP_StockJournalConsistencyCheck(string sqlConnectionString, int stockId, List<int> statusIdEffected = null)
|
||||
{
|
||||
if (statusIdEffected == null)
|
||||
{
|
||||
statusIdEffected = new List<int>();
|
||||
}
|
||||
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// if no list supplied, build list of all used status' for stockId
|
||||
if (statusIdEffected.Count == 0)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockJournalPost.StockStatusID
|
||||
FROM
|
||||
tblStockJournal
|
||||
INNER JOIN tblStockJournalPost
|
||||
ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID
|
||||
WHERE
|
||||
tblStockJournal.StockID=@stockId
|
||||
GROUP BY
|
||||
tblStockJournalPost.StockStatusID;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
statusIdEffected.Add(reader.GetInt32(0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("No stock journal entries exist for StockID=" + stockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build the sql string to build creditCreate bool
|
||||
var dicStatusCreditOnly = new Dictionary<int, bool>();
|
||||
string sqlString = @"
|
||||
SELECT
|
||||
tblStockStatus.StockStatusID, tblStockStatus.IsCreditOnly
|
||||
FROM
|
||||
tblStockStatus ";
|
||||
|
||||
for (var i = 0; i < statusIdEffected.Count; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
sqlString = sqlString + " WHERE tblStockStatus.StockStatusID=" + statusIdEffected[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlString = sqlString + " OR tblStockStatus.StockStatusID=" + statusIdEffected[i];
|
||||
}
|
||||
|
||||
//if (i == (statusIdEffected.Count - 1))
|
||||
//{
|
||||
// sqlString = sqlString + ";";
|
||||
//}
|
||||
}
|
||||
sqlString = sqlString + " GROUP BY tblStockStatus.StockStatusID, tblStockStatus.IsCreditOnly;";
|
||||
|
||||
// run query & build dictionaries
|
||||
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
dicStatusCreditOnly.Add(reader.GetInt32(0), reader.GetBoolean(1));
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
dicStatusCreditOnly.Add(reader.GetInt32(0), reader.GetBoolean(1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Error, no journal entries found for StockID=" + stockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check integrity of supplied statusIds
|
||||
foreach (int statusId in statusIdEffected)
|
||||
{
|
||||
if (!dicStatusCreditOnly.ContainsKey(statusId))
|
||||
{
|
||||
throw new Exception("Supplied StatusId (" + statusId + ") doesn't exist for StockId=" + stockId);
|
||||
}
|
||||
}
|
||||
|
||||
// loop through each statudId and check integrity, if createdEnabled=false
|
||||
foreach (int statudId in statusIdEffected)
|
||||
{
|
||||
if (dicStatusCreditOnly[statudId] == false)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockJournal.EntryDate, tblStockJournalPost.Quantity
|
||||
FROM
|
||||
tblStockJournal
|
||||
INNER JOIN tblStockJournalPost
|
||||
ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID
|
||||
WHERE
|
||||
tblStockJournal.StockID=@stockId
|
||||
AND tblStockJournalPost.StockStatusID=@statudId
|
||||
ORDER BY
|
||||
tblStockJournal.EntryDate;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
cmd.Parameters.AddWithValue("@statudId", statudId);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
// read first line into variables
|
||||
reader.Read();
|
||||
int quantity = reader.GetInt32(1);
|
||||
DateTime entryDate = DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// compare to next values
|
||||
if (reader.Read())
|
||||
{
|
||||
DateTime nextEntryDate = DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc);
|
||||
// don't check quantites for transactions on same date
|
||||
if (entryDate == nextEntryDate)
|
||||
{
|
||||
entryDate = nextEntryDate;
|
||||
quantity = quantity + reader.GetInt32(1);
|
||||
}
|
||||
// check if dates are different
|
||||
else
|
||||
{
|
||||
if (quantity < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
entryDate = nextEntryDate;
|
||||
quantity = quantity + reader.GetInt32(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end if no records, check quantity
|
||||
else
|
||||
{
|
||||
if (quantity < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// get this far, all good
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int StockTransactionTypeIdInsert(string sqlConnectionString, int stockJournalTypeId, string typeCode, bool transScopeSuppress = true)
|
||||
{
|
||||
int transactionTypeId;
|
||||
var scopeOption = new TransactionScopeOption();
|
||||
if (transScopeSuppress)
|
||||
{
|
||||
scopeOption = TransactionScopeOption.Suppress;
|
||||
}
|
||||
else
|
||||
{
|
||||
scopeOption = TransactionScopeOption.Required;
|
||||
}
|
||||
|
||||
using (TransactionScope scope = new TransactionScope(scopeOption))
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
//check to see if type already exists, return id of that if it does
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblStockSkuTransactionType.StockSkuTransactionTypeID
|
||||
FROM
|
||||
tblStockSkuTransactionType
|
||||
WHERE
|
||||
tblStockSkuTransactionType.StockJournalTypeID=@stockJournalTypeId
|
||||
AND tblStockSkuTransactionType.TypeCode=@typeCode;
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@typeCode", typeCode);
|
||||
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (!(obj == null || obj == DBNull.Value))
|
||||
{
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
// insert new and retrive new value
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblStockSkuTransactionType
|
||||
( TypeName, StockJournalTypeID, TypeCode )
|
||||
OUTPUT
|
||||
INSERTED.StockSkuTransactionTypeID
|
||||
VALUES
|
||||
( @typeName, @stockJournalTypeId, @typeCode );
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@typeName", typeCode);
|
||||
cmd.Parameters.AddWithValue("@typeCode", typeCode);
|
||||
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
|
||||
|
||||
transactionTypeId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
return transactionTypeId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MiscFunction
|
||||
{
|
||||
public static string TraceMessage(
|
||||
|
||||
Reference in New Issue
Block a user