This commit is contained in:
2025-07-14 14:29:56 +01:00
parent afd4bae10e
commit 2d751ebf80
15 changed files with 550 additions and 170 deletions

View File

@@ -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<int, Model.Stock.StockJournalBuilder> ReadStockJournal(List<int> stockJournalIdList)
{
if (stockJournalIdList == null || !stockJournalIdList.Any())
{
throw new ArgumentException("Stock journal ID list cannot be null or empty.", nameof(stockJournalIdList));
}
var returnDict = new Dictionary<int, Model.Stock.StockJournalBuilder>();
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<Model.Stock.StockJournalBuilder.StockJournalBuilderPost>()
};
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<int, (int id, string title, int? stockStatusIdDebit, int? stockStatusIdCredit)> ReadStockJournalType(List<int> stockJournalTypeIdList)
{
var returnDict = new Dictionary<int, (int id, string title, int? stockStatusIdDebit, int? stockStatusIdCredit)>();
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)

View File

@@ -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<int, Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null)
public Dictionary<int, Model.Stock.StatusBuilder> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null)
{
var sqlBuilder = new SqlWhereBuilder();
var returnList = new Dictionary<int, Model.Stock.Status>();
var returnList = new Dictionary<int, Model.Stock.StatusBuilder>();
//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<int, Model.Stock.StatusType> ReadStatusType()
public Dictionary<int, Model.Stock.StatusTypeBuilder> ReadStatusType(List<int> stockStatusTypeIds = null)
{
var returnDict = new Dictionary<int, Model.Stock.StatusType>();
var returnDict = new Dictionary<int, Model.Stock.StatusTypeBuilder>();
var sqlWhere = new SqlWhereBuilder();
// get all account info before we start
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode();
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
string sql = @"
SELECT [StockStatusTypeID]
,[StatusTypeName]
,[ForeignKeyType]
,[ReferenceType]
,[AccountChartOfID]
FROM [e2A].[dbo].[tblStockStatusType]";
FROM [e2A].[dbo].[tblStockStatusType]
WHERE 1=1 ";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (sqlWhere.ParameterListIsSet)
{
sqlWhere.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
var accountIdDict = new Dictionary<int, int>();
while (reader.Read())
{
int statusTypeId = reader.GetInt32(0);
string name = reader.GetString(1);
string foreignKey = null;
if (!reader.IsDBNull(2)) { foreignKey = reader.GetString(2); }
string reference = null;
if (!reader.IsDBNull(3)) { reference = reader.GetString(3); }
uint accountId = (uint)reader.GetInt32(4);
var statusType = new Model.Stock.StatusType(statusTypeId, name, foreignKey, reference, accountDict[(int)accountId]);
returnDict.Add(statusTypeId, statusType);
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);
}
}
}

View File

@@ -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<int, Model.Stock.StockJournalBuilder> ReadStockJournal(List<int> stockJournalIdList);
Dictionary<int, (int id, string title, int? stockStatusIdDebit, int? stockStatusIdCredit)> ReadStockJournalType(List<int> 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<string, int> ReadStatusBalanceByStatusId(int statusId);
DateTime? ReadMostRecentEntryDateForStatusDebit(int stockId, List<int> stockStatusIdList);
}
}

View File

@@ -8,7 +8,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IStockStatusRepository
{
Dictionary<int, Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null);
Dictionary<int, Model.Stock.StatusType> ReadStatusType();
Dictionary<int, Model.Stock.StatusBuilder> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null);
Dictionary<int, Model.Stock.StatusTypeBuilder> ReadStatusType(List<int> stockStatusTypeIds = null);
}
}

View File

@@ -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<int, Model.Account.Account> GetAll()
internal AccountCodeService(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
public Dictionary<int, Model.Account.Account> GetAccountCode(List<int> accountIdList = null, List<int> 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<int> { accountCode });
if (list.Any())
{
return list[0];
}
else
{
return null;
}
}
public List<Model.Account.Account> ByAccountCode(List<int> accountCodeList)
{
return WithUnitOfWork(uow =>
{
return uow.AccountCodeRepository.ReadAccountCode(null, accountCodeList).Values.ToList();
});
}
public Dictionary<int, Model.Account.Account> ConvertToDictionary(List<Model.Account.Account> accountCodeList)
{
var returnDict = new Dictionary<int, Model.Account.Account>();
if (accountCodeList == null)
{
return returnDict;
}
foreach (var accountCode in accountCodeList)
{
if (!returnDict.ContainsKey((int)accountCode.AccountCode))
{
returnDict.Add((int)accountCode.AccountCode, accountCode);
}
}
return returnDict;
}
}
}

View File

@@ -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<int, Model.Stock.StockJournal> ReadStockJournal(List<int> 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<int>();
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<int>();
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<int, Model.Stock.StockJournal>();
foreach (var journal in builderList.Values)
{
returnDict.Add(journal.StockJournalId, journal.Build(journalTypeDict, statusDict));
}
return returnDict;
});
}
public Dictionary<int, Model.Stock.StockJournalType> ReadStockJournalType(List<int> stockJournalTypeIds = null)
{
return WithUnitOfWork(uow =>
{
return ReadStockJournalType(uow, stockJournalTypeIds);
});
}
private Dictionary<int, Model.Stock.StockJournalType> ReadStockJournalType(IUnitOfWork uow, List<int> 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<int>();
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<int, Model.Stock.StockJournalType>();
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<int, bool>();
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<int>()
var postIdList = new List<int>();
foreach (var post in journalPosts)
{
postIdList.Add(uow.StockJournalRepository.InsertStockJournalPost(stockJournalId, post.statusId, post.quantity));

View File

@@ -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<int>();
foreach (var status in builderList)
{
satusTypeIdList.Add(status.StatusTypeId);
}
satusTypeIdList = satusTypeIdList.Distinct().ToList();
var statusTypeDict = GetStatusType(uow, satusTypeIdList);
var retrunDict = new Dictionary<int, Model.Stock.Status>();
foreach (var status in builderList)
{
retrunDict.Add(status.StatusId, status.Build(statusTypeDict));
}
return retrunDict;
});
}
private Dictionary<int, Model.Stock.StatusType> GetStatusType(IUnitOfWork uow, List<int> 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<int>();
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<int, Model.Stock.StatusType>();
foreach (var type in typeBuilderList.Values)
{
returnDict.Add(type.StockStatusTypeID, type.Build(accountDict));
}
return returnDict;
}
public Dictionary<int, Model.Stock.StatusType> GetStatusType(List<int> statusTypeIds = null)
{
return WithUnitOfWork(uow =>
{
return GetStatusType(uow, statusTypeIds);
});
}
@@ -41,7 +87,5 @@ namespace bnhtrade.Core.Logic.Inventory
return uow.StockJournalRepository.ReadStatusBalanceBySku(sku, statusId);
});
}
}
}

View File

@@ -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
/// <summary>
/// Database record id
/// </summary>
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; }
}
}

View File

@@ -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<JournalEntryPost> JournalPosts { get; set; } = new List<JournalEntryPost>();
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<ValidationResult> Validate(ValidationContext validationContext)
{
throw new NotImplementedException();
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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<int, StatusType> 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
);
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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<int, Model.Account.Account> accountDict)
{
if (!accountDict.ContainsKey(AccountId))
{
throw new InvalidOperationException($"Account with ID {AccountId} does not exist.");
}
return new StatusType(
StockStatusTypeID,
StatusTypeName,
ForeignKeyType,
ReferenceType,
accountDict[AccountId]
);
}
}
}

View File

@@ -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<StockJournalBuilderPost> 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<int, StockJournalType> stockJournalTypeDict, Dictionary<int, Status> stockStatusDict)
{
if (StockJournalBuilderPosts == null || !StockJournalBuilderPosts.Any())
{
throw new InvalidOperationException("At least one journal post is required.");
}
var posts = new List<StockJournalPost>();
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
);
}
}
}

View File

@@ -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; }
}
}
}