diff --git a/src/bnhtrade.Core/Data/Database/Repository/Implementation/AccountJournalRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Implementation/AccountJournalRepository.cs index 79eede7..e841afc 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Implementation/AccountJournalRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Implementation/AccountJournalRepository.cs @@ -1,5 +1,6 @@ using bnhtrade.Core.Data.Database._BoilerPlate; using bnhtrade.Core.Data.Database.Repository.Interface; +using bnhtrade.Core.Model.Account; using Microsoft.Data.SqlClient; using System; using System.Collections.Generic; @@ -21,7 +22,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation // 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 if (entryDate.Kind != DateTimeKind.Utc) @@ -44,7 +45,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation (@journalTypeId, @entryDate, @lockEntry);"; // add parameters - cmd.Parameters.AddWithValue("@journalTypeId", journalTypeId); + cmd.Parameters.AddWithValue("@journalTypeId", accountJournalTypeId); cmd.Parameters.AddWithValue("@entryDate", entryDate.ToUniversalTime()); cmd.Parameters.AddWithValue("@lockEntry", lockEntry); @@ -55,11 +56,168 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation 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 // + public Dictionary ReadJournalBuilder(List journalIdList) + { + var sqlBuilder = new SqlWhereBuilder(); + var returnDict = new Dictionary(); + //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(); + + 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) { @@ -98,12 +256,12 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation /// /// Test for locked journal entry /// - /// False on locked journal entry - public bool ReadJournalIsLocked(int journalId) + /// True/False or null on no records found + 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 = @" @@ -115,16 +273,16 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation tblAccountJournal.AccountJournalID=@accountJournalId;"; using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) - { + { cmd.CommandText = sql; cmd.Transaction = _transaction as SqlTransaction; - cmd.Parameters.AddWithValue("@accountJournalId", journalId); + cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId); 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 { @@ -133,15 +291,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation } } - - public Dictionary ReadJournalType(List journalTypeIds = null, List typeTitles = null) + public List<(int, string, int?, int?)> ReadJournalType(List accountJournalTypeIds = null, List typeTitles = null) { + var returnList = new List<(int, string, int?, int?)>(); var sqlBuilder = new SqlWhereBuilder(); - // create the return (emptyP list) here - var returnList = new Dictionary(); - sqlBuilder.Init(); - //build sql query string sql = @" SELECT [AccountJournalTypeID] @@ -152,9 +306,9 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation WHERE 1 = 1 "; // build the where statments - if (journalTypeIds.Any()) + if (accountJournalTypeIds.Any()) { - sqlBuilder.In("AccountJournalTypeID", journalTypeIds, "AND"); + sqlBuilder.In("AccountJournalTypeID", accountJournalTypeIds, "AND"); } if (typeTitles.Any()) { @@ -167,10 +321,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation sql = sql + sqlBuilder.SqlWhereString; } - // create dictionary to add credit/debit accounts on after db read - var creditDict = new Dictionary(); - var debitDict = new Dictionary(); - using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) { cmd.CommandText = sql; @@ -183,70 +333,156 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation using (SqlDataReader reader = cmd.ExecuteReader()) { - if (reader.HasRows) + while (reader.Read()) { - while (reader.Read()) - { - // read from db and create object - int journalTypeId = reader.GetInt32(0); - string title = reader.GetString(1); - int? debitAccountId = null; - if (!reader.IsDBNull(2)) { debitAccountId = reader.GetInt32(2); } - int? creditAccountId = null; - if (!reader.IsDBNull(3)) { creditAccountId = reader.GetInt32(3); } + // read from db and create object + int journalTypeId = reader.GetInt32(0); + string title = reader.GetString(1); + int? debitAccountId = null; + if (!reader.IsDBNull(2)) + debitAccountId = reader.GetInt32(2); + int? creditAccountId = null; + if (!reader.IsDBNull(3)) + creditAccountId = reader.GetInt32(3); - // build return list - 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); - } - } + returnList.Add((journalTypeId, title, debitAccountId, creditAccountId)); } } } - // 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; } + /// + /// Retrieves the default debit and credit account IDs associated with a specific account journal. + /// + /// 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 is valid. + /// The unique identifier of the account journal for which to retrieve the default debit and credit account IDs. + /// A tuple containing two nullable integers: The first value represents + /// the default debit account ID, or if no debit account is set. + /// The second value represents the default credit account ID, or if + /// no credit account is set. + /// Thrown if the specified does not exist in the database. + 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 // + 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 // + 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(); + } + } } } diff --git a/src/bnhtrade.Core/Data/Database/Repository/Implementation/PurchaseRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Implementation/PurchaseRepository.cs index 6024857..f71d479 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Implementation/PurchaseRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Implementation/PurchaseRepository.cs @@ -37,9 +37,9 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation cmd.CommandText = @" SELECT Count(tblStock.StockID) AS CountOfStockID FROM tblStock - WHERE (((tblStock.AccountJournalID)=@accountJouranlId)); + WHERE (((tblStock.AccountJournalID)=@accountJournalId)); "; - cmd.Parameters.AddWithValue("@accountJouranlId", accountJouranlId); + cmd.Parameters.AddWithValue("@accountJournalId", accountJouranlId); count = (int)cmd.ExecuteScalar(); } diff --git a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs index 1d1d3a9..8fc6ff5 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs @@ -151,10 +151,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation } } - - - - // // Read // diff --git a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockRepository.cs index 1198212..be09035 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockRepository.cs @@ -212,12 +212,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation } } - // // delete // - public int DeleteStockTableLine(int stockId) + public int DeleteStock(int stockId) { if (stockId <= 0) { diff --git a/src/bnhtrade.Core/Data/Database/Repository/Interface/IAccountJournalRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Interface/IAccountJournalRepository.cs index 35f2e8c..823df8a 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Interface/IAccountJournalRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Interface/IAccountJournalRepository.cs @@ -8,9 +8,17 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface { 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 ReadJournalBuilder(List journalIdList); + DateTime ReadJournalEntryDate(int journalId); + int CountJournalPosts(int accountJournalId); bool IsJournalDebitAssetType(int accountJournalId); - bool ReadJournalIsLocked(int journalId); - Dictionary ReadJournalType(List journalTypeIds = null, List typeTitles = null); + bool? IsJournalLocked(int journalId); + List<(int, string, int?, int?)> ReadJournalType(List accountJournalTypeIds = null, List typeTitles = null); + (int?, int?) ReadJournalTypeDefaultDebitCredit(int accountJournalId); + bool UpdateJournalEntryModifiedDate(int accountJournalId); + int DeleteJournalHeader(int accountJournalId); + int DeleteJournalPostAll(int accountJournalId); } } diff --git a/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockRepository.cs index 8300651..0fe00ab 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockRepository.cs @@ -14,9 +14,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface int? ReadStockJournalId(int stockId); int UpdateAccountJournalId(int stockId, int? accountJournalID); int UpdateStockJournalId(int stockId, int? stockJournalID); - int DeleteStockTableLine(int stockId); - void WIP_StockDelete(int stockId); - void WIP_StockDeleteSub(int stockId); - void WIP_StockDeleteSubAccountJournalEntry(int stockId); + int DeleteStock(int stockId); } } diff --git a/src/bnhtrade.Core/Logic/Account/AccountJournalService.cs b/src/bnhtrade.Core/Logic/Account/AccountJournalService.cs index eafd8cf..93a56bd 100644 --- a/src/bnhtrade.Core/Logic/Account/AccountJournalService.cs +++ b/src/bnhtrade.Core/Logic/Account/AccountJournalService.cs @@ -1,6 +1,7 @@ using bnhtrade.Core.Data.Database; using bnhtrade.Core.Data.Database.Repository.Implementation; using bnhtrade.Core.Data.Database.UnitOfWork; +using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound; using System; using System.Collections.Generic; using System.Data.Common; @@ -28,153 +29,75 @@ namespace bnhtrade.Core.Logic.Account return WithUnitOfWork(uow => { // 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 (not sure why this is needed, but it was in the old code) + int count = uow.AccountJournalRepository.CountJournalPosts(journalId); + if (count > 0) + { + throw new Exception("Unable the insert journal posts, post already present AccountJournalID=" + journalId); + } - // ensure their are no other entries - using (SqlCommand cmd = new SqlCommand(@" - SELECT - Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID - FROM - tblAccountJournalPost - WHERE - (((tblAccountJournalPost.AccountJournalID)=@AccountJournalID)); - ", conn)) + // check defaults for debit and credit accounts + var result = uow.AccountJournalRepository.ReadJournalTypeDefaultDebitCredit(journalId); + int? defaultDebit = result.Item1; + int? defaultCredit = result.Item2; + + if (defaultDebit == null) + { + if (debitAccountId == 0) { - 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); - } + throw new Exception("Debit Account ID required, default not set for journal type"); + } + } + else + { + if (debitAccountId == 0) + { + debitAccountId = defaultDebit.Value; + } + else if (debitAccountId != defaultDebit) + { + throw new Exception("Debit Account ID supplied does not match default set for journal type"); } - //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)) + } + + if (defaultCredit == null) + { + if (creditAccountId == 0) { - 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."); - } - } + throw new Exception("Credit Account ID required, default not set for journal type"); } - - // currency conversion - if (currencyCode != "GBP") + } + else + { + if (creditAccountId == 0) { - amount = new Logic.Account.CurrencyService().CurrencyConvertToGbp(currencyCode, amount, entryDate); + creditAccountId = defaultCredit.Value; } - - // 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)) + else if (creditAccountId != defaultCredit) { - // add parameters - cmd.Parameters.AddWithValue("@AccountJournalId", journalId); - cmd.Parameters.AddWithValue("@AccountChartOfId", debitAccountId); - cmd.Parameters.AddWithValue("@AmountGbp", amount); - - cmd.ExecuteNonQuery(); + throw new Exception("Credit Account ID supplied does not match default set for journal type"); } + } - // 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; - - - - - - - - + // currency conversion + if (currencyCode != "GBP") + { + amount = new Logic.Account.CurrencyService(uow).CurrencyConvertToGbp(currencyCode, amount, entryDate); + } + // ensure decimal is rounded + amount = Math.Round(amount, 2); + // insert posts + int debitPostId = uow.AccountJournalRepository.InsertJournalPost(journalId, debitAccountId, amount); + int creditPostId = uow.AccountJournalRepository.InsertJournalPost(journalId, creditAccountId, amount * -1); + // need to add verification here to ensure the entry is correct + // finished CommitIfOwned(uow); return journalId; }); @@ -182,406 +105,160 @@ namespace bnhtrade.Core.Logic.Account public Dictionary ReadJournal(List journalIdList) { - var sqlBuilder = new SqlWhereBuilder(); + throw new NotImplementedException("done, but needs testing"); - //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 "; + var returnDict = new Dictionary(); - // build the where statments - if (journalIdList.Any()) + WithUnitOfWork(uow => { - 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) + var builderDict = uow.AccountJournalRepository.ReadJournalBuilder(journalIdList); + if (builderDict.Any()) { - sqlBuilder.AddParametersToSqlCommand(cmd); - } + // build list of journal types and accounts from the builderDict + var journalTypeIdList = new List(); + var accountIdList = new List(); - using (SqlDataReader reader = cmd.ExecuteReader()) - { - if (reader.HasRows) + foreach (var journal in builderDict.Values) { - hasRows = true; - int lastJournalId = 0; - while (reader.Read()) + journalTypeIdList.Add(journal.JournalTypeId); + foreach (var post in journal.JournalBuilderPosts) { - // 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(); - if (hasRows) - { - // build lists to filter db results by - var journalTypeIdList = new List(); - var accountIdList = new List(); - 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(); - 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); + accountIdList.Add(post.AccountId); } } - // create the journal - var newJournal = new Core.Model.Account.Journal( - dbJournal.AccountJournalId - , journalTypeDict[dbJournal.AccountJournalTypeId] - , newPosts - , dbJournal.EntryDate - , dbJournal.PostDate - , dbJournal.LastModified - , dbJournal.IsLocked); + journalTypeIdList = journalTypeIdList.Distinct().ToList(); + accountIdList = accountIdList.Distinct().ToList(); - returnList.Add(dbJournal.AccountJournalId, newJournal); + // get object dictionaries + var journalTypeDict = ReadJournalType(journalTypeIdList); + var accountDict = uow.AccountCodeRepository.ReadAccountCode(accountIdList); + + // build final return dictionary + foreach (var item in builderDict) + { + var journal = item.Value.Build(journalTypeDict, accountDict); + returnDict.Add(journal.JournalId, journal); + } } - } - // all done, return the list herevar - return returnList; + }); + + return returnDict; } 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 = @" - SELECT tblAccountJournal.EntryDate - FROM tblAccountJournal - WHERE (((tblAccountJournal.AccountJournalID)=@accountJournalId));"; + public Dictionary ReadJournalType(List journalTypeIdList) + { + var returnDict = new Dictionary(); - using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) + WithUnitOfWork(uow => { - cmd.CommandText = sql; - cmd.Transaction = _transaction as SqlTransaction; + // get base info from db + var dbJournalTypeList = uow.AccountJournalRepository.ReadJournalType(journalTypeIdList); - cmd.Parameters.AddWithValue("@accountJournalId", journalId); - - object obj = cmd.ExecuteScalar(); - - if (obj == null) + // build list of account object to retrieve + var accountIdList = new List(); + foreach (var dbJournalType in dbJournalTypeList) { - throw new Exception("Journal entry not found for AccountJournalID=" + journalId); + if (dbJournalType.Item3.HasValue) + { + accountIdList.Add(dbJournalType.Item3.Value); + } + if (dbJournalType.Item4.HasValue) + { + accountIdList.Add(dbJournalType.Item4.Value); + } } + accountIdList = accountIdList.Distinct().ToList(); - return DateTime.SpecifyKind((DateTime)obj, DateTimeKind.Utc); - } + // 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; } /// - /// Old code needs sorting + /// Deletes all posts associated with an entry and replaces the posts for a journal entry with two new posts /// - public bool AccountJournalPostInsert(IUnitOfWork uow, int journalId, DateTime entryDate, string currencyCode, decimal amount, int debitAccountId = 0, int creditAccountId = 0) + /// Raise exception if journal entry has more than two associated posts + internal bool AccountJournalPostReplace(int accountJournalId, string currencyCode, decimal amountGbp, int debitAccountId = 0, int creditAccountId = 0, bool twoPostCheck = true) { - int defaultDebit; - int defaultCredit; - entryDate = DateTime.SpecifyKind(entryDate, DateTimeKind.Utc); - - using (TransactionScope scope = new TransactionScope()) - using (SqlConnection conn = new SqlConnection(SqlConnectionString)) + if (amountGbp <= 0) { - 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; + throw new ArgumentException("Amount must be greater than zero", nameof(amountGbp)); + } + 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)); } - } - - 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) + WithUnitOfWork(uow => { - cmd.Transaction = _transaction as SqlTransaction; - cmd.CommandText = @" - SELECT - tblAccountJournal.EntryDate - FROM - tblAccountJournal - WHERE - (((tblAccountJournal.AccountJournalID)=@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); + } - cmd.Parameters.AddWithValue("@accountJournalId", journalId); + // retrive journal entry date + DateTime entryDate = uow.AccountJournalRepository.ReadJournalEntryDate(accountJournalId); - entryDate = DateTime.SpecifyKind((DateTime)cmd.ExecuteScalar(), DateTimeKind.Utc); - } + // delete the original posts + var rowsDeleted = uow.AccountJournalRepository.DeleteJournalPostAll(accountJournalId); + if (rowsDeleted == 0) + { + throw new Exception("No posts found for AccountJournalID=" + accountJournalId); + } + if (twoPostCheck && rowsDeleted > 2) + { + throw new Exception("More than two posts found for AccountJournalID=" + accountJournalId + ", cannot replace posts with two new posts."); + } - // 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));"; + //insert new posts + 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); + } - cmd.Parameters.AddWithValue("@accountJournalId", journalId); + // update modified date on journal + if (uow.AccountJournalRepository.UpdateJournalEntryModifiedDate(accountJournalId) == false) + { + throw new Exception("Failed to update LastModified date for AccountJournalID=" + accountJournalId); + } - 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(); - } + CommitIfOwned(uow); + }); return true; } @@ -591,42 +268,32 @@ namespace bnhtrade.Core.Logic.Account /// public bool DeleteJournal(int accountJournalId) { - bool IsLocked = ReadJournalIsLocked(accountJournalId); - if (IsLocked == true) + WithUnitOfWork(uow => { - 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) + if (accountJournalId <= 0) { - throw new Exception("Journal entry and/or entry posts do not exist for AccountJournalId=" + accountJournalId); + 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); } - } - using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) - { - cmd.CommandText = @" - DELETE FROM tblAccountJournal - WHERE AccountJournalID=@accountJournalId;"; - cmd.Transaction = _transaction as SqlTransaction; + // delete posts first + uow.AccountJournalRepository.DeleteJournalPostAll(accountJournalId); - cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId); + // then delete header record + uow.AccountJournalRepository.DeleteJournalHeader(accountJournalId); - cmd.ExecuteNonQuery(); - } + CommitIfOwned(uow); + }); + return true; } } diff --git a/src/bnhtrade.Core/Logic/Inventory/StockService.cs b/src/bnhtrade.Core/Logic/Inventory/StockService.cs index 3ebc3b6..f8bd73d 100644 --- a/src/bnhtrade.Core/Logic/Inventory/StockService.cs +++ b/src/bnhtrade.Core/Logic/Inventory/StockService.cs @@ -194,7 +194,7 @@ namespace bnhtrade.Core.Logic.Inventory uow.StockJournalRepository.StockJournalDelete(stockJournalId); // delete stock table entry - count = uow.StockRepository.DeleteStockTableLine(stockId); + count = uow.StockRepository.DeleteStock(stockId); if (count != 1) { throw new Exception("StockID = " + stockId + " delete failed"); diff --git a/src/bnhtrade.Core/Logic/Purchase/PurchaseService.cs b/src/bnhtrade.Core/Logic/Purchase/PurchaseService.cs index 46c83e2..d97a187 100644 --- a/src/bnhtrade.Core/Logic/Purchase/PurchaseService.cs +++ b/src/bnhtrade.Core/Logic/Purchase/PurchaseService.cs @@ -62,10 +62,78 @@ namespace bnhtrade.Core.Logic.Purchase { 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); - new AccountJournalService(uow).AccountJournalPostUpdate(accountJouranlId, currencyCode, amountNet, creditAccountId); + new AccountJournalService(uow).AccountJournalPostReplace(accountJouranlId, currencyCode, amountNet, creditAccountId); 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) diff --git a/src/bnhtrade.Core/Model/Account/JournalBuilder.cs b/src/bnhtrade.Core/Model/Account/JournalBuilder.cs new file mode 100644 index 0000000..fdac79a --- /dev/null +++ b/src/bnhtrade.Core/Model/Account/JournalBuilder.cs @@ -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 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 journalTypeDict, Dictionary 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(); + 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); + } + } +} diff --git a/src/bnhtrade.Core/Model/Account/JournalType.cs b/src/bnhtrade.Core/Model/Account/JournalType.cs index 8970dd1..25c4c2c 100644 --- a/src/bnhtrade.Core/Model/Account/JournalType.cs +++ b/src/bnhtrade.Core/Model/Account/JournalType.cs @@ -16,24 +16,18 @@ namespace bnhtrade.Core.Model.Account DefaultDebitAccount = defaultDebitAccount; } - internal void AddDefaultAccounts(Model.Account.Account defaultCreditAccount = null, Model.Account.Account defaultDebitAccount = null) - { - DefaultCreditAccount = defaultCreditAccount; - DefaultDebitAccount = defaultDebitAccount; - } + public int JournalTypeId { get; } - public int JournalTypeId { get ; private set; } + public string Title { get; } - public string Title { get; private set; } - - public Model.Account.Account DefaultDebitAccount { get; private set; } + public Model.Account.Account DefaultDebitAccount { get; } public bool IsSetDefaultDebitAccount { get { return DefaultDebitAccount != null; } } - public Model.Account.Account DefaultCreditAccount { get; private set; } + public Model.Account.Account DefaultCreditAccount { get; } public bool IsSetDefaultCreditAccount {