From 2d751ebf808a1fcdee9e4c5105aa9c017ad40aa8 Mon Sep 17 00:00:00 2001 From: Bob Hodgetts Date: Mon, 14 Jul 2025 14:29:56 +0100 Subject: [PATCH] wip --- .../Implementation/StockJournalRepository.cs | 134 ++++++++++++++++++ .../Implementation/StockStatusRepository.cs | 94 ++++++------ .../Interface/IStockJournalRepository.cs | 3 +- .../Interface/IStockStatusRepository.cs | 4 +- .../Logic/Account/AccountCodeService.cs | 51 ++----- .../Logic/Inventory/StockJournalService.cs | 107 +++++++++++++- .../Logic/Inventory/StockStatusService.cs | 50 ++++++- src/bnhtrade.Core/Model/Account/Account.cs | 16 +-- src/bnhtrade.Core/Model/Stock/JournalEntry.cs | 44 ------ src/bnhtrade.Core/Model/Stock/Status.cs | 28 ++-- .../Model/Stock/StatusBuilder.cs | 48 +++++++ src/bnhtrade.Core/Model/Stock/StatusType.cs | 10 +- .../Model/Stock/StatusTypeBuilder.cs | 32 +++++ .../Model/Stock/StockJournalBuilder.cs | 74 ++++++++++ .../Model/Stock/StockJournalType.cs | 25 ++++ 15 files changed, 550 insertions(+), 170 deletions(-) delete mode 100644 src/bnhtrade.Core/Model/Stock/JournalEntry.cs create mode 100644 src/bnhtrade.Core/Model/Stock/StatusBuilder.cs create mode 100644 src/bnhtrade.Core/Model/Stock/StatusTypeBuilder.cs create mode 100644 src/bnhtrade.Core/Model/Stock/StockJournalBuilder.cs diff --git a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs index 9ba1261..de547d6 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockJournalRepository.cs @@ -1,6 +1,7 @@ using bnhtrade.Core.Data.Database._BoilerPlate; using bnhtrade.Core.Data.Database.Repository.Interface; using bnhtrade.Core.Model.Account; +using bnhtrade.Core.Model.Stock; using Microsoft.Data.SqlClient; using System; using System.Collections.Generic; @@ -76,6 +77,139 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation // Read // + public Dictionary ReadStockJournal(List stockJournalIdList) + { + if (stockJournalIdList == null || !stockJournalIdList.Any()) + { + throw new ArgumentException("Stock journal ID list cannot be null or empty.", nameof(stockJournalIdList)); + } + + var returnDict = new Dictionary(); + var sqlWhere = new SqlWhereBuilder(); + + string sql = @" + SELECT tblStockJournal.StockJournalID, + tblStockJournal.StockJournalTypeID, + tblStockJournal.StockID, + tblStock.StockNumber + tblStockJournal.EntryDate, + tblStockJournal.PostDate, + tblStockJournal.LastModified, + tblStockJournal.IsLocked, + tblStockJournal.AccountIsProcessed, + tblStockJournalPost.StockJournalPostID, + tblStockJournalPost.StockStatusID, + tblStockJournalPost.Quantity, + FROM tblStockJournal + LEFT OUTER JOIN + tblStock + ON tblStockJournal.StockID = tblStock.StockID + LEFT OUTER JOIN + tblStockJournalPost + ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID + WHERE 1=1 "; + + if (stockJournalIdList != null && stockJournalIdList.Any()) + { + sqlWhere.In("tblStockJournal.StockJournalID", stockJournalIdList, "AND"); + } + + sql += sqlWhere.SqlWhereString + " ORDER BY tblStockJournal.EntryDate, tblStockJournal.StockJournalID, tblStockJournalPost.StockJournalPostID;"; + + using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) + { + cmd.Transaction = _transaction as SqlTransaction; + cmd.CommandText = sql; + + if (sqlWhere.ParameterListIsSet) + { + sqlWhere.AddParametersToSqlCommand(cmd); + } + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + int stockJournalId = reader.GetInt32(0); + + // add header information, if not already in dictionary + if (returnDict.ContainsKey(stockJournalId) == false) + { + // create new StockJournalBuilder + var stockJournalBuilder = new Model.Stock.StockJournalBuilder + { + StockJournalId = stockJournalId, + StockJournalTypeId = reader.GetInt32(1), + StockId = reader.GetInt32(2), + StockNumber = "STK#" + reader.GetInt32(3).ToString("D6"), + EntryDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc), + PostDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc), + LastModified = DateTime.SpecifyKind(reader.GetDateTime(6), DateTimeKind.Utc), + IsLocked = reader.GetBoolean(7), + AccountIsProcessed = reader.GetBoolean(8), + StockJournalBuilderPosts = new List() + }; + returnDict.Add(stockJournalId, stockJournalBuilder); + } + + var stockJournalBuilderPost = new Model.Stock.StockJournalBuilder.StockJournalBuilderPost + { + StockJournalPostId = reader.GetInt32(9), + StatusId = reader.GetInt32(10), + Quantity = reader.GetInt32(11) + }; + + returnDict[stockJournalId].StockJournalBuilderPosts.Add(stockJournalBuilderPost); + } + return returnDict; + } + } + } + + public Dictionary ReadStockJournalType(List stockJournalTypeIdList) + { + var returnDict = new Dictionary(); + var sqlWhere = new SqlWhereBuilder(); + + string sql = @" + SELECT StockJournalTypeID, TypeTitle, StockStatusID_Debit, StockStatusID_Credit + FROM tblStockJournalType + WHERE 1=1 "; + + if (stockJournalTypeIdList != null && stockJournalTypeIdList.Any()) + { + sqlWhere.In("StockJournalTypeID", stockJournalTypeIdList, "AND"); + } + + sql += sqlWhere.SqlWhereString + ";"; + + using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) + { + cmd.Transaction = _transaction as SqlTransaction; + cmd.CommandText = sql; + + if (sqlWhere.ParameterListIsSet) + { + sqlWhere.AddParametersToSqlCommand(cmd); + } + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + int stockJournalTypeId = reader.GetInt32(0); + returnDict.Add(stockJournalTypeId, ( + id: stockJournalTypeId, + title: reader.GetString(1), + stockStatusIdDebit: reader.IsDBNull(2) ? (int?)null : reader.GetInt32(2), + stockStatusIdCredit: reader.IsDBNull(3) ? (int?)null : reader.GetInt32(3) + )); + } + } + } + return returnDict; + } + public (int, DateTime) ReadJournalStockIdAndEntryDate(int stockJournalId) { using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) diff --git a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockStatusRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockStatusRepository.cs index c2ad7c8..bd8fe2a 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockStatusRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Implementation/StockStatusRepository.cs @@ -1,4 +1,5 @@ -using bnhtrade.Core.Data.Database._BoilerPlate; +using Amazon.Runtime.Internal.Transform; +using bnhtrade.Core.Data.Database._BoilerPlate; using bnhtrade.Core.Data.Database.Repository.Interface; using Microsoft.Data.SqlClient; using System; @@ -16,10 +17,10 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation { } - public Dictionary ReadStatus(List statusIds = null, List statusTypeIds = null) + public Dictionary ReadStatus(List statusIds = null, List statusTypeIds = null) { var sqlBuilder = new SqlWhereBuilder(); - var returnList = new Dictionary(); + var returnList = new Dictionary(); //build sql query string sql = @" @@ -63,75 +64,64 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation using (SqlDataReader reader = cmd.ExecuteReader()) { - var typeDict = new StockStatusRepository(_connection, _transaction).ReadStatusType(); - while (reader.Read()) { - int statusId = reader.GetInt32(0); - int? statusCode = null; - if (!reader.IsDBNull(1)) { statusCode = reader.GetInt32(1); } - string stockStatus = reader.GetString(2); - int typeId = reader.GetInt32(3); - string reference = null; - if (!reader.IsDBNull(4)) { reference = reader.GetString(4); } - int? foreignKeyId = null; - if (!reader.IsDBNull(5)) { foreignKeyId = reader.GetInt32(5); } - bool isCreditOnly = reader.GetBoolean(6); - bool isClosed = reader.GetBoolean(7); - DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc); + var statusBuilder = new Model.Stock.StatusBuilder + { + StatusId = reader.GetInt32(0), + StatusCode = reader.IsDBNull(1) ? (int?)null : reader.GetInt32(1), + StatusTitle = reader.GetString(2), + StatusTypeId = reader.GetInt32(3), + Reference = reader.IsDBNull(4) ? null : reader.GetString(4), + ForeignKeyID = reader.IsDBNull(5) ? (int?)null : reader.GetInt32(5), + IsCreditOnly = reader.GetBoolean(6), + IsClosed = reader.GetBoolean(7), + RecordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc) + }; - var newItem = new Model.Stock.Status(statusId - , statusCode - , stockStatus - , typeDict[typeId] - , reference - , foreignKeyId - , isCreditOnly - , isClosed - , recordCreated - ); - - returnList.Add(statusId, newItem); + returnList.Add(statusBuilder.StatusId, statusBuilder); } } } return returnList; } - public Dictionary ReadStatusType() + public Dictionary ReadStatusType(List stockStatusTypeIds = null) { - var returnDict = new Dictionary(); + var returnDict = new Dictionary(); + var sqlWhere = new SqlWhereBuilder(); - // get all account info before we start - var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(); + string sql = @" + SELECT [StockStatusTypeID] + ,[StatusTypeName] + ,[ForeignKeyType] + ,[ReferenceType] + ,[AccountChartOfID] + FROM [e2A].[dbo].[tblStockStatusType] + WHERE 1=1 "; using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) { - cmd.CommandText = @" - SELECT [StockStatusTypeID] - ,[StatusTypeName] - ,[ForeignKeyType] - ,[ReferenceType] - ,[AccountChartOfID] - FROM [e2A].[dbo].[tblStockStatusType]"; + cmd.CommandText = sql; cmd.Transaction = _transaction as SqlTransaction; + if (sqlWhere.ParameterListIsSet) + { + sqlWhere.AddParametersToSqlCommand(cmd); + } using (SqlDataReader reader = cmd.ExecuteReader()) { - var accountIdDict = new Dictionary(); - while (reader.Read()) { - int statusTypeId = reader.GetInt32(0); - string name = reader.GetString(1); - string foreignKey = null; - if (!reader.IsDBNull(2)) { foreignKey = reader.GetString(2); } - string reference = null; - if (!reader.IsDBNull(3)) { reference = reader.GetString(3); } - uint accountId = (uint)reader.GetInt32(4); - - var statusType = new Model.Stock.StatusType(statusTypeId, name, foreignKey, reference, accountDict[(int)accountId]); - returnDict.Add(statusTypeId, statusType); + var statusTypeBuilder = new Model.Stock.StatusTypeBuilder + { + StockStatusTypeID = reader.GetInt32(0), + StatusTypeName = reader.GetString(1), + ForeignKeyType = reader.IsDBNull(2) ? null : reader.GetString(2), + ReferenceType = reader.IsDBNull(3) ? null : reader.GetString(3), + AccountId = reader.GetInt32(4) + }; + returnDict.Add(statusTypeBuilder.StockStatusTypeID, statusTypeBuilder); } } } diff --git a/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockJournalRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockJournalRepository.cs index beacbcc..dc5a27d 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockJournalRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockJournalRepository.cs @@ -10,6 +10,8 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface { int InsertStockJournalHeader(int stockId, int journalTypeId, DateTime entryDate, bool isLocked); int InsertStockJournalPost(int stockJournalId, int stockStatusId, int quantity); + Dictionary ReadStockJournal(List stockJournalIdList); + Dictionary ReadStockJournalType(List stockJournalTypeIdList); (int, DateTime) ReadJournalStockIdAndEntryDate(int stockJournalId); int ReadJournalTypeIdByStockId(int stockId); int ReadStatusBalanceBySku(string sku, int statusId); @@ -17,7 +19,6 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface int ReadStatusBalanceByStockId(int stockId, int statusId); int ReadJournalEntryCountByStockId(int stockId); int? ReadTypeIdStatusCreditId(int stockJournalTypeId); - Dictionary ReadStatusBalanceByStatusId(int statusId); DateTime? ReadMostRecentEntryDateForStatusDebit(int stockId, List stockStatusIdList); } } diff --git a/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockStatusRepository.cs b/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockStatusRepository.cs index c3d2a47..d76ea58 100644 --- a/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockStatusRepository.cs +++ b/src/bnhtrade.Core/Data/Database/Repository/Interface/IStockStatusRepository.cs @@ -8,7 +8,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface { internal interface IStockStatusRepository { - Dictionary ReadStatus(List statusIds = null, List statusTypeIds = null); - Dictionary ReadStatusType(); + Dictionary ReadStatus(List statusIds = null, List statusTypeIds = null); + Dictionary ReadStatusType(List stockStatusTypeIds = null); } } diff --git a/src/bnhtrade.Core/Logic/Account/AccountCodeService.cs b/src/bnhtrade.Core/Logic/Account/AccountCodeService.cs index b0611dd..2918359 100644 --- a/src/bnhtrade.Core/Logic/Account/AccountCodeService.cs +++ b/src/bnhtrade.Core/Logic/Account/AccountCodeService.cs @@ -1,4 +1,5 @@ -using System; +using bnhtrade.Core.Data.Database.UnitOfWork; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -12,52 +13,16 @@ namespace bnhtrade.Core.Logic.Account { } - public Dictionary GetAll() + internal AccountCodeService(IUnitOfWork unitOfWork) : base(unitOfWork) + { + } + + public Dictionary GetAccountCode(List accountIdList = null, List accountCodeList = null) { return WithUnitOfWork(uow => { - return uow.AccountCodeRepository.ReadAccountCode(); + return uow.AccountCodeRepository.ReadAccountCode(accountIdList, accountCodeList); }); } - - public Model.Account.Account ByAccountCode(int accountCode) - { - var list = ByAccountCode(new List { accountCode }); - if (list.Any()) - { - return list[0]; - } - else - { - return null; - } - } - - public List ByAccountCode(List accountCodeList) - { - return WithUnitOfWork(uow => - { - return uow.AccountCodeRepository.ReadAccountCode(null, accountCodeList).Values.ToList(); - }); - } - - public Dictionary ConvertToDictionary(List accountCodeList) - { - var returnDict = new Dictionary(); - - if (accountCodeList == null) - { - return returnDict; - } - - foreach (var accountCode in accountCodeList) - { - if (!returnDict.ContainsKey((int)accountCode.AccountCode)) - { - returnDict.Add((int)accountCode.AccountCode, accountCode); - } - } - return returnDict; - } } } \ No newline at end of file diff --git a/src/bnhtrade.Core/Logic/Inventory/StockJournalService.cs b/src/bnhtrade.Core/Logic/Inventory/StockJournalService.cs index 3586fea..9a09ec8 100644 --- a/src/bnhtrade.Core/Logic/Inventory/StockJournalService.cs +++ b/src/bnhtrade.Core/Logic/Inventory/StockJournalService.cs @@ -1,5 +1,6 @@ using Amazon.Runtime.Internal.Transform; using bnhtrade.Core.Data.Database.UnitOfWork; +using bnhtrade.Core.Logic.Account; using System; using System.Collections.Generic; using System.Linq; @@ -15,6 +16,106 @@ namespace bnhtrade.Core.Logic.Inventory internal StockJournalService(IUnitOfWork unitOfWork) : base(unitOfWork) { } + public Dictionary ReadStockJournal(List stockJournalIds) + { + if (stockJournalIds == null || stockJournalIds.Count == 0) + { + throw new ArgumentException("Stock journal IDs cannot be null or empty.", nameof(stockJournalIds)); + } + + return WithUnitOfWork(uow => + { + // get the stock journal entries from the repository + var builderList = uow.StockJournalRepository.ReadStockJournal(stockJournalIds); + + // get the stock status for the journal posts + var statusIds = new List(); + foreach (var journal in builderList.Values) + { + foreach (var post in journal.StockJournalBuilderPosts) + { + if (!statusIds.Contains(post.StatusId)) + { + statusIds.Add(post.StatusId); + } + } + } + var statusDict = new StockStatusService(uow).GetStatus(statusIds); + + // get the stock journal types for the journal entries + var journalTypeIds = new List(); + foreach (var journal in builderList.Values) + { + if (!journalTypeIds.Contains(journal.StockJournalTypeId)) + { + journalTypeIds.Add(journal.StockJournalTypeId); + } + } + var journalTypeDict = ReadStockJournalType(uow, journalTypeIds); + + // build the stock journal objects and return them in a dictionary + var returnDict = new Dictionary(); + foreach (var journal in builderList.Values) + { + returnDict.Add(journal.StockJournalId, journal.Build(journalTypeDict, statusDict)); + } + + return returnDict; + }); + } + + public Dictionary ReadStockJournalType(List stockJournalTypeIds = null) + { + return WithUnitOfWork(uow => + { + return ReadStockJournalType(uow, stockJournalTypeIds); + }); + } + + private Dictionary ReadStockJournalType(IUnitOfWork uow, List stockJournalTypeIds = null) + { + return WithUnitOfWork(uow => + { + // get the stock journal types from the repository + var tupleList = uow.StockJournalRepository.ReadStockJournalType(stockJournalTypeIds); + + // get the accounts for the stock journal types + var statusIds = new List(); + foreach (var type in tupleList.Values) + { + if (type.stockStatusIdDebit.HasValue) + { + statusIds.Add(type.stockStatusIdDebit.Value); + } + + if (type.stockStatusIdCredit.HasValue) + { + statusIds.Add(type.stockStatusIdCredit.Value); + } + } + statusIds = statusIds.Distinct().ToList(); + var statusDict = new StockStatusService(uow).GetStatus(statusIds); + + // build the stock journal type objects and return them in a dictionary + var returnDict = new Dictionary(); + foreach (var type in tupleList.Values) + { + var debitStatus = type.stockStatusIdDebit.HasValue ? statusDict[type.stockStatusIdDebit.Value] : null; + var creditStatus = type.stockStatusIdCredit.HasValue ? statusDict[type.stockStatusIdCredit.Value] : null; + + var stockJournalType = new Model.Stock.StockJournalType( + type.id, + type.title, + debitStatus, + creditStatus + ); + + returnDict.Add(stockJournalType.StockJournalTypeID, stockJournalType); + } + return returnDict; + }); + } + public int StockJournalInsert(int journalTypeId, int stockId, List<(int statusId, int quantity)> journalPosts, DateTime entryDate, bool isNewStock = false) { @@ -134,9 +235,9 @@ namespace bnhtrade.Core.Logic.Inventory } } // get isCreditOnly for each status - var statusList = new StockStatusService(uow).GetStatus(dicStatusQty.Keys.ToList()); + var statusDict = new StockStatusService(uow).GetStatus(dicStatusQty.Keys.ToList()); var dicStatusIsCreditOnly = new Dictionary(); - foreach (var status in statusList.Values.ToList()) + foreach (var status in statusDict.Values.ToList()) { dicStatusIsCreditOnly.Add(status.StatusId, status.IsCreditOnly); } @@ -189,7 +290,7 @@ namespace bnhtrade.Core.Logic.Inventory // get this far... // insert journal posts into database - var postIdList = new List() + var postIdList = new List(); foreach (var post in journalPosts) { postIdList.Add(uow.StockJournalRepository.InsertStockJournalPost(stockJournalId, post.statusId, post.quantity)); diff --git a/src/bnhtrade.Core/Logic/Inventory/StockStatusService.cs b/src/bnhtrade.Core/Logic/Inventory/StockStatusService.cs index 1519838..ff22aaa 100644 --- a/src/bnhtrade.Core/Logic/Inventory/StockStatusService.cs +++ b/src/bnhtrade.Core/Logic/Inventory/StockStatusService.cs @@ -17,7 +17,53 @@ namespace bnhtrade.Core.Logic.Inventory { return WithUnitOfWork(uow => { - return uow.StockStatusRepository.ReadStatus(statusIds, statusTypeIds); + var builderList = uow.StockStatusRepository.ReadStatus(statusIds, statusTypeIds).Values.ToList(); + + var satusTypeIdList = new List(); + foreach (var status in builderList) + { + satusTypeIdList.Add(status.StatusTypeId); + } + satusTypeIdList = satusTypeIdList.Distinct().ToList(); + var statusTypeDict = GetStatusType(uow, satusTypeIdList); + + var retrunDict = new Dictionary(); + foreach (var status in builderList) + { + retrunDict.Add(status.StatusId, status.Build(statusTypeDict)); + } + return retrunDict; + }); + } + + private Dictionary GetStatusType(IUnitOfWork uow, List statusTypeIds = null) + { + // get the status types from the repository + var typeBuilderList = uow.StockStatusRepository.ReadStatusType(statusTypeIds); + + // get the accounts for the status types + var accountIds = new List(); + foreach (var type in typeBuilderList.Values) + { + accountIds.Add(type.AccountId); + } + accountIds = accountIds.Distinct().ToList(); + var accountDict = uow.AccountCodeRepository.ReadAccountCode(accountIds); + + // build the status type objects and return them in a dictionary + var returnDict = new Dictionary(); + foreach (var type in typeBuilderList.Values) + { + returnDict.Add(type.StockStatusTypeID, type.Build(accountDict)); + } + return returnDict; + } + + public Dictionary GetStatusType(List statusTypeIds = null) + { + return WithUnitOfWork(uow => + { + return GetStatusType(uow, statusTypeIds); }); } @@ -41,7 +87,5 @@ namespace bnhtrade.Core.Logic.Inventory return uow.StockJournalRepository.ReadStatusBalanceBySku(sku, statusId); }); } - - } } diff --git a/src/bnhtrade.Core/Model/Account/Account.cs b/src/bnhtrade.Core/Model/Account/Account.cs index e8a85bc..8170df7 100644 --- a/src/bnhtrade.Core/Model/Account/Account.cs +++ b/src/bnhtrade.Core/Model/Account/Account.cs @@ -11,7 +11,7 @@ namespace bnhtrade.Core.Model.Account { public Account(int id, int accountCode, string accountName, string description, string type, string basicType, int multiplier) { - Id = id; + AccountId = id; AccountCode = accountCode; AccountName = accountName; Description = description; @@ -23,18 +23,18 @@ namespace bnhtrade.Core.Model.Account /// /// Database record id /// - public int Id { get; private set; } + public int AccountId { get; } - public int AccountCode { get; private set; } + public int AccountCode { get; } - public string AccountName { get; private set; } + public string AccountName { get; } - public string Description { get; private set; } + public string Description { get; } - public string Type { get; private set; } + public string Type { get; } - public string BasicType { get; private set; } + public string BasicType { get; } - public int Multiplier { get; private set; } + public int Multiplier { get; } } } diff --git a/src/bnhtrade.Core/Model/Stock/JournalEntry.cs b/src/bnhtrade.Core/Model/Stock/JournalEntry.cs deleted file mode 100644 index a8ef8e1..0000000 --- a/src/bnhtrade.Core/Model/Stock/JournalEntry.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace bnhtrade.Core.Model.Stock -{ - public class JournalEntry : IValidatableObject - { - public string TypeTitle { get; set; } - - public int StockNumber { get; set; } - - public DateTime EntryDate { get; set; } - - public DateTime PostDate { get; set; } - - public DateTime LastModified { get; set; } - - public bool IsLocked { get; set; } - - public List JournalPosts { get; set; } = new List(); - - public class JournalEntryPost - { - public int JournalPostId { get; set; } - - public int StockStatusId { get; set; } - - [Required()] - public string StockStatus { get; set; } - - [Required()] - public int Quantity { get; set; } - } - - public IEnumerable Validate(ValidationContext validationContext) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/bnhtrade.Core/Model/Stock/Status.cs b/src/bnhtrade.Core/Model/Stock/Status.cs index 244564b..7977850 100644 --- a/src/bnhtrade.Core/Model/Stock/Status.cs +++ b/src/bnhtrade.Core/Model/Stock/Status.cs @@ -21,22 +21,32 @@ namespace bnhtrade.Core.Model.Stock RecordCreated = recordCreated; } - public int StatusId { get; private set; } + public int StatusId { get; } - public int? StatusCode { get; private set; } + public int? StatusCode { get; } - public string StatusTitle { get; private set; } + public bool StatusCodeIsSet + { + get { return StatusCode.HasValue; } + } - public Model.Stock.StatusType StatusType { get; private set; } + public string StatusTitle { get; } - public string Reference { get; private set; } + public Model.Stock.StatusType StatusType { get; } - public int? ForeignKeyID { get; private set; } + public string Reference { get; } - public bool IsCreditOnly { get; private set; } + public int? ForeignKeyID { get; } - public bool IsClosed { get; private set; } + public bool ForeignKeyIDIsSet + { + get { return ForeignKeyID.HasValue; } + } - public DateTime RecordCreated { get; private set; } + public bool IsCreditOnly { get; } + + public bool IsClosed { get; } + + public DateTime RecordCreated { get; } } } diff --git a/src/bnhtrade.Core/Model/Stock/StatusBuilder.cs b/src/bnhtrade.Core/Model/Stock/StatusBuilder.cs new file mode 100644 index 0000000..96e76fc --- /dev/null +++ b/src/bnhtrade.Core/Model/Stock/StatusBuilder.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace bnhtrade.Core.Model.Stock +{ + internal class StatusBuilder + { + public int StatusId { get; set; } + + public int? StatusCode { get; set; } + + public string StatusTitle { get; set; } + + public int StatusTypeId { get; set; } + + public string Reference { get; set; } + + public int? ForeignKeyID { get; set; } + + public bool IsCreditOnly { get; set; } + + public bool IsClosed { get; set; } + + public DateTime RecordCreated { get; set; } + + public Status Build(Dictionary statusTypeDict) + { + if (!statusTypeDict.ContainsKey(StatusTypeId)) + { + throw new InvalidOperationException($"Status type with ID {StatusTypeId} does not exist."); + } + return new Status( + StatusId, + StatusCode, + StatusTitle, + statusTypeDict[StatusTypeId], + Reference, + ForeignKeyID, + IsCreditOnly, + IsClosed, + RecordCreated + ); + } + } +} diff --git a/src/bnhtrade.Core/Model/Stock/StatusType.cs b/src/bnhtrade.Core/Model/Stock/StatusType.cs index c699b4e..9ea3e20 100644 --- a/src/bnhtrade.Core/Model/Stock/StatusType.cs +++ b/src/bnhtrade.Core/Model/Stock/StatusType.cs @@ -17,10 +17,10 @@ namespace bnhtrade.Core.Model.Stock ReferenceType = referenceType; Account = account; } - public int StockStatusTypeID { get; private set; } - public string StatusTypeName { get; private set; } - public string ForeignKeyType { get; private set; } - public string ReferenceType { get; private set; } - public Model.Account.Account Account { get; private set; } + public int StockStatusTypeID { get; } + public string StatusTypeName { get; } + public string ForeignKeyType { get; } + public string ReferenceType { get; } + public Model.Account.Account Account { get; } } } diff --git a/src/bnhtrade.Core/Model/Stock/StatusTypeBuilder.cs b/src/bnhtrade.Core/Model/Stock/StatusTypeBuilder.cs new file mode 100644 index 0000000..02e5199 --- /dev/null +++ b/src/bnhtrade.Core/Model/Stock/StatusTypeBuilder.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace bnhtrade.Core.Model.Stock +{ + internal class StatusTypeBuilder + { + public int StockStatusTypeID { get; set; } + public string StatusTypeName { get; set; } + public string ForeignKeyType { get; set; } + public string ReferenceType { get; set; } + public int AccountId { get; set; } + + public StatusType Build(Dictionary accountDict) + { + if (!accountDict.ContainsKey(AccountId)) + { + throw new InvalidOperationException($"Account with ID {AccountId} does not exist."); + } + return new StatusType( + StockStatusTypeID, + StatusTypeName, + ForeignKeyType, + ReferenceType, + accountDict[AccountId] + ); + } + } +} diff --git a/src/bnhtrade.Core/Model/Stock/StockJournalBuilder.cs b/src/bnhtrade.Core/Model/Stock/StockJournalBuilder.cs new file mode 100644 index 0000000..ffe4cb7 --- /dev/null +++ b/src/bnhtrade.Core/Model/Stock/StockJournalBuilder.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static bnhtrade.Core.Data.Database.Constants; +using static bnhtrade.Core.Model.Stock.StockJournal; + +namespace bnhtrade.Core.Model.Stock +{ + internal class StockJournalBuilder + { + public int StockJournalId { get; set; } + + public int StockJournalTypeId { get; set; } + + public int StockId { get; set; } + + public string StockNumber { get; set; } + + public DateTime EntryDate { get; set; } + + public DateTime PostDate { get; set; } + + public DateTime LastModified { get; set; } + + public bool IsLocked { get; set; } + + public bool AccountIsProcessed { get; set; } + + public List StockJournalBuilderPosts { get; set; } + + public class StockJournalBuilderPost + { + public int StockJournalPostId { get; set; } + + public int StatusId { get; set; } + + public int Quantity { get; set; } + } + + public StockJournal Build(Dictionary stockJournalTypeDict, Dictionary stockStatusDict) + { + if (StockJournalBuilderPosts == null || !StockJournalBuilderPosts.Any()) + { + throw new InvalidOperationException("At least one journal post is required."); + } + + var posts = new List(); + foreach (var builderPost in StockJournalBuilderPosts) + { + var post = new StockJournalPost( + builderPost.StockJournalPostId, + stockStatusDict[builderPost.StockJournalPostId], + builderPost.Quantity + ); + posts.Add(post); + } + + return new StockJournal( + StockJournalId, + stockJournalTypeDict[StockJournalTypeId], + StockId, + StockNumber, + EntryDate, + PostDate, + LastModified, + IsLocked, + posts + ); + } + } +} diff --git a/src/bnhtrade.Core/Model/Stock/StockJournalType.cs b/src/bnhtrade.Core/Model/Stock/StockJournalType.cs index 4821394..d3357fb 100644 --- a/src/bnhtrade.Core/Model/Stock/StockJournalType.cs +++ b/src/bnhtrade.Core/Model/Stock/StockJournalType.cs @@ -8,5 +8,30 @@ namespace bnhtrade.Core.Model.Stock { public class StockJournalType { + public StockJournalType(int stockJournalTypeId, string stockJournalTypeTitle, Status defaultDebitStatus, Status defaultCreditStatus) + { + StockJournalTypeID = stockJournalTypeId; + StockJournalTypeTitle = stockJournalTypeTitle ?? throw new ArgumentNullException(nameof(stockJournalTypeTitle), "Stock journal type title cannot be null."); + DefaultDebitStatus = defaultDebitStatus; + DefaultCreditStatus = defaultCreditStatus; + } + + public int StockJournalTypeID { get; } + + public string StockJournalTypeTitle { get; } + + public Status DefaultDebitStatus { get; } + + public bool DefaultDebitStatusIsSet + { + get { return DefaultDebitStatus != null; } + } + + public Status DefaultCreditStatus { get; } + + public bool DefaultCreditStatusIsSet + { + get { return DefaultCreditStatus != null; } + } } }