This commit is contained in:
2025-07-10 14:33:13 +01:00
parent d4170d2b80
commit ee487db21f
11 changed files with 648 additions and 620 deletions

View File

@@ -1,5 +1,6 @@
using bnhtrade.Core.Data.Database._BoilerPlate; using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface; using bnhtrade.Core.Data.Database.Repository.Interface;
using bnhtrade.Core.Model.Account;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -21,7 +22,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
// create // create
// //
public int AccountJournalInsert(int journalTypeId, DateTime entryDate, bool lockEntry = false) public int InsertJournalHeader(int accountJournalTypeId, DateTime entryDate, bool lockEntry = false)
{ {
// ensure date is UTC // ensure date is UTC
if (entryDate.Kind != DateTimeKind.Utc) if (entryDate.Kind != DateTimeKind.Utc)
@@ -44,7 +45,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
(@journalTypeId, @entryDate, @lockEntry);"; (@journalTypeId, @entryDate, @lockEntry);";
// add parameters // add parameters
cmd.Parameters.AddWithValue("@journalTypeId", journalTypeId); cmd.Parameters.AddWithValue("@journalTypeId", accountJournalTypeId);
cmd.Parameters.AddWithValue("@entryDate", entryDate.ToUniversalTime()); cmd.Parameters.AddWithValue("@entryDate", entryDate.ToUniversalTime());
cmd.Parameters.AddWithValue("@lockEntry", lockEntry); cmd.Parameters.AddWithValue("@lockEntry", lockEntry);
@@ -55,11 +56,168 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
return journalId; return journalId;
} }
public int InsertJournalPost(int accountJournalId, int accountChartOfId, decimal amountGbp)
{
if (accountJournalId <= 0)
{
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
}
if (accountChartOfId <= 0)
{
throw new ArgumentException("Invalid account chart of ID provided.", nameof(accountChartOfId));
}
if (amountGbp == 0)
{
throw new ArgumentException("Amount cannot be zero.", nameof(amountGbp));
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
INSERT INTO tblAccountJournalPost
(AccountJournalID, AccountChartOfID, AmountGbp)
OUTPUT INSERTED.AccountJournalPostID
VALUES
(@accountJournalId, @accountChartOfId, @amountGbp);";
// add parameters
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
cmd.Parameters.AddWithValue("@accountChartOfId", accountChartOfId);
cmd.Parameters.AddWithValue("@amountGbp", amountGbp);
// execute
return (int)cmd.ExecuteScalar();
}
}
// //
// read // read
// //
public Dictionary<int, Model.Account.JournalBuilder> ReadJournalBuilder(List<int> journalIdList)
{
var sqlBuilder = new SqlWhereBuilder();
var returnDict = new Dictionary<int, Model.Account.JournalBuilder>();
//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;
}
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())
{
while (reader.Read())
{
int journalId = reader.GetInt32(0);
if (returnDict.ContainsKey(journalId) == false)
{
var journalBuilder = new Model.Account.JournalBuilder();
journalBuilder.JournalId = journalId;
journalBuilder.JournalTypeId = reader.GetInt32(1);
journalBuilder.EntryDate = DateTime.SpecifyKind(reader.GetDateTime(2), DateTimeKind.Utc);
journalBuilder.PostDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
journalBuilder.LastModified = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
journalBuilder.IsLocked = reader.GetBoolean(5);
journalBuilder.JournalBuilderPosts = new List<Model.Account.JournalBuilder.JournalPostBuilder>();
returnDict.Add(journalId, journalBuilder);
}
var journalBuilderLine = new Model.Account.JournalBuilder.JournalPostBuilder();
journalBuilderLine.PostId = reader.GetInt32(6);
journalBuilderLine.AccountId = reader.GetInt32(7);
journalBuilderLine.AmountGbp = reader.GetDecimal(8);
returnDict[journalId].JournalBuilderPosts.Add(journalBuilderLine);
}
}
}
return returnDict;
}
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);
}
}
public int CountJournalPosts(int accountJournalId)
{
if (accountJournalId <= 0)
{
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
SELECT
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
FROM
tblAccountJournalPost
WHERE
(((tblAccountJournalPost.AccountJournalID)=@AccountJournalID));";
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
return (int)cmd.ExecuteScalar();
}
}
public bool IsJournalDebitAssetType(int accountJournalId) public bool IsJournalDebitAssetType(int accountJournalId)
{ {
@@ -98,12 +256,12 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
/// <summary> /// <summary>
/// Test for locked journal entry /// Test for locked journal entry
/// </summary> /// </summary>
/// <returns>False on locked journal entry</returns> /// <returns>True/False or null on no records found</returns>
public bool ReadJournalIsLocked(int journalId) public bool? IsJournalLocked(int accountJournalId)
{ {
if (journalId <= 0) if (accountJournalId <= 0)
{ {
throw new ArgumentException("Invalid journal ID provided.", nameof(journalId)); throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
} }
string sql = @" string sql = @"
@@ -119,12 +277,12 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction; cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@accountJournalId", journalId); cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
object obj = cmd.ExecuteScalar(); object obj = cmd.ExecuteScalar();
if (obj == null) if (obj == null || obj == DBNull.Value)
{ {
throw new Exception("Journal entry not found for AccountJournalID=" + journalId); return null;
} }
else else
{ {
@@ -133,15 +291,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
} }
} }
public List<(int, string, int?, int?)> ReadJournalType(List<int> accountJournalTypeIds = null, List<string> typeTitles = null)
public Dictionary<int, Model.Account.JournalType> ReadJournalType(List<int> journalTypeIds = null, List<string> typeTitles = null)
{ {
var returnList = new List<(int, string, int?, int?)>();
var sqlBuilder = new SqlWhereBuilder(); var sqlBuilder = new SqlWhereBuilder();
// create the return (emptyP list) here
var returnList = new Dictionary<int, Model.Account.JournalType>();
sqlBuilder.Init();
//build sql query //build sql query
string sql = @" string sql = @"
SELECT [AccountJournalTypeID] SELECT [AccountJournalTypeID]
@@ -152,9 +306,9 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
WHERE 1 = 1 "; WHERE 1 = 1 ";
// build the where statments // build the where statments
if (journalTypeIds.Any()) if (accountJournalTypeIds.Any())
{ {
sqlBuilder.In("AccountJournalTypeID", journalTypeIds, "AND"); sqlBuilder.In("AccountJournalTypeID", accountJournalTypeIds, "AND");
} }
if (typeTitles.Any()) if (typeTitles.Any())
{ {
@@ -167,10 +321,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
sql = sql + sqlBuilder.SqlWhereString; sql = sql + sqlBuilder.SqlWhereString;
} }
// create dictionary to add credit/debit accounts on after db read
var creditDict = new Dictionary<int, int>();
var debitDict = new Dictionary<int, int>();
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
@@ -182,8 +332,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
} }
using (SqlDataReader reader = cmd.ExecuteReader()) using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{ {
while (reader.Read()) while (reader.Read())
{ {
@@ -191,62 +339,150 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
int journalTypeId = reader.GetInt32(0); int journalTypeId = reader.GetInt32(0);
string title = reader.GetString(1); string title = reader.GetString(1);
int? debitAccountId = null; int? debitAccountId = null;
if (!reader.IsDBNull(2)) { debitAccountId = reader.GetInt32(2); } if (!reader.IsDBNull(2))
debitAccountId = reader.GetInt32(2);
int? creditAccountId = null; int? creditAccountId = null;
if (!reader.IsDBNull(3)) { creditAccountId = reader.GetInt32(3); } if (!reader.IsDBNull(3))
creditAccountId = reader.GetInt32(3);
// build return list returnList.Add((journalTypeId, title, debitAccountId, creditAccountId));
var item = new Model.Account.JournalType(journalTypeId, title);
returnList.Add(journalTypeId, item);
// build dictionaries
if (debitAccountId != null)
{
debitDict.Add(journalTypeId, debitAccountId.Value);
}
if (creditAccountId != null)
{
creditDict.Add(journalTypeId, creditAccountId.Value);
} }
} }
} }
}
}
// get account objects from db
var accountIdList = debitDict.Values.ToList();
accountIdList.AddRange(creditDict.Values.ToList());
var dbDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountIdList);
// add to the returnlist
foreach (var account in returnList.Values)
{
Model.Account.Account debitAccount = null;
if (debitDict.ContainsKey(account.JournalTypeId))
{
debitAccount = dbDict[debitDict[account.JournalTypeId]];
}
Model.Account.Account creditAccount = null;
if (creditDict.ContainsKey(account.JournalTypeId))
{
creditAccount = dbDict[creditDict[account.JournalTypeId]]; // key of 59 needed
}
account.AddDefaultAccounts(creditAccount, debitAccount);
}
// all done, return the list here
return returnList; return returnList;
} }
/// <summary>
/// Retrieves the default debit and credit account IDs associated with a specific account journal.
/// </summary>
/// <remarks>This method queries the database to retrieve the default debit and credit account IDs
/// for the specified account journal. If the account journal does not exist, an exception is thrown. Ensure
/// that the provided <paramref name="accountJournalId"/> is valid.</remarks>
/// <param name="accountJournalId">The unique identifier of the account journal for which to retrieve the default debit and credit account IDs.</param>
/// <returns>A tuple containing two nullable integers: <list type="bullet"> <item><description>The first value represents
/// the default debit account ID, or <see langword="null"/> if no debit account is set.</description></item>
/// <item><description>The second value represents the default credit account ID, or <see langword="null"/> if
/// no credit account is set.</description></item> </list></returns>
/// <exception cref="Exception">Thrown if the specified <paramref name="accountJournalId"/> does not exist in the database.</exception>
public (int?, int?) ReadJournalTypeDefaultDebitCredit(int accountJournalId)
{
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
SELECT
tblAccountJournalType.ChartOfAccountID_Debit, tblAccountJournalType.ChartOfAccountID_Credit
FROM
tblAccountJournal
INNER JOIN tblAccountJournalType
ON tblAccountJournal.AccountJournalTypeID = tblAccountJournalType.AccountJournalTypeID
WHERE
(((tblAccountJournal.AccountJournalID)=@journalId));";
cmd.Parameters.AddWithValue("@journalId", accountJournalId);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
int? defaultDebit = null;
int? defaultCredit = null;
// debit check
if (reader.IsDBNull(0) == false)
{
defaultDebit = reader.GetInt32(0);
}
// credit check
if (reader.IsDBNull(1) == false)
{
defaultCredit = reader.GetInt32(1);
}
return (defaultDebit, defaultCredit);
}
else
{
throw new Exception("AccountJournalID '" + accountJournalId + "' does not exist.");
}
}
}
}
// //
// update // update
// //
public bool UpdateJournalEntryModifiedDate(int accountJournalId)
{
if (accountJournalId <= 0)
{
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
}
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", accountJournalId);
cmd.Parameters.AddWithValue("@utcNow", DateTime.UtcNow);
if (cmd.ExecuteNonQuery() == 1)
{
return true; // update successful
}
else
{
return false; // update failed, journal ID may not exist
}
}
}
// //
// delete // delete
// //
public int DeleteJournalHeader(int accountJournalId)
{
if (accountJournalId <= 0)
{
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
DELETE FROM
tblAccountJournal
WHERE
AccountJournalID=@accountJournalId;";
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
return cmd.ExecuteNonQuery();
}
}
public int DeleteJournalPostAll(int accountJournalId)
{
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", accountJournalId);
return cmd.ExecuteNonQuery();
}
}
} }
} }

View File

@@ -37,9 +37,9 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
cmd.CommandText = @" cmd.CommandText = @"
SELECT Count(tblStock.StockID) AS CountOfStockID SELECT Count(tblStock.StockID) AS CountOfStockID
FROM tblStock FROM tblStock
WHERE (((tblStock.AccountJournalID)=@accountJouranlId)); WHERE (((tblStock.AccountJournalID)=@accountJournalId));
"; ";
cmd.Parameters.AddWithValue("@accountJouranlId", accountJouranlId); cmd.Parameters.AddWithValue("@accountJournalId", accountJouranlId);
count = (int)cmd.ExecuteScalar(); count = (int)cmd.ExecuteScalar();
} }

View File

@@ -151,10 +151,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
} }
} }
// //
// Read // Read
// //

View File

@@ -212,12 +212,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
} }
} }
// //
// delete // delete
// //
public int DeleteStockTableLine(int stockId) public int DeleteStock(int stockId)
{ {
if (stockId <= 0) if (stockId <= 0)
{ {

View File

@@ -8,9 +8,17 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
{ {
internal interface IAccountJournalRepository internal interface IAccountJournalRepository
{ {
int AccountJournalInsert(int journalTypeId, DateTime entryDate, bool lockEntry = false); int InsertJournalHeader(int journalTypeId, DateTime entryDate, bool lockEntry = false);
int InsertJournalPost(int accountJournalId, int accountChartOfId, decimal amountGbp);
Dictionary<int, Model.Account.JournalBuilder> ReadJournalBuilder(List<int> journalIdList);
DateTime ReadJournalEntryDate(int journalId);
int CountJournalPosts(int accountJournalId);
bool IsJournalDebitAssetType(int accountJournalId); bool IsJournalDebitAssetType(int accountJournalId);
bool ReadJournalIsLocked(int journalId); bool? IsJournalLocked(int journalId);
Dictionary<int, Model.Account.JournalType> ReadJournalType(List<int> journalTypeIds = null, List<string> typeTitles = null); List<(int, string, int?, int?)> ReadJournalType(List<int> accountJournalTypeIds = null, List<string> typeTitles = null);
(int?, int?) ReadJournalTypeDefaultDebitCredit(int accountJournalId);
bool UpdateJournalEntryModifiedDate(int accountJournalId);
int DeleteJournalHeader(int accountJournalId);
int DeleteJournalPostAll(int accountJournalId);
} }
} }

View File

@@ -14,9 +14,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
int? ReadStockJournalId(int stockId); int? ReadStockJournalId(int stockId);
int UpdateAccountJournalId(int stockId, int? accountJournalID); int UpdateAccountJournalId(int stockId, int? accountJournalID);
int UpdateStockJournalId(int stockId, int? stockJournalID); int UpdateStockJournalId(int stockId, int? stockJournalID);
int DeleteStockTableLine(int stockId); int DeleteStock(int stockId);
void WIP_StockDelete(int stockId);
void WIP_StockDeleteSub(int stockId);
void WIP_StockDeleteSubAccountJournalEntry(int stockId);
} }
} }

View File

@@ -1,6 +1,7 @@
using bnhtrade.Core.Data.Database; using bnhtrade.Core.Data.Database;
using bnhtrade.Core.Data.Database.Repository.Implementation; using bnhtrade.Core.Data.Database.Repository.Implementation;
using bnhtrade.Core.Data.Database.UnitOfWork; using bnhtrade.Core.Data.Database.UnitOfWork;
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
@@ -28,52 +29,21 @@ namespace bnhtrade.Core.Logic.Account
return WithUnitOfWork(uow => return WithUnitOfWork(uow =>
{ {
// insert header record // insert header record
int journalId = uow.AccountJournalRepository.AccountJournalInsert(journalTypeId, entryDate, lockEntry); int journalId = uow.AccountJournalRepository.InsertJournalHeader(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();
// ensure their are no other entries (not sure why this is needed, but it was in the old code)
int count = uow.AccountJournalRepository.CountJournalPosts(journalId);
if (count > 0) if (count > 0)
{ {
throw new Exception("Unable the insert journal posts, post already present AccountJournalID=" + journalId); throw new Exception("Unable the insert journal posts, post already present AccountJournalID=" + journalId);
} }
}
//checks // check defaults for debit and credit accounts
using (SqlCommand cmd = new SqlCommand(@" var result = uow.AccountJournalRepository.ReadJournalTypeDefaultDebitCredit(journalId);
SELECT int? defaultDebit = result.Item1;
tblAccountJournalType.ChartOfAccountID_Debit, tblAccountJournalType.ChartOfAccountID_Credit int? defaultCredit = result.Item2;
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 (defaultDebit == null)
{
if (reader.Read())
{
// debit check
if (reader.IsDBNull(0))
{ {
if (debitAccountId == 0) if (debitAccountId == 0)
{ {
@@ -82,10 +52,9 @@ namespace bnhtrade.Core.Logic.Account
} }
else else
{ {
defaultDebit = reader.GetInt32(0);
if (debitAccountId == 0) if (debitAccountId == 0)
{ {
debitAccountId = defaultDebit; debitAccountId = defaultDebit.Value;
} }
else if (debitAccountId != defaultDebit) else if (debitAccountId != defaultDebit)
{ {
@@ -93,8 +62,8 @@ namespace bnhtrade.Core.Logic.Account
} }
} }
// credit check
if (reader.IsDBNull(1)) if (defaultCredit == null)
{ {
if (creditAccountId == 0) if (creditAccountId == 0)
{ {
@@ -103,78 +72,32 @@ namespace bnhtrade.Core.Logic.Account
} }
else else
{ {
defaultCredit = reader.GetInt32(1);
if (creditAccountId == 0) if (creditAccountId == 0)
{ {
creditAccountId = defaultCredit; creditAccountId = defaultCredit.Value;
} }
else if (creditAccountId != defaultCredit) else if (creditAccountId != defaultCredit)
{ {
throw new Exception("Credit Account ID supplied does not match default set for journal type"); 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 // currency conversion
if (currencyCode != "GBP") if (currencyCode != "GBP")
{ {
amount = new Logic.Account.CurrencyService().CurrencyConvertToGbp(currencyCode, amount, entryDate); amount = new Logic.Account.CurrencyService(uow).CurrencyConvertToGbp(currencyCode, amount, entryDate);
} }
// ensure decimal is rounded // ensure decimal is rounded
amount = Math.Round(amount, 2); amount = Math.Round(amount, 2);
// insert debit post // insert posts
using (SqlCommand cmd = new SqlCommand(@" int debitPostId = uow.AccountJournalRepository.InsertJournalPost(journalId, debitAccountId, amount);
INSERT INTO tblAccountJournalPost int creditPostId = uow.AccountJournalRepository.InsertJournalPost(journalId, creditAccountId, amount * -1);
(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;
// need to add verification here to ensure the entry is correct
// finished
CommitIfOwned(uow); CommitIfOwned(uow);
return journalId; return journalId;
}); });
@@ -182,407 +105,161 @@ namespace bnhtrade.Core.Logic.Account
public Dictionary<int, Core.Model.Account.Journal> ReadJournal(List<int> journalIdList) public Dictionary<int, Core.Model.Account.Journal> ReadJournal(List<int> journalIdList)
{ {
var sqlBuilder = new SqlWhereBuilder(); throw new NotImplementedException("done, but needs testing");
//build sql query var returnDict = new Dictionary<int, Core.Model.Account.Journal>();
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 WithUnitOfWork(uow =>
if (journalIdList.Any())
{ {
sqlBuilder.In("tblAccountJournal.AccountJournalID", journalIdList, "AND"); var builderDict = uow.AccountJournalRepository.ReadJournalBuilder(journalIdList);
} if (builderDict.Any())
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{ {
sql = sql + sqlBuilder.SqlWhereString; // build list of journal types and accounts from the builderDict
}
// 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 journalTypeIdList = new List<int>();
var accountIdList = new List<int>(); var accountIdList = new List<int>();
foreach (var item in dbJournalList)
foreach (var journal in builderDict.Values)
{ {
journalTypeIdList.Add(item.AccountJournalTypeId); journalTypeIdList.Add(journal.JournalTypeId);
foreach (var post in journal.JournalBuilderPosts)
{
accountIdList.Add(post.AccountId);
} }
foreach (var item in dbJournalPostList)
{
accountIdList.Add(item.AccountChartOfId);
} }
// get journalTypes from db journalTypeIdList = journalTypeIdList.Distinct().ToList();
var journalTypeDict = new AccountJournalRepository(_connection, _transaction).ReadJournalType(journalTypeIdList); accountIdList = accountIdList.Distinct().ToList();
// get accounts from db // get object dictionaries
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountIdList); var journalTypeDict = ReadJournalType(journalTypeIdList);
var accountDict = uow.AccountCodeRepository.ReadAccountCode(accountIdList);
// build final return dictionary // build final return dictionary
foreach (var dbJournal in dbJournalList) foreach (var item in builderDict)
{ {
// build posts var journal = item.Value.Build(journalTypeDict, accountDict);
var newPosts = new List<Core.Model.Account.Journal.Post>(); returnDict.Add(journal.JournalId, journal);
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); return returnDict;
}
}
// 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) public DateTime ReadJournalEntryDate(int journalId)
{ {
if (journalId <= 0) return WithUnitOfWork(uow =>
{ {
throw new ArgumentException("Invalid journal ID provided.", nameof(journalId)); return uow.AccountJournalRepository.ReadJournalEntryDate(journalId);
});
} }
string sql = @" public Dictionary<int, Model.Account.JournalType> ReadJournalType(List<int> journalTypeIdList)
SELECT tblAccountJournal.EntryDate
FROM tblAccountJournal
WHERE (((tblAccountJournal.AccountJournalID)=@accountJournalId));";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{ {
cmd.CommandText = sql; var returnDict = new Dictionary<int, Model.Account.JournalType>();
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@accountJournalId", journalId); WithUnitOfWork(uow =>
object obj = cmd.ExecuteScalar();
if (obj == null)
{ {
throw new Exception("Journal entry not found for AccountJournalID=" + journalId); // get base info from db
} var dbJournalTypeList = uow.AccountJournalRepository.ReadJournalType(journalTypeIdList);
return DateTime.SpecifyKind((DateTime)obj, DateTimeKind.Utc); // build list of account object to retrieve
var accountIdList = new List<int>();
foreach (var dbJournalType in dbJournalTypeList)
{
if (dbJournalType.Item3.HasValue)
{
accountIdList.Add(dbJournalType.Item3.Value);
} }
if (dbJournalType.Item4.HasValue)
{
accountIdList.Add(dbJournalType.Item4.Value);
}
}
accountIdList = accountIdList.Distinct().ToList();
// retieve account objects from db
var accountDict = uow.AccountCodeRepository.ReadAccountCode(accountIdList);
// build the return dictionary
foreach (var dbJournalType in dbJournalTypeList)
{
var journalType = new Model.Account.JournalType(
dbJournalType.Item1, // JournalTypeId
dbJournalType.Item2, // Name
dbJournalType.Item3.HasValue ? accountDict[dbJournalType.Item3.Value] : null, // DebitAccount
dbJournalType.Item4.HasValue ? accountDict[dbJournalType.Item4.Value] : null // CreditAccount
);
returnDict.Add(journalType.JournalTypeId, journalType);
}
});
return returnDict;
} }
/// <summary> /// <summary>
/// Old code needs sorting /// Deletes all posts associated with an entry and replaces the posts for a journal entry with two new posts
/// </summary> /// </summary>
public bool AccountJournalPostInsert(IUnitOfWork uow, int journalId, DateTime entryDate, string currencyCode, decimal amount, int debitAccountId = 0, int creditAccountId = 0) /// <param name="twoPostCheck">Raise exception if journal entry has more than two associated posts</param>
internal bool AccountJournalPostReplace(int accountJournalId, string currencyCode, decimal amountGbp, int debitAccountId = 0, int creditAccountId = 0, bool twoPostCheck = true)
{ {
int defaultDebit; if (amountGbp <= 0)
int defaultCredit;
entryDate = DateTime.SpecifyKind(entryDate, DateTimeKind.Utc);
using (TransactionScope scope = new TransactionScope())
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{ {
conn.Open(); throw new ArgumentException("Amount must be greater than zero", nameof(amountGbp));
// 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);
} }
if ( amountGbp.Scale > 2)
{
throw new ArgumentException("Amount must have a maximum of two decimal places", nameof(amountGbp));
}
if (debitAccountId <= 0 || creditAccountId <= 0)
{
throw new ArgumentException("Debit and Credit Account IDs must be greater than zero", nameof(debitAccountId));
} }
//checks WithUnitOfWork(uow =>
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); // check if the journal entry is locked
bool? isLocked = uow.AccountJournalRepository.IsJournalLocked(accountJournalId);
using (SqlDataReader reader = cmd.ExecuteReader()) if (isLocked == null)
{ {
if (reader.Read()) throw new Exception("Journal entry does not exist for AccountJournalID=" + accountJournalId);
{
// debit check
if (reader.IsDBNull(0))
{
if (debitAccountId == 0)
{
throw new Exception("Debit Account ID required, default not set for journal type");
} }
} else if (isLocked.Value)
else
{ {
defaultDebit = reader.GetInt32(0); throw new Exception("Cannot replace posts for locked journal entry AccountJournalID=" + accountJournalId);
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 // retrive journal entry date
DateTime entryDate; DateTime entryDate = uow.AccountJournalRepository.ReadJournalEntryDate(accountJournalId);
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 // delete the original posts
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) var rowsDeleted = uow.AccountJournalRepository.DeleteJournalPostAll(accountJournalId);
if (rowsDeleted == 0)
{ {
cmd.Transaction = _transaction as SqlTransaction; throw new Exception("No posts found for AccountJournalID=" + accountJournalId);
cmd.CommandText = @" }
DELETE FROM if (twoPostCheck && rowsDeleted > 2)
tblAccountJournalPost {
WHERE throw new Exception("More than two posts found for AccountJournalID=" + accountJournalId + ", cannot replace posts with two new posts.");
(((tblAccountJournalPost.AccountJournalID)=@accountJournalId));";
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
cmd.ExecuteNonQuery();
} }
//insert new posts //insert new posts
bool postResult = AccountJournalPostInsert(journalId, entryDate, currencyCode, amount, debitAccountId, creditAccountId); var rowsInserted = uow.AccountJournalRepository.InsertJournalPost(accountJournalId, debitAccountId, amountGbp);
rowsInserted += uow.AccountJournalRepository.InsertJournalPost(accountJournalId, creditAccountId, amountGbp * -1);
if (rowsInserted != 2)
{
throw new Exception("Failed to insert two posts for AccountJournalID=" + accountJournalId);
}
// update modified date on journal // update modified date on journal
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) if (uow.AccountJournalRepository.UpdateJournalEntryModifiedDate(accountJournalId) == false)
{ {
cmd.Transaction = _transaction as SqlTransaction; throw new Exception("Failed to update LastModified date for AccountJournalID=" + accountJournalId);
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();
} }
CommitIfOwned(uow);
});
return true; return true;
} }
@@ -591,42 +268,32 @@ namespace bnhtrade.Core.Logic.Account
/// </summary> /// </summary>
public bool DeleteJournal(int accountJournalId) public bool DeleteJournal(int accountJournalId)
{ {
bool IsLocked = ReadJournalIsLocked(accountJournalId); WithUnitOfWork(uow =>
if (IsLocked == true)
{ {
return false; if (accountJournalId <= 0)
{
throw new ArgumentException("Account journal ID must be greater than zero", nameof(accountJournalId));
}
// check if the journal entry is locked
bool? isLocked = uow.AccountJournalRepository.IsJournalLocked(accountJournalId);
if (isLocked == null)
{
throw new Exception("Journal entry does not exist for AccountJournalID=" + accountJournalId);
}
else if (isLocked.Value)
{
throw new Exception("Cannot replace posts for locked journal entry AccountJournalID=" + accountJournalId);
} }
// make the delete // delete posts first
uow.AccountJournalRepository.DeleteJournalPostAll(accountJournalId);
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) // then delete header record
{ uow.AccountJournalRepository.DeleteJournalHeader(accountJournalId);
cmd.CommandText = @"
DELETE FROM tblAccountJournalPost
WHERE AccountJournalID=@accountJournalId;";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId); CommitIfOwned(uow);
});
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; return true;
} }
} }

View File

@@ -194,7 +194,7 @@ namespace bnhtrade.Core.Logic.Inventory
uow.StockJournalRepository.StockJournalDelete(stockJournalId); uow.StockJournalRepository.StockJournalDelete(stockJournalId);
// delete stock table entry // delete stock table entry
count = uow.StockRepository.DeleteStockTableLine(stockId); count = uow.StockRepository.DeleteStock(stockId);
if (count != 1) if (count != 1)
{ {
throw new Exception("StockID = " + stockId + " delete failed"); throw new Exception("StockID = " + stockId + " delete failed");

View File

@@ -62,10 +62,78 @@ namespace bnhtrade.Core.Logic.Purchase
{ {
WithUnitOfWork(uow => WithUnitOfWork(uow =>
{ {
// stock accountId check
if (debitAccountId == 86)
{
int count = 0;
using (SqlCommand cmd = new SqlCommand(@"
SELECT Count(tblStock.StockID) AS CountOfStockID
FROM tblStock
WHERE (((tblStock.AccountJournalID)=@accountJouranlId));
", conn))
{
cmd.Parameters.AddWithValue("@accountJouranlId", accountJouranlId);
count = (int)cmd.ExecuteScalar();
}
if (count == 0)
{
throw new Exception("Add account journal entry to stock before attempting this operation.");
}
else if (count > 1)
{
throw new Exception("Houston we have a problem! An account journal entry is assigned to " + count + " stock lines.");
}
}
uow.PurchaseRepository.WIP_PurchaseLineTransactionNetUpdate(accountJouranlId, currencyCode, amountNet, debitAccountId); uow.PurchaseRepository.WIP_PurchaseLineTransactionNetUpdate(accountJouranlId, currencyCode, amountNet, debitAccountId);
new AccountJournalService(uow).AccountJournalPostUpdate(accountJouranlId, currencyCode, amountNet, creditAccountId); new AccountJournalService(uow).AccountJournalPostReplace(accountJouranlId, currencyCode, amountNet, creditAccountId);
CommitIfOwned(uow); CommitIfOwned(uow);
}); });
// stock accountId check
if (debitAccountId == 86)
{
int count = 0;
using (SqlCommand cmd = new SqlCommand(@"
SELECT Count(tblStock.StockID) AS CountOfStockID
FROM tblStock
WHERE (((tblStock.AccountJournalID)=@accountJouranlId));
", conn))
{
cmd.Parameters.AddWithValue("@accountJouranlId", accountJouranlId);
count = (int)cmd.ExecuteScalar();
}
if (count == 0)
{
throw new Exception("Add account journal entry to stock before attempting this operation.");
}
else if (count > 1)
{
throw new Exception("Houston we have a problem! An account journal entry is assigned to " + count + " stock lines.");
}
}
// make the update
bool result = new Data.Database.Account.UpdateJournal().AccountJournalPostUpdate(accountJouranlId, currencyCode, amountNet, debitAccountId, creditAccountId);
} }
public void WIP_PurchaseLineTransactionDelete(int purchaseLineId, int accountJournalId) public void WIP_PurchaseLineTransactionDelete(int purchaseLineId, int accountJournalId)

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Account
{
public class JournalBuilder
{
// Setters for each property
public int JournalId { get; set; }
public int JournalTypeId { get; set; }
public List<JournalPostBuilder> JournalBuilderPosts { get; set; }
public DateTime EntryDate { get; set; }
public DateTime PostDate { get; set; }
public DateTime LastModified { get; set; }
public bool IsLocked { get; set; }
public class JournalPostBuilder
{
public int AccountId { get; set; }
public int PostId { get; set; }
public decimal AmountGbp { get; set; }
}
public Journal Build(Dictionary<int, Model.Account.JournalType> journalTypeDict, Dictionary<int, Model.Account.Account> accountDict)
{
if (journalTypeDict == null || !journalTypeDict.ContainsKey(JournalTypeId))
{
throw new ArgumentException($"Journal type with ID {JournalTypeId} does not exist.");
}
if (JournalBuilderPosts == null || JournalBuilderPosts.Count == 0)
{
throw new ArgumentException("Journal posts cannot be null or empty.");
}
if (accountDict == null || accountDict.Any() == false)
{
throw new ArgumentException("Account dictionary cannot be null or empty");
}
// build lines
var journalPosts = new List<Journal.Post>();
foreach (var post in JournalBuilderPosts)
{
if (!accountDict.ContainsKey(post.AccountId))
{
throw new ArgumentException($"Account with ID {post.AccountId} does not exist.");
}
journalPosts.Add(new Journal.Post(post.PostId, accountDict[post.AccountId], post.AmountGbp));
}
return new Journal(
JournalId
, journalTypeDict[JournalTypeId]
, journalPosts
, EntryDate
, PostDate
, LastModified
, IsLocked);
}
}
}

View File

@@ -16,24 +16,18 @@ namespace bnhtrade.Core.Model.Account
DefaultDebitAccount = defaultDebitAccount; DefaultDebitAccount = defaultDebitAccount;
} }
internal void AddDefaultAccounts(Model.Account.Account defaultCreditAccount = null, Model.Account.Account defaultDebitAccount = null) public int JournalTypeId { get; }
{
DefaultCreditAccount = defaultCreditAccount;
DefaultDebitAccount = defaultDebitAccount;
}
public int JournalTypeId { get ; private set; } public string Title { get; }
public string Title { get; private set; } public Model.Account.Account DefaultDebitAccount { get; }
public Model.Account.Account DefaultDebitAccount { get; private set; }
public bool IsSetDefaultDebitAccount public bool IsSetDefaultDebitAccount
{ {
get { return DefaultDebitAccount != null; } get { return DefaultDebitAccount != null; }
} }
public Model.Account.Account DefaultCreditAccount { get; private set; } public Model.Account.Account DefaultCreditAccount { get; }
public bool IsSetDefaultCreditAccount public bool IsSetDefaultCreditAccount
{ {