mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-03-25 17:17:15 +00:00
wip
This commit is contained in:
633
src/bnhtrade.Core/Logic/Account/AccountJournalService.cs
Normal file
633
src/bnhtrade.Core/Logic/Account/AccountJournalService.cs
Normal file
@@ -0,0 +1,633 @@
|
||||
using bnhtrade.Core.Data.Database;
|
||||
using bnhtrade.Core.Data.Database.Repository.Implementation;
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class AccountJournalService : UnitOfWorkBase
|
||||
{
|
||||
public AccountJournalService()
|
||||
{
|
||||
}
|
||||
|
||||
internal AccountJournalService(IUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
|
||||
public int JournalInsert(int journalTypeId, DateTime entryDate, string currencyCode,
|
||||
decimal amount, int debitAccountId = 0, int creditAccountId = 0, bool lockEntry = false)
|
||||
{
|
||||
return WithUnitOfWork(uow =>
|
||||
{
|
||||
// insert header record
|
||||
int journalId = uow.AccountJournalRepository.AccountJournalInsert(journalTypeId, entryDate, lockEntry);
|
||||
|
||||
// insert post record
|
||||
int defaultDebit;
|
||||
int defaultCredit;
|
||||
|
||||
// ensure their are no other entries
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
|
||||
FROM
|
||||
tblAccountJournalPost
|
||||
WHERE
|
||||
(((tblAccountJournalPost.AccountJournalID)=@AccountJournalID));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@AccountJournalID", journalId);
|
||||
|
||||
int count = (int)cmd.ExecuteScalar();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
throw new Exception("Unable the insert journal posts, post already present AccountJournalID=" + journalId);
|
||||
}
|
||||
}
|
||||
|
||||
//checks
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblAccountJournalType.ChartOfAccountID_Debit, tblAccountJournalType.ChartOfAccountID_Credit
|
||||
FROM
|
||||
tblAccountJournal
|
||||
INNER JOIN tblAccountJournalType
|
||||
ON tblAccountJournal.AccountJournalTypeID = tblAccountJournalType.AccountJournalTypeID
|
||||
WHERE
|
||||
(((tblAccountJournal.AccountJournalID)=@journalId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@journalId", journalId);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
// debit check
|
||||
if (reader.IsDBNull(0))
|
||||
{
|
||||
if (debitAccountId == 0)
|
||||
{
|
||||
throw new Exception("Debit Account ID required, default not set for journal type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultDebit = reader.GetInt32(0);
|
||||
if (debitAccountId == 0)
|
||||
{
|
||||
debitAccountId = defaultDebit;
|
||||
}
|
||||
else if (debitAccountId != defaultDebit)
|
||||
{
|
||||
throw new Exception("Debit Account ID supplied does not match default set for journal type");
|
||||
}
|
||||
|
||||
}
|
||||
// credit check
|
||||
if (reader.IsDBNull(1))
|
||||
{
|
||||
if (creditAccountId == 0)
|
||||
{
|
||||
throw new Exception("Credit Account ID required, default not set for journal type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultCredit = reader.GetInt32(1);
|
||||
if (creditAccountId == 0)
|
||||
{
|
||||
creditAccountId = defaultCredit;
|
||||
}
|
||||
else if (creditAccountId != defaultCredit)
|
||||
{
|
||||
throw new Exception("Credit Account ID supplied does not match default set for journal type");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("AccountJournalID '" + journalId + "' does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// currency conversion
|
||||
if (currencyCode != "GBP")
|
||||
{
|
||||
amount = new Logic.Account.CurrencyService().CurrencyConvertToGbp(currencyCode, amount, entryDate);
|
||||
}
|
||||
|
||||
// ensure decimal is rounded
|
||||
amount = Math.Round(amount, 2);
|
||||
|
||||
// insert debit post
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAccountJournalPost
|
||||
(AccountJournalID, AccountChartOfID, AmountGbp)
|
||||
VALUES
|
||||
(@AccountJournalId, @AccountChartOfId, @AmountGbp)
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@AccountJournalId", journalId);
|
||||
cmd.Parameters.AddWithValue("@AccountChartOfId", debitAccountId);
|
||||
cmd.Parameters.AddWithValue("@AmountGbp", amount);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// insert credit post
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAccountJournalPost
|
||||
(AccountJournalID, AccountChartOfID, AmountGbp)
|
||||
VALUES
|
||||
(@AccountJournalId, @AccountChartOfId, @AmountGbp)
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@AccountJournalId", journalId);
|
||||
cmd.Parameters.AddWithValue("@AccountChartOfId", creditAccountId);
|
||||
cmd.Parameters.AddWithValue("@AmountGbp", (amount * -1));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CommitIfOwned(uow);
|
||||
return journalId;
|
||||
});
|
||||
}
|
||||
|
||||
public Dictionary<int, Core.Model.Account.Journal> ReadJournal(List<int> journalIdList)
|
||||
{
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT tblAccountJournal.AccountJournalID
|
||||
,tblAccountJournal.AccountJournalTypeID
|
||||
,tblAccountJournal.EntryDate
|
||||
,tblAccountJournal.PostDate
|
||||
,tblAccountJournal.LastModified
|
||||
,tblAccountJournal.IsLocked
|
||||
,tblAccountJournalPost.AccountJournalPostID
|
||||
,tblAccountJournalPost.AccountChartOfID
|
||||
,tblAccountJournalPost.AmountGbp
|
||||
FROM tblAccountJournal
|
||||
INNER JOIN tblAccountJournalPost ON tblAccountJournal.AccountJournalID = tblAccountJournalPost.AccountJournalID
|
||||
WHERE 1 = 1 ";
|
||||
|
||||
// build the where statments
|
||||
if (journalIdList.Any())
|
||||
{
|
||||
sqlBuilder.In("tblAccountJournal.AccountJournalID", journalIdList, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
// build tuple list
|
||||
var dbJournalList = new List<(
|
||||
int AccountJournalId
|
||||
, int AccountJournalTypeId
|
||||
, DateTime EntryDate
|
||||
, DateTime PostDate
|
||||
, DateTime LastModified
|
||||
, bool IsLocked
|
||||
)>();
|
||||
|
||||
var dbJournalPostList = new List<(
|
||||
int AccountJournalId
|
||||
, int AccountJournalPostId
|
||||
, int AccountChartOfId
|
||||
, decimal AmountGbp
|
||||
)>();
|
||||
|
||||
|
||||
bool hasRows = false;
|
||||
|
||||
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())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
hasRows = true;
|
||||
int lastJournalId = 0;
|
||||
while (reader.Read())
|
||||
{
|
||||
// read journal header
|
||||
int journalId = reader.GetInt32(0);
|
||||
if (journalId != lastJournalId)
|
||||
{
|
||||
lastJournalId = journalId;
|
||||
|
||||
(int AccountJournalId
|
||||
, int AccountJournalTypeId
|
||||
, DateTime EntryDate
|
||||
, DateTime PostDate
|
||||
, DateTime LastModified
|
||||
, bool IsLocked
|
||||
)
|
||||
journal =
|
||||
(journalId
|
||||
, reader.GetInt32(1)
|
||||
, DateTime.SpecifyKind(reader.GetDateTime(2), DateTimeKind.Utc)
|
||||
, DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc)
|
||||
, DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc)
|
||||
, reader.GetBoolean(5)
|
||||
);
|
||||
|
||||
dbJournalList.Add(journal);
|
||||
}
|
||||
|
||||
// read journal posts
|
||||
(int AccountJournalId
|
||||
, int AccountJournalPostId
|
||||
, int AccountChartOfId
|
||||
, decimal AmountGbp
|
||||
)
|
||||
journalPost =
|
||||
(journalId
|
||||
, reader.GetInt32(6)
|
||||
, reader.GetInt32(7)
|
||||
, reader.GetDecimal(8)
|
||||
);
|
||||
|
||||
dbJournalPostList.Add(journalPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var returnList = new Dictionary<int, Core.Model.Account.Journal>();
|
||||
if (hasRows)
|
||||
{
|
||||
// build lists to filter db results by
|
||||
var journalTypeIdList = new List<int>();
|
||||
var accountIdList = new List<int>();
|
||||
foreach (var item in dbJournalList)
|
||||
{
|
||||
journalTypeIdList.Add(item.AccountJournalTypeId);
|
||||
}
|
||||
foreach (var item in dbJournalPostList)
|
||||
{
|
||||
accountIdList.Add(item.AccountChartOfId);
|
||||
}
|
||||
|
||||
// get journalTypes from db
|
||||
var journalTypeDict = new AccountJournalRepository(_connection, _transaction).ReadJournalType(journalTypeIdList);
|
||||
|
||||
// get accounts from db
|
||||
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountIdList);
|
||||
|
||||
// build final return dictionary
|
||||
foreach (var dbJournal in dbJournalList)
|
||||
{
|
||||
// build posts
|
||||
var newPosts = new List<Core.Model.Account.Journal.Post>();
|
||||
foreach (var dbJournalPost in dbJournalPostList)
|
||||
{
|
||||
if (dbJournalPost.AccountJournalId == dbJournal.AccountJournalId)
|
||||
{
|
||||
var newPost = new Core.Model.Account.Journal.Post(
|
||||
dbJournalPost.AccountJournalPostId
|
||||
, accountDict[dbJournalPost.AccountChartOfId]
|
||||
, dbJournalPost.AmountGbp);
|
||||
|
||||
newPosts.Add(newPost);
|
||||
}
|
||||
}
|
||||
|
||||
// create the journal
|
||||
var newJournal = new Core.Model.Account.Journal(
|
||||
dbJournal.AccountJournalId
|
||||
, journalTypeDict[dbJournal.AccountJournalTypeId]
|
||||
, newPosts
|
||||
, dbJournal.EntryDate
|
||||
, dbJournal.PostDate
|
||||
, dbJournal.LastModified
|
||||
, dbJournal.IsLocked);
|
||||
|
||||
returnList.Add(dbJournal.AccountJournalId, newJournal);
|
||||
}
|
||||
}
|
||||
// all done, return the list herevar
|
||||
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>
|
||||
/// Old code needs sorting
|
||||
/// </summary>
|
||||
public bool AccountJournalPostInsert(IUnitOfWork uow, int journalId, DateTime entryDate, string currencyCode, decimal amount, int debitAccountId = 0, int creditAccountId = 0)
|
||||
{
|
||||
int defaultDebit;
|
||||
int defaultCredit;
|
||||
entryDate = DateTime.SpecifyKind(entryDate, DateTimeKind.Utc);
|
||||
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// ensure their are no other entries
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
|
||||
FROM
|
||||
tblAccountJournalPost
|
||||
WHERE
|
||||
(((tblAccountJournalPost.AccountJournalID)=@AccountJournalID));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@AccountJournalID", journalId);
|
||||
|
||||
int count = (int)cmd.ExecuteScalar();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
throw new Exception("Unable the insert journal posts, post already present AccountJournalID=" + journalId);
|
||||
}
|
||||
}
|
||||
|
||||
//checks
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
tblAccountJournalType.ChartOfAccountID_Debit, tblAccountJournalType.ChartOfAccountID_Credit
|
||||
FROM
|
||||
tblAccountJournal
|
||||
INNER JOIN tblAccountJournalType
|
||||
ON tblAccountJournal.AccountJournalTypeID = tblAccountJournalType.AccountJournalTypeID
|
||||
WHERE
|
||||
(((tblAccountJournal.AccountJournalID)=@journalId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@journalId", journalId);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
// debit check
|
||||
if (reader.IsDBNull(0))
|
||||
{
|
||||
if (debitAccountId == 0)
|
||||
{
|
||||
throw new Exception("Debit Account ID required, default not set for journal type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultDebit = reader.GetInt32(0);
|
||||
if (debitAccountId == 0)
|
||||
{
|
||||
debitAccountId = defaultDebit;
|
||||
}
|
||||
else if (debitAccountId != defaultDebit)
|
||||
{
|
||||
throw new Exception("Debit Account ID supplied does not match default set for journal type");
|
||||
}
|
||||
|
||||
}
|
||||
// credit check
|
||||
if (reader.IsDBNull(1))
|
||||
{
|
||||
if (creditAccountId == 0)
|
||||
{
|
||||
throw new Exception("Credit Account ID required, default not set for journal type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultCredit = reader.GetInt32(1);
|
||||
if (creditAccountId == 0)
|
||||
{
|
||||
creditAccountId = defaultCredit;
|
||||
}
|
||||
else if (creditAccountId != defaultCredit)
|
||||
{
|
||||
throw new Exception("Credit Account ID supplied does not match default set for journal type");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("AccountJournalID '" + journalId + "' does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// currency conversion
|
||||
if (currencyCode != "GBP")
|
||||
{
|
||||
amount = new Logic.Account.CurrencyService().CurrencyConvertToGbp(currencyCode, amount, entryDate);
|
||||
}
|
||||
|
||||
// ensure decimal is rounded
|
||||
amount = Math.Round(amount, 2);
|
||||
|
||||
// insert debit post
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAccountJournalPost
|
||||
(AccountJournalID, AccountChartOfID, AmountGbp)
|
||||
VALUES
|
||||
(@AccountJournalId, @AccountChartOfId, @AmountGbp)
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@AccountJournalId", journalId);
|
||||
cmd.Parameters.AddWithValue("@AccountChartOfId", debitAccountId);
|
||||
cmd.Parameters.AddWithValue("@AmountGbp", amount);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// insert credit post
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAccountJournalPost
|
||||
(AccountJournalID, AccountChartOfID, AmountGbp)
|
||||
VALUES
|
||||
(@AccountJournalId, @AccountChartOfId, @AmountGbp)
|
||||
", conn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@AccountJournalId", journalId);
|
||||
cmd.Parameters.AddWithValue("@AccountChartOfId", creditAccountId);
|
||||
cmd.Parameters.AddWithValue("@AmountGbp", (amount * -1));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool AccountJournalPostUpdate(int journalId, string currencyCode, decimal amount, int debitAccountId = 0, int creditAccountId = 0)
|
||||
{
|
||||
// retrive journal entry date
|
||||
DateTime entryDate;
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
tblAccountJournal.EntryDate
|
||||
FROM
|
||||
tblAccountJournal
|
||||
WHERE
|
||||
(((tblAccountJournal.AccountJournalID)=@accountJournalId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
|
||||
|
||||
entryDate = DateTime.SpecifyKind((DateTime)cmd.ExecuteScalar(), DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
// delete the original posts
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM
|
||||
tblAccountJournalPost
|
||||
WHERE
|
||||
(((tblAccountJournalPost.AccountJournalID)=@accountJournalId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
//insert new posts
|
||||
bool postResult = AccountJournalPostInsert(journalId, entryDate, currencyCode, amount, debitAccountId, creditAccountId);
|
||||
|
||||
// update modified date on journal
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
UPDATE
|
||||
tblAccountJournal
|
||||
SET
|
||||
tblAccountJournal.LastModified=@utcNow
|
||||
WHERE
|
||||
(((tblAccountJournal.AccountJournalID)=@accountJournalId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
|
||||
cmd.Parameters.AddWithValue("@utcNow", DateTime.UtcNow);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Old code needs sorting
|
||||
/// </summary>
|
||||
public bool DeleteJournal(int accountJournalId)
|
||||
{
|
||||
bool IsLocked = ReadJournalIsLocked(accountJournalId);
|
||||
if (IsLocked == true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// make the delete
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblAccountJournalPost
|
||||
WHERE AccountJournalID=@accountJournalId;";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
int rows = cmd.ExecuteNonQuery();
|
||||
|
||||
if (rows == 0)
|
||||
{
|
||||
throw new Exception("Journal entry and/or entry posts do not exist for AccountJournalId=" + accountJournalId);
|
||||
}
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblAccountJournal
|
||||
WHERE AccountJournalID=@accountJournalId;";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class JournalService : UnitOfWorkBase
|
||||
{
|
||||
public JournalService()
|
||||
{
|
||||
}
|
||||
|
||||
internal JournalService(IUnitOfWork unitOfWork) : base(unitOfWork)
|
||||
{
|
||||
}
|
||||
|
||||
public int JournalInsert(int journalTypeId, DateTime entryDate, string currencyCode,
|
||||
decimal amount, int debitAccountId = 0, int creditAccountId = 0, bool lockEntry = false)
|
||||
{
|
||||
return WithUnitOfWork(uow =>
|
||||
{
|
||||
int journalId = uow.AccountJournalRepository.AccountJournalInsert(journalTypeId, entryDate, currencyCode,
|
||||
amount, debitAccountId, creditAccountId, lockEntry);
|
||||
CommitIfOwned(uow);
|
||||
return journalId;
|
||||
});
|
||||
}
|
||||
|
||||
public bool JournalDelete(int accountJournalId)
|
||||
{
|
||||
return WithUnitOfWork(uow =>
|
||||
{
|
||||
bool result = uow.AccountJournalRepository.DeleteJournal(accountJournalId);
|
||||
CommitIfOwned(uow);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using bnhtrade.Core.Logic.Account;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -22,9 +23,9 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
|
||||
return WithUnitOfWork(uow =>
|
||||
{
|
||||
stockJournalEntryDate = uow.AccountJournalRepository.ReadJournalEntryDate(accountJournalId);
|
||||
int result = uow.StockRepository.WIP_StockInsertSub(
|
||||
productId, conditionId, accountTaxCodeId, accountJournalId, stockJournalTypeId, stockJournalEntryDate, quantity, statusDebitId);
|
||||
stockJournalEntryDate = new AccountJournalService(uow).ReadJournalEntryDate(accountJournalId);
|
||||
int result = WIP_StockInsertSub(
|
||||
uow, productId, conditionId, accountTaxCodeId, accountJournalId, stockJournalTypeId, stockJournalEntryDate, quantity, statusDebitId);
|
||||
CommitIfOwned(uow);
|
||||
return result;
|
||||
});
|
||||
@@ -48,15 +49,68 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId)
|
||||
{
|
||||
// add account journal entry
|
||||
int accountJournalId = new Logic.Account.JournalService(uow).JournalInsert(accountJournalType, entryDate, currencyCode, amount);
|
||||
int accountJournalId = new Logic.Account.AccountJournalService(uow).JournalInsert(accountJournalType, entryDate, currencyCode, amount);
|
||||
|
||||
// make the stock insert
|
||||
int stockId = uow.StockRepository.WIP_StockInsertSub(productId, conditionId, accountTaxCodeId,
|
||||
int stockId = WIP_StockInsertSub(uow, productId, conditionId, accountTaxCodeId,
|
||||
accountJournalId, stockJournalType, entryDate, quantity, debitStatusId);
|
||||
|
||||
return stockId;
|
||||
}
|
||||
|
||||
private int WIP_StockInsertSub(IUnitOfWork uow, 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 = uow.StockRepository.CountStockTableRecords(new List<int> { accountJournalId });
|
||||
|
||||
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
|
||||
bool isIt = uow.AccountJournalRepository.IsJournalDebitAssetType(accountJournalId);
|
||||
if (!isIt)
|
||||
{
|
||||
throw new Exception("Supplied AccountJournal entry must debit an 'Asset' account type.");
|
||||
}
|
||||
|
||||
// get statusCreditId for stock journal type
|
||||
int? statusCreditId = uow.StockJournalRepository.ReadTypeIdStatusCreditId(stockJournalTypeId);
|
||||
|
||||
if (statusCreditId == null)
|
||||
{
|
||||
throw new Exception("Default credit status not set for StockJournalTypeID=" + stockJournalTypeId);
|
||||
}
|
||||
|
||||
// get/set an skuId
|
||||
int skuId = new Logic.Inventory.SkuService(uow).GetSkuId(productId, conditionId, accountTaxCodeId, true);
|
||||
|
||||
// add the entry to the stock table (minus stockJournalId)
|
||||
int stockId = uow.StockRepository.InsertNewStock(skuId, accountJournalId);
|
||||
|
||||
// insert stock journal entry
|
||||
var journalPosts = new List<(int statusId, int quantity)>();
|
||||
journalPosts.Add((statusDebitId, quantity));
|
||||
journalPosts.Add((statusCreditId.Value, (quantity * -1)));
|
||||
int stockJournalId = uow.StockJournalRepository.StockJournalInsert(stockJournalTypeId, stockId, journalPosts, stockJournalEntryDate, true);
|
||||
|
||||
// update the stock table
|
||||
count = uow.StockRepository.UpdateStockJournalId(stockId, stockJournalId);
|
||||
if (count < 1)
|
||||
{
|
||||
throw new Exception("New stock insert cancelled, failed to update StockJournalID");
|
||||
}
|
||||
|
||||
return stockId;
|
||||
}
|
||||
|
||||
public void WIP_StockDeletePurchase(int stockId)
|
||||
{
|
||||
@@ -162,8 +216,7 @@ namespace bnhtrade.Core.Logic.Inventory
|
||||
}
|
||||
|
||||
// delete account journal entry
|
||||
uow.AccountJournalRepository.DeleteJournal(accountJournalId);
|
||||
new AccountJournalService(uow).DeleteJournal(accountJournalId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using bnhtrade.Core.Data.Database.Repository.Implementation;
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using bnhtrade.Core.Logic.Account;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -10,17 +12,50 @@ namespace bnhtrade.Core.Logic.Purchase
|
||||
{
|
||||
public class PurchaseService : UnitOfWorkBase
|
||||
{
|
||||
private static int accountJournalTypeIdNet = 1;
|
||||
private static int accountJournalTypeIdTax = 2;
|
||||
private static int stockJournalTypeId = 1;
|
||||
private static int creditAccountId = 59;
|
||||
private static int creditStatusId = 13;
|
||||
private static int defaultAccountId = 138;
|
||||
|
||||
public PurchaseService() : base() { }
|
||||
|
||||
internal PurchaseService(IUnitOfWork unitOfWork) : base(unitOfWork) { }
|
||||
|
||||
public void WIP_PurchaseLineTransactionNetInsert(int purchaseLineId, string currencyCode, decimal amountNet, DateTime entryDate, int debitAccountId = 0)
|
||||
{
|
||||
WithUnitOfWork(uow =>
|
||||
// default to 'Inventory, Receivable/Processing'
|
||||
if (debitAccountId < 1)
|
||||
{
|
||||
uow.PurchaseRepository.WIP_PurchaseLineTransactionNetInsert(purchaseLineId, currencyCode, amountNet, entryDate, debitAccountId);
|
||||
CommitIfOwned(uow);
|
||||
});
|
||||
debitAccountId = defaultAccountId;
|
||||
}
|
||||
|
||||
// create account journal entry
|
||||
int journalId = new Data.Database.Repository.Implementation.AccountJournalRepository(_connection, _transaction).
|
||||
AccountJournalInsert(accountJournalTypeIdNet, entryDate, currencyCode, amountNet, debitAccountId);
|
||||
|
||||
// add transaction to purchase line transaction table
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO
|
||||
tblPurchaseLineTransaction
|
||||
( PurchaseLineID, AccountJournalID )
|
||||
VALUES
|
||||
( @purchaseLineID, @accountJournalID );";
|
||||
|
||||
cmd.Parameters.AddWithValue("@purchaseLineID", purchaseLineId);
|
||||
cmd.Parameters.AddWithValue("@accountJournalID", journalId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
throw new Exception("Failed to insert record to tblPurchaseLineTransaction table");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WIP_PurchaseLineTransactionNetUpdate(int accountJouranlId, string currencyCode, decimal amountNet, int debitAccountId)
|
||||
@@ -28,17 +63,60 @@ namespace bnhtrade.Core.Logic.Purchase
|
||||
WithUnitOfWork(uow =>
|
||||
{
|
||||
uow.PurchaseRepository.WIP_PurchaseLineTransactionNetUpdate(accountJouranlId, currencyCode, amountNet, debitAccountId);
|
||||
new AccountJournalService(uow).AccountJournalPostUpdate(accountJouranlId, currencyCode, amountNet, creditAccountId);
|
||||
CommitIfOwned(uow);
|
||||
});
|
||||
}
|
||||
|
||||
public void WIP_PurchaseLineTransactionDelete(int purchaseLineId, int accountJournalId)
|
||||
{
|
||||
WithUnitOfWork(uow =>
|
||||
// check accountJournalId does not exist in stock table
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
uow.PurchaseRepository.WIP_PurchaseLineTransactionDelete(purchaseLineId, accountJournalId);
|
||||
CommitIfOwned(uow);
|
||||
});
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT StockID
|
||||
FROM tblStock
|
||||
WHERE AccountJournalID=@accountJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
throw new Exception("Integrity check failure! AccountJournalID=" + accountJournalId + " exists multiple time in stock table!");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Delete stock first before proceeding, AccountJournalID=" + accountJournalId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete line in purchase line transaction table
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblPurchaseLineTransaction
|
||||
WHERE AccountJournalID=@accountJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
throw new Exception("Operation cancelled, failed to delete entry in tblPurchaseLineTransaction WHERE AccountJournalID=" + accountJournalId);
|
||||
}
|
||||
}
|
||||
|
||||
// delete account journal entry
|
||||
new AccountJournalService(uow).DeleteJournal(accountJournalId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user