Bug fix in ExportSalesInvoice and converted more code over to repository and service pattern

This commit is contained in:
2025-07-07 15:22:21 +01:00
parent 5900a6e6e4
commit 5cd653d700
64 changed files with 2623 additions and 2517 deletions
@@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
//using System.Data.SqlClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Account
{
public class CreateInvoiceLineItem : Connection
{
public CreateInvoiceLineItem()
{
}
public int CreateDefault(string itemCode)
{
using (var conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblAccountInvoiceLineItem ( ItemName, ItemCode )
OUTPUT INSERTED.AccountInvoiceLineItemID
VALUES ( @itemName, @itemCode )
", conn))
{
cmd.Parameters.AddWithValue("@itemName", itemCode);
cmd.Parameters.AddWithValue("@itemCode", itemCode);
object obj = cmd.ExecuteScalar();
if (obj == null || obj == DBNull.Value)
{
throw new Exception("Error inserting new defalt invoice line item into database");
}
return (int)obj;
}
}
}
}
}
@@ -1,64 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Account
{
internal class DeleteJournal : Connection
{
/// <summary>
/// Old code needs sorting
/// </summary>
public bool AccountJournalDelete(int accountJournalId)
{
// check if journal entry is locked
using (TransactionScope scope = new TransactionScope())
{
bool IsLocked = new Data.Database.Account.ReadJournal().EntryIsLocked(accountJournalId);
if (IsLocked == true)
{
return false;
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
// make the delete
using (SqlCommand cmd = new SqlCommand(@"
DELETE FROM tblAccountJournalPost
WHERE AccountJournalID=@accountJournalId;
", conn))
{
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
int rows = cmd.ExecuteNonQuery();
if (rows == 0)
{
throw new Exception("Journal entry and/or entry posts do not exist for AccountJournalId=" + accountJournalId);
}
}
using (SqlCommand cmd = new SqlCommand(@"
DELETE FROM tblAccountJournal
WHERE AccountJournalID=@accountJournalId;
", conn))
{
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
cmd.ExecuteNonQuery();
}
scope.Complete();
return true;
}
}
}
}
}
@@ -1,126 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Account
{
public class ReadAccountCode : Connection
{
private Data.Database.SqlWhereBuilder sqlWhere = new SqlWhereBuilder();
public ReadAccountCode()
{
}
/// <summary>
/// Gets the full chart of accounts
/// </summary>
/// <returns>Dictionary where the database record id is the key</returns>
public Dictionary<uint, Model.Account.Account> All()
{
Innit();
var list = Execute(null, null);
var dictionary = new Dictionary<uint, Model.Account.Account>();
foreach (var item in list)
{
dictionary.Add(item.Value.Id, item.Value);
}
return dictionary;
}
public Dictionary<uint, Model.Account.Account> ByAccountId(List<uint> accountIdList)
{
Innit();
var resultDict = new Dictionary<uint, Model.Account.Account>();
if (accountIdList == null || !accountIdList.Any())
{
return resultDict;
}
sqlWhere.In("tblAccountChartOf.AccountChartOfID", accountIdList, " WHERE ");
resultDict = Execute(sqlWhere.SqlWhereString, sqlWhere.ParameterList);
return resultDict;
}
public Dictionary<uint, Model.Account.Account> ByAccountCode(List<int> accountCodeList)
{
Innit();
var resultDict = new Dictionary<uint, Model.Account.Account>();
if (accountCodeList == null || !accountCodeList.Any())
{
return resultDict;
}
sqlWhere.In("tblAccountChartOf.AccountCode", accountCodeList, " WHERE ");
resultDict = Execute(sqlWhere.SqlWhereString, sqlWhere.ParameterList);
return resultDict;
}
private Dictionary<uint, Model.Account.Account> Execute(string sqlWhere, Dictionary<string, object> parameters)
{
var resultDict = new Dictionary<uint, Model.Account.Account>();
//build sql query
string sqlString = @"
SELECT tblAccountChartOf.AccountChartOfID
,tblAccountChartOf.AccountCode
,tblAccountChartOf.AccountName
,tblAccountChartOf.Description
,tblAccountChartOfType.AccountChartOfType
,tblAccountChartOfType.BasicType
,tblAccountChartOfType.Multiplier
FROM tblAccountChartOf
INNER JOIN tblAccountChartOfType ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
" + sqlWhere;
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
if (parameters != null)
{
foreach (var parameter in parameters)
{
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value);
}
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
uint tablePk = (uint)reader.GetInt32(0);
uint accountCode = (uint)reader.GetInt32(1);
string title = reader.GetString(2);
string description = null;
if (!reader.IsDBNull(3)) { description = reader.GetString(3); }
string type = reader.GetString(4);
string basicType = reader.GetString(5);
int multiplier = reader.GetInt32(6);
var result = new Model.Account.Account(tablePk, accountCode, title, description, type, basicType, multiplier);
resultDict.Add(tablePk, result);
}
}
}
}
}
return resultDict;
}
private void Innit()
{
sqlWhere.Init();
}
}
}
@@ -1,123 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadInvoiceLineItem : Connection
{
public ReadInvoiceLineItem()
{
}
/// <summary>
/// Reads all invoice line items from the database.
/// </summary>
/// <returns>dictionary where key=id, value=object</returns>
internal Dictionary<int, Model.Account.InvoiceLineItem> All()
{
return Execute();
}
/// <summary>
/// Read list of invoice line items by item code.
/// </summary>
/// <param name="itemCodes">List of item coeds to query db against</param>
/// <returns>dictionary where key=id, value=object</returns>
/// <exception cref="ArgumentException"></exception>
internal Dictionary<int, Model.Account.InvoiceLineItem> ByItemCode(List<string> itemCodes)
{
if (itemCodes == null || !itemCodes.Any())
{
throw new ArgumentException("Item codes list cannot be null or empty.");
}
var sqlwhere = new SqlWhereBuilder();
sqlwhere.In("ItemCode", itemCodes, "AND");
return Execute(sqlwhere);
}
private Dictionary<int, Model.Account.InvoiceLineItem> Execute(SqlWhereBuilder sqlwhere = null)
{
var resultList = new Dictionary<int, Model.Account.InvoiceLineItem>();
var accountCodeIdList = new Dictionary<int, uint>(); // key=LineItemID, value=AccountChartOfID
var taxCodeIdList = new Dictionary<int, int>(); // key=LineItemID, value=AccountTaxCodeID
string sql = @"
SELECT [AccountInvoiceLineItemID]
,[ItemName]
,[ItemCode]
,[ItemDescription]
,[IsNewReviewRequired]
,[InvoiceLineEntryEnable]
,[AccountChartOfID_Default]
,[AccountTaxCodeID_Default]
FROM [e2A].[dbo].[tblAccountInvoiceLineItem]
WHERE 1=1 ";
if (sqlwhere != null)
{
sql += sqlwhere.SqlWhereString;
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
if (sqlwhere != null)
{
sqlwhere.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var lineItem = new Model.Account.InvoiceLineItem();
int lineItemId = reader.GetInt32(0);
lineItem.Name = reader.GetString(1);
lineItem.ItemCode = reader.GetString(2);
if (!reader.IsDBNull(3)) { lineItem.Description = reader.GetString(3); }
lineItem.IsNewReviewRequired = reader.GetBoolean(4);
lineItem.InvoiceLineEntryEnabled = reader.GetBoolean(5);
if (!reader.IsDBNull(6))
{
accountCodeIdList.Add(lineItemId, (uint)reader.GetInt32(6));
}
if (!reader.IsDBNull(7))
{
taxCodeIdList.Add(lineItemId, reader.GetInt32(7));
}
resultList.Add(lineItemId, lineItem);
}
}
}
// get account codes and add to result list
var accountCodeDictionary = new Data.Database.Account.ReadAccountCode().ByAccountId(accountCodeIdList.Values.ToList());
foreach (var accountCode in accountCodeIdList)
{
resultList[accountCode.Key].DefaultAccountCode = accountCodeDictionary[accountCode.Value];
}
// get tax codes
var taxCodeDictionary = new Data.Database.Account.ReadTaxCode().GetByTaxCodeId(taxCodeIdList.Values.ToList());
foreach (var taxCode in taxCodeIdList)
{
resultList[taxCode.Key].DefaultTaxCode = taxCodeDictionary[taxCode.Value];
}
return resultList;
}
}
}
}
@@ -1,242 +0,0 @@
using FikaAmazonAPI.AmazonSpApiSDK.Models.CatalogItems;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.InteropServices.Marshalling;
using System.Text;
using System.Threading.Tasks;
using static System.ComponentModel.Design.ObjectSelectorEditor;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadJournal : Connection
{
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
/// <summary>
/// Filter the read results
/// </summary>
public List<uint> AccountJournalId { get; set; }
public ReadJournal()
{
Init();
}
public void Init()
{
sqlBuilder = new SqlWhereBuilder();
AccountJournalId = new List<uint>();
}
/// <summary>
///
/// </summary>
/// <returns>Dictionary were key is the table primary key</returns>
public Dictionary<uint, Core.Model.Account.Journal> Read()
{
sqlBuilder.Init();
//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 (AccountJournalId.Any())
{
sqlBuilder.In("tblAccountJournal.AccountJournalID", AccountJournalId, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// build tuple list
var dbJournalList = new List<(
uint AccountJournalId
, uint AccountJournalTypeId
, DateTime EntryDate
, DateTime PostDate
, DateTime LastModified
, bool IsLocked
)>();
var dbJournalPostList = new List<(
uint AccountJournalId
, uint AccountJournalPostId
, uint AccountChartOfId
, decimal AmountGbp
)>();
bool hasRows = false;
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
hasRows = true;
uint lastJournalId = 0;
while (reader.Read())
{
// read journal header
uint journalId = (uint)reader.GetInt32(0);
if (journalId != lastJournalId)
{
lastJournalId = journalId;
(uint AccountJournalId
, uint AccountJournalTypeId
, DateTime EntryDate
, DateTime PostDate
, DateTime LastModified
, bool IsLocked
)
journal =
( journalId
, (uint)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
(uint AccountJournalId
, uint AccountJournalPostId
, uint AccountChartOfId
, decimal AmountGbp
)
journalPost =
( journalId
, (uint)reader.GetInt32(6)
, (uint)reader.GetInt32(7)
, reader.GetDecimal(8)
);
dbJournalPostList.Add(journalPost);
}
}
}
}
}
var returnList = new Dictionary<uint, Core.Model.Account.Journal>();
if (hasRows)
{
// build lists to filter db results by
var journalTypeIdList = new List<uint>();
var accountIdList = new List<uint>();
foreach (var item in dbJournalList)
{
journalTypeIdList.Add(item.AccountJournalTypeId);
}
foreach (var item in dbJournalPostList)
{
accountIdList.Add(item.AccountChartOfId);
}
// get journalTypes from db
var dbJournalType = new Data.Database.Account.ReadJournalType();
dbJournalType.IdList = journalTypeIdList;
var journalTypeDict = dbJournalType.Read();
// get accounts from db
var dbAccount = new Data.Database.Account.ReadAccountCode();
var accountDict = dbAccount.ByAccountId(accountIdList);
// build final return dictionary
foreach (var dbJournal in dbJournalList)
{
// build posts
var newPosts = new List<Core.Model.Account.Journal.Post>();
foreach (var dbJournalPost in dbJournalPostList)
{
if (dbJournalPost.AccountJournalId == dbJournal.AccountJournalId)
{
var newPost = new Core.Model.Account.Journal.Post(
dbJournalPost.AccountJournalPostId
, accountDict[dbJournalPost.AccountChartOfId]
, dbJournalPost.AmountGbp);
newPosts.Add(newPost);
}
}
// create the journal
var newJournal = new Core.Model.Account.Journal(
dbJournal.AccountJournalId
, journalTypeDict[dbJournal.AccountJournalTypeId]
, newPosts
, dbJournal.EntryDate
, dbJournal.PostDate
, dbJournal.LastModified
, dbJournal.IsLocked);
returnList.Add(dbJournal.AccountJournalId, newJournal);
}
}
// all done, return the list herevar
return returnList;
}
/// <summary>
/// Test for locked journal entry
/// </summary>
/// <returns>False on locked journal entry</returns>
public bool EntryIsLocked(int journalId)
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT
tblAccountJournal.IsLocked
FROM
tblAccountJournal
WHERE
tblAccountJournal.AccountJournalID=@accountJournalId;
", conn))
{
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
object obj = cmd.ExecuteScalar();
if (obj == null)
{
throw new Exception("Journal entry not found for AccountJournalID=" + journalId);
}
else
{
return (bool)obj;
}
}
}
}
}
}
@@ -1,144 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadJournalType : Connection
{
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
/// <summary>
/// Results filter
/// </summary>
public List<uint> IdList { get; set; }
/// <summary>
/// Searches for the specificed phases within the item description. Uses the LIKE AND sql function
/// </summary>
public List<string> TitleList { get; set; }
public ReadJournalType()
{
Init();
}
public void Init()
{
sqlBuilder = new SqlWhereBuilder();
IdList = new List<uint>();
TitleList = new List<string>();
}
/// <summary>
///
/// </summary>
/// <returns>Dictionary where key is the table primary key</returns>
public Dictionary<uint, Model.Account.JournalType> Read()
{
// create the return (emptyP list) here
var returnList = new Dictionary<uint, Model.Account.JournalType>();
sqlBuilder.Init();
//build sql query
string sql = @"
SELECT [AccountJournalTypeID]
,[TypeTitle]
,[ChartOfAccountID_Debit]
,[ChartOfAccountID_Credit]
FROM [e2A].[dbo].[tblAccountJournalType]
WHERE 1 = 1 ";
// build the where statments
if (IdList.Any())
{
sqlBuilder.In("AccountJournalTypeID", IdList, "AND");
}
if (TitleList.Any())
{
sqlBuilder.In("TypeTitle", TitleList, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// create dictionary to add credit/debit accounts on after db read
var creditDict = new Dictionary<uint, uint>();
var debitDict = new Dictionary<uint, uint>();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
// read from db and create object
uint journalTypeId = (uint)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, (uint)debitAccountId);
}
if (creditAccountId != null)
{
creditDict.Add(journalTypeId, (uint)creditAccountId);
}
}
}
}
}
}
// get account objects from db
var accountIdList = debitDict.Values.ToList();
accountIdList.AddRange(creditDict.Values.ToList());
var dbaccount = new Data.Database.Account.ReadAccountCode();
var dbDict = dbaccount.ByAccountId(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;
}
}
}
@@ -1,178 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.ComponentModel.Design.ObjectSelectorEditor;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadPurchaseInvoice : Connection
{
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
public IEnumerable<int> PurchaseInvoiceIdList { get; set; }
public ReadPurchaseInvoice()
{
Init();
}
public void Init()
{
sqlBuilder = new SqlWhereBuilder();
PurchaseInvoiceIdList = new List<int>();
}
public Dictionary<int, Model.Account.PurchaseInvoice> Read()
{
var returnList = new Dictionary<int, Model.Account.PurchaseInvoice>();
sqlBuilder.Init();
//build sql query
string sql = @"
SELECT tblPurchase.PurchaseID
,tblPurchase.PurchaseNumber
,tblPurchase.RecordID
,tblPurchase.PurchaseDate
,tblPurchase.ContactID
,tblPurchase.SupplierRef
,tblPurchase.PurchaseTotalAmount
,tblPurchase.VatInclusiveAmounts
,tblPurchase.RecordCreated
,tblPurchase.RecordModified
,tblPurchase.IsActive
,tblAccountCurrency.CurrencyCode
,tblPurchaseChannel.PurchaseChannelName
,tblPurchaseStatus.PurchaseStatus
FROM tblPurchase
LEFT OUTER JOIN tblAccountCurrency ON tblPurchase.AccountCurrencyID = tblAccountCurrency.AccountCurrencyID
LEFT OUTER JOIN tblPurchaseStatus ON tblPurchase.PurchaseStatusID = tblPurchaseStatus.PurchaseStatusID
LEFT OUTER JOIN tblPurchaseChannel ON tblPurchase.PurchaseChannelID = tblPurchaseChannel.PurchaseChannelID
WHERE 1 = 1
";
// build the where statments
if (PurchaseInvoiceIdList.Any())
{
sqlBuilder.In("[PurchaseID]", PurchaseInvoiceIdList, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// dictionary so we can fill in details afterwards
var invoiceContactDict = new Dictionary<int, int>();
var purchaseIdList = new List<int>();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int purchaseID = reader.GetInt32(0);
int purchaseNumber = reader.GetInt32(1);
int? recordID = null;
if (!reader.IsDBNull(2)) { recordID = reader.GetInt32(2); }
DateTime purchaseDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
int? contactID = null;
if (!reader.IsDBNull(4)) { contactID = reader.GetInt32(4);}
string supplierRef = null;
if (!reader.IsDBNull(5)) { supplierRef = reader.GetString(5);}
decimal? purchaseTotalAmount = null;
if (!reader.IsDBNull(6)) { purchaseTotalAmount = reader.GetDecimal(6);}
bool vatInclusiveAmounts = reader.GetBoolean(7);
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc);
DateTime recordModified = DateTime.SpecifyKind(reader.GetDateTime(9), DateTimeKind.Utc);
bool isActive = reader.GetBoolean(10);
string currencyCode = reader.GetString(11);
string purchaseChannelName = reader.GetString(12);
string purchaseStatus = null;
if (!reader.IsDBNull(13)) { purchaseStatus = reader.GetString(13);}
var invoice = new Model.Account.PurchaseInvoice();
invoice.PurchaseID = purchaseID;
invoice.PurchaseNumber = purchaseNumber;
invoice.RecordID = recordID;
invoice.PurchaseDate = purchaseDate;
invoice.SupplierRef = supplierRef;
//invoice.PurchaseTotalAmount = purchaseTotalAmount;
invoice.VatInclusiveAmounts = vatInclusiveAmounts;
invoice.RecordCreated = recordCreated;
invoice.RecordModified = recordModified;
invoice.IsActive = isActive;
invoice.CurrencyCode = currencyCode;
invoice.PurchaseChannel = purchaseChannelName;
// is there contact info that needs to be added?
if (contactID != null)
{
invoiceContactDict.Add(purchaseID, (int)contactID);
}
purchaseIdList.Add(purchaseID);
returnList.Add(purchaseID, invoice);
}
}
}
}
}
// add contact info
if (invoiceContactDict.Any())
{
var readContact = new Data.Database.Account.ReadContact();
readContact.ContactIdList = invoiceContactDict.Values.ToList();
var contactDict = readContact.Read();
if (contactDict.Any())
{
foreach ( var invoice in returnList)
{
if (invoiceContactDict.ContainsKey(invoice.Value.PurchaseID))
{
int contactId = invoiceContactDict[invoice.Value.PurchaseID];
invoice.Value.Contact = contactDict[contactId];
}
}
}
}
// add invoice lines
var readLines = new Data.Database.Account.ReadPurchaseInvoiceLine();
readLines.InvoiceIdList = purchaseIdList;
var lines = readLines.Read();
foreach(var invoice in returnList.Values)
{
foreach(var line in lines.Values)
{
if (line.PurchaseId == invoice.PurchaseID)
{
if (invoice.InvoiceLines == null)
{
invoice.InvoiceLines = new List<Model.Account.PurchaseInvoice.Line>();
}
invoice.InvoiceLines.Add(line);
}
}
}
return returnList;
}
}
}
@@ -1,212 +0,0 @@
using Amazon.Runtime.Internal.Transform;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.ComponentModel.Design.ObjectSelectorEditor;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadPurchaseInvoiceLine : Connection
{
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
/// <summary>
/// Results filter
/// </summary>
public List<int> InvoiceIdList { get; set; }
/// <summary>
/// Results filter
/// </summary>
public List<int> InvoiceLineIdList { get; set; }
/// <summary>
/// Results filter
/// </summary>
public List<string> StatusList { get; set; }
/// <summary>
/// Searches for the specificed phases within the item description. Uses the LIKE AND sql function
/// </summary>
public List<string> ItemDescription { get; set; }
public ReadPurchaseInvoiceLine()
{
Init();
}
public void Init()
{
sqlBuilder = new SqlWhereBuilder();
InvoiceIdList = new List<int>();
InvoiceLineIdList = new List<int>();
StatusList = new List<string>();
ItemDescription = new List<string>();
}
public Dictionary<int, Model.Account.PurchaseInvoice.Line> Read()
{
var returnList = new Dictionary<int, Model.Account.PurchaseInvoice.Line>();
sqlBuilder.Init();
//build sql query
string sql = @"
SELECT tblPurchaseLine.PurchaseLineID
,tblPurchaseLine.PurchaseID
,tblPurchaseLineStatus.PurchaseLineStatus
,tblPurchaseLine.SupplierRef
,tblPurchaseLine.CheckedIn
,tblPurchaseLine.ItemDescription
,tblPurchaseLine.ItemQuantity
,tblPurchaseLine.ItemGross
,tblPurchaseLine.ItemTax
,tblPurchaseLine.ShippingGross
,tblPurchaseLine.ShippingTax
,tblPurchaseLine.OtherGross
,tblPurchaseLine.OtherTax
,tblPurchaseLine.AccountTaxCodeID
,tblPurchaseLine.Tax_AccountTransactionID
,tblPurchaseLine.Net_AccountChartOfID
,tblPurchaseLine.Net_AccountTransactionID
,tblPurchaseLine.RecordCreated
,tblPurchaseLine.RecordModified
,tblPurchaseLine.IsActive
,tblAccountTaxCode.TaxCode
FROM tblPurchaseLine
INNER JOIN tblPurchaseLineStatus ON tblPurchaseLine.PurchaseLineStatusID = tblPurchaseLineStatus.PurchaseLineStatusID
LEFT OUTER JOIN tblAccountTaxCode ON tblPurchaseLine.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID
WHERE 1 = 1 ";
// build the where statments
if (InvoiceIdList.Any())
{
sqlBuilder.In("PurchaseID", InvoiceLineIdList, "AND");
}
if (InvoiceLineIdList.Any())
{
sqlBuilder.In("PurchaseLineID", InvoiceLineIdList, "AND");
}
if (StatusList.Any())
{
sqlBuilder.In("PurchaseLineStatus", InvoiceLineIdList, "AND");
}
if (ItemDescription.Any())
{
sqlBuilder.LikeAnd("ItemDescription", ItemDescription, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// catch taxcode to add in after db read
var lineTaxCodeDict = new Dictionary<int, string>();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int purchaseLineID = reader.GetInt32(0);
int purchaseID = reader.GetInt32(1);
string purchaseLineStatus = reader.GetString(2);
string supplierRef = null;
if (!reader.IsDBNull(3)) { supplierRef = reader.GetString(3); }
DateTime? checkedIn = null;
if (!reader.IsDBNull(4)) { checkedIn = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc); }
string itemDescription = null;
if (!reader.IsDBNull(5)) { itemDescription = reader.GetString(5); }
int itemQuantity = reader.GetInt32(6);
decimal itemGross = 0;
if (!reader.IsDBNull(7)) { itemGross = reader.GetDecimal(7); }
decimal itemTax = 0;
if (!reader.IsDBNull(8)) { itemTax = reader.GetDecimal(8); }
decimal shippingGross = 0;
if (!reader.IsDBNull(9)) { shippingGross = reader.GetDecimal(9); }
decimal shippingTax = 0;
if (!reader.IsDBNull(10)) { shippingTax = reader.GetDecimal(10); }
decimal otherGross = 0;
if (!reader.IsDBNull(11)) { otherGross = reader.GetDecimal(11); }
decimal otherTax = 0;
if (!reader.IsDBNull(12)) { otherTax = reader.GetDecimal(12); }
int accountTaxCodeID = reader.GetInt32(13);
int? tax_AccountTransactionID = null;
if (!reader.IsDBNull(14)) { tax_AccountTransactionID = reader.GetInt32(14); }
int net_AccountChartOfID = reader.GetInt32(15);
int? net_AccountTransactionID = null;
if (!reader.IsDBNull(16)) { net_AccountTransactionID = reader.GetInt32(16); }
DateTime recordModified;
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(17), DateTimeKind.Utc);
if (reader.IsDBNull(18)) { recordModified = recordCreated; }
else { recordModified = DateTime.SpecifyKind(reader.GetDateTime(18), DateTimeKind.Utc); }
bool isActive = reader.GetBoolean(19);
string accountTaxCode = reader.GetString(20);
var line = new Model.Account.PurchaseInvoice.Line();
line.PurchaseLineId = purchaseLineID;
line.PurchaseId = purchaseID;
line.Status = purchaseLineStatus;
line.SupplierRef = supplierRef;
line.CheckedIn = checkedIn;
line.ItemDescription = itemDescription;
line.ItemQuantity = itemQuantity;
line.ItemGross = itemGross;
line.ItemTax = itemTax;
line.ShippingGross = shippingGross;
line.ShippingTax = shippingTax;
line.OtherGross = otherGross;
line.OtherTax = otherTax;
line.Tax_AccountTransactionId = tax_AccountTransactionID;
line.Net_AccountChartOfId = net_AccountChartOfID;
line.Net_AccountTransactionId = net_AccountTransactionID;
line.RecordModified = recordModified;
line.RecordCreated = recordCreated;
line.IsActive = isActive;
returnList.Add(purchaseLineID, line);
lineTaxCodeDict.Add(purchaseLineID, accountTaxCode);
}
}
}
}
}
// read tax codes form db and add to return object
var taxcodeList = new Data.Database.Account.ReadTaxCode().GetByTaxCode(lineTaxCodeDict.Values.ToList());
foreach (var line in returnList.Values)
{
foreach(var taxcode in taxcodeList)
{
if (taxcode.TaxCode == lineTaxCodeDict[line.PurchaseLineId])
{
line.AccountTaxCode = taxcode;
break;
}
}
if (line.AccountTaxCode == null)
{
throw new Exception("Fail safe, this really shouodn't happen");
}
}
// all done
return returnList;
}
}
}
@@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadPurchaseInvoiceLineStatus : Connection
{
public Dictionary<int, Model.Account.PurchaseInvoiceLineStatus> Read()
{
var returnList = new Dictionary<int, Model.Account.PurchaseInvoiceLineStatus>();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT [PurchaseLineStatusID]
,[PurchaseLineStatus]
,[ListSort]
,[TimeStamp]
FROM [e2A].[dbo].[tblPurchaseLineStatus]
ORDER BY [ListSort]
", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
// do something
}
else
{
while (reader.Read())
{
int id = reader.GetInt32(0);
string name = reader.GetString(1);
int lineSort = reader.GetInt32(2);
var returnItem = new Model.Account.PurchaseInvoiceLineStatus(id, name,lineSort);
returnList.Add(id, returnItem );
}
}
}
}
}
return returnList;
}
}
}
@@ -1,91 +0,0 @@
using FikaAmazonAPI.AmazonSpApiSDK.Models.ProductFees;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.ComponentModel.Design.ObjectSelectorEditor;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadPurchaseInvoiceLineSummary : Connection
{
public List<Model.Account.PurchaseInvoiceLineSummary> Read(DateTime periodTo, string lineStatus, List<string> descriptionSearch)
{
var returnList = new List<Model.Account.PurchaseInvoiceLineSummary>();
var sqlBuilder = new bnhtrade.Core.Data.Database.SqlWhereBuilder();
//build sql query
string sql = @"
SELECT tblPurchase.PurchaseDate
,tblPurchase.PurchaseID
,tblPurchase.PurchaseNumber
,tblPurchaseLine.PurchaseLineID
,tblPurchaseLine.ItemDescription
,tblPurchaseLineStatus.PurchaseLineStatus
FROM tblPurchase
INNER JOIN tblPurchaseLine ON tblPurchase.PurchaseID = tblPurchaseLine.PurchaseID
INNER JOIN tblPurchaseLineStatus ON tblPurchaseLine.PurchaseLineStatusID = tblPurchaseLineStatus.PurchaseLineStatusID
WHERE tblPurchase.PurchaseDate <= @purchaseDate
";
if (lineStatus != null)
{
sql = sql + " AND PurchaseLineStatus = @purchaseLineStatus ";
}
// build the where statments
if (descriptionSearch.Any())
{
sqlBuilder.LikeAnd("ItemDescription", descriptionSearch, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@purchaseDate", periodTo);
if (lineStatus != null)
{
cmd.Parameters.AddWithValue("@purchaseLineStatus", lineStatus);
}
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
DateTime purchaseDate = DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc);
int purchaseID = reader.GetInt32(1);
int purchaseNumber = reader.GetInt32(2);
int purchaseLineID = reader.GetInt32(3);
string itemDescription = reader.GetString(4);
string purchaseLineStatus = reader.GetString(5);
var item = new Model.Account.PurchaseInvoiceLineSummary();
item.PurchaseDate = purchaseDate;
item.PurchaseId = purchaseID;
item.PurchaseNumber = purchaseNumber;
item.PurchaseLineId = purchaseLineID;
item.ItemDescription = itemDescription;
item.LineStatus = purchaseLineStatus;
returnList.Add(item);
}
}
}
}
return returnList;
}
}
}
@@ -1,242 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Account
{
internal class ReadTaxCode : Connection
{
private Data.Database.SqlWhereBuilder whereBuilder = new SqlWhereBuilder();
public ReadTaxCode()
{
}
private Dictionary<int, Model.Account.TaxCodeInfo> Execute(string sqlWhere, Dictionary<string, object> parameters)
{
var resultList = new Dictionary<int, Model.Account.TaxCodeInfo>();
//build sql query
string sqlString = @"
SELECT
AccountTaxCodeID
,TaxCode
,TaxCodeName
,TaxCodeDescription
,TaxRatePercent
,IsMarginScheme
,IsValidOnExpense
,IsVailidOnIncome
,IsActive
,TaxType
FROM tblAccountTaxCode";
sqlString += sqlWhere;
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
foreach (var paramter in parameters)
{
cmd.Parameters.AddWithValue(paramter.Key, paramter.Value);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int taxCodeId = reader.GetByte(0);
string taxCode = reader.GetString(1);
string name = reader.GetString(2);
string description = null;
if (!reader.IsDBNull(3)) { description = reader.GetString(3); }
decimal rate = reader.GetDecimal(4);
bool isMargin = reader.GetBoolean(5);
bool isValidOnExpense = reader.GetBoolean(6);
bool isValidOnIncome = reader.GetBoolean(7);
bool isActive = reader.GetBoolean(8);
string taxType = reader.GetString(9);
var result = new Model.Account.TaxCodeInfo(
taxCode,
name,
description,
rate,
isMargin,
isValidOnExpense,
isValidOnIncome,
taxType,
isActive);
resultList.Add(taxCodeId, result);
}
}
}
}
}
return resultList;
}
public List<Model.Account.TaxCodeInfo> GetByTaxCode(List<string> taxcodeList)
{
var resultList = new List<Model.Account.TaxCodeInfo>();
if (taxcodeList == null || !taxcodeList.Any())
{
return resultList;
}
taxcodeList = taxcodeList.Distinct().ToList();
whereBuilder.Init();
whereBuilder.In("TaxCode", taxcodeList, "WHERE");
var dic = Execute(whereBuilder.SqlWhereString, whereBuilder.ParameterList);
return dic.Values.ToList();
}
public Dictionary<int, Model.Account.TaxCodeInfo> GetByTaxCodeId(List<int> taxcodeIdList)
{
var resultList = new Dictionary<int, Model.Account.TaxCodeInfo>();
if (taxcodeIdList == null || !taxcodeIdList.Any())
{
return resultList;
}
taxcodeIdList = taxcodeIdList.Distinct().ToList();
whereBuilder.Init();
whereBuilder.In("AccountTaxCodeID", taxcodeIdList, "WHERE");
return Execute(whereBuilder.SqlWhereString, whereBuilder.ParameterList);
}
/// <summary>
/// Gets all active Tax Code objects
/// </summary>
/// <returns>Dictionary where database record ID is the key</returns>
public Dictionary<int, Model.Account.TaxCodeInfo> GetAllActive()
{
string sqlWhere = @"
WHERE IsActive=@isActive;";
var parameters = new Dictionary<string, object>();
parameters.Add("@isActive", true);
return Execute(sqlWhere, parameters);
}
public Dictionary<string, string> GetTaxCodeBySkuNumber(List<string> skuNumberList)
{
var resultList = new Dictionary<string, string>();
if (skuNumberList == null || !skuNumberList.Any())
{
return resultList;
}
skuNumberList = skuNumberList.Distinct().ToList();
string sql = @"
SELECT tblSku.skuSkuNumber
,tblAccountTaxCode.TaxCode
FROM tblSku
INNER JOIN tblAccountTaxCode ON tblSku.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID ";
whereBuilder.Init();
whereBuilder.In("tblSku.skuSkuNumber", skuNumberList, "WHERE");
sql += whereBuilder.SqlWhereString;
using (var conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (var cmd = new SqlCommand(sql, conn))
{
foreach (var param in whereBuilder.ParameterList)
{
cmd.Parameters.AddWithValue(param.Key, param.Value);
}
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return resultList;
}
while (reader.Read())
{
resultList.Add(reader.GetString(0), reader.GetString(1));
}
}
}
}
return resultList;
}
public Dictionary<string, string> GetTaxCodeByInvoiceLineItemCode(List<string> lineItemCode)
{
var resultList = new Dictionary<string, string>();
if (lineItemCode == null || !lineItemCode.Any())
{
return resultList;
}
lineItemCode = lineItemCode.Distinct().ToList();
string sql = @"
SELECT tblAccountInvoiceLineItem.ItemCode
,tblAccountTaxCode.TaxCode
FROM tblAccountInvoiceLineItem
LEFT OUTER JOIN tblAccountTaxCode ON tblAccountInvoiceLineItem.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
";
whereBuilder.Init();
whereBuilder.In("tblAccountInvoiceLineItem.ItemCode", lineItemCode, "WHERE");
sql += whereBuilder.SqlWhereString;
using (var conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (var cmd = new SqlCommand(sql, conn))
{
foreach (var param in whereBuilder.ParameterList)
{
cmd.Parameters.AddWithValue(param.Key, param.Value);
}
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return resultList;
}
while (reader.Read())
{
if (reader.IsDBNull(1)) { resultList.Add(reader.GetString(0), null); }
else { resultList.Add(reader.GetString(0), reader.GetString(1)); }
}
}
}
}
return resultList;
}
}
}
@@ -0,0 +1,82 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class AccountCodeRepository : _Base, IAccountCodeRepository
{
public AccountCodeRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public Dictionary<int, Model.Account.Account> ReadAccountCode(List<int> accountIdList = null, List<int> accountCodeList = null)
{
var resultDict = new Dictionary<int, Model.Account.Account>();
var sqlWhere = new SqlWhereBuilder();
//build sql query
string sqlString = @"
SELECT tblAccountChartOf.AccountChartOfID
,tblAccountChartOf.AccountCode
,tblAccountChartOf.AccountName
,tblAccountChartOf.Description
,tblAccountChartOfType.AccountChartOfType
,tblAccountChartOfType.BasicType
,tblAccountChartOfType.Multiplier
FROM tblAccountChartOf
INNER JOIN tblAccountChartOfType ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
WHERE 1=1 ";
if (accountIdList != null && accountIdList.Any())
{
sqlWhere.In("tblAccountChartOf.AccountChartOfID", accountIdList, " AND ");
}
if (accountCodeList != null && accountCodeList.Any())
{
sqlWhere.In("tblAccountChartOf.AccountCode", accountCodeList, " AND ");
}
if (sqlWhere.IsSetSqlWhereString)
{
sqlString = sqlString + sqlWhere.SqlWhereString;
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sqlString;
cmd.Transaction = _transaction as SqlTransaction;
if (sqlWhere.ParameterListIsSet)
{
sqlWhere.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int tablePk = reader.GetInt32(0);
int accountCode = reader.GetInt32(1);
string title = reader.GetString(2);
string description = null;
if (!reader.IsDBNull(3)) { description = reader.GetString(3); }
string type = reader.GetString(4);
string basicType = reader.GetString(5);
int multiplier = reader.GetInt32(6);
var result = new Model.Account.Account(tablePk, accountCode, title, description, type, basicType, multiplier);
resultDict.Add(tablePk, result);
}
}
}
return resultDict;
}
}
}
@@ -0,0 +1,201 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class AccountTaxRepository : _Base, IAccountTaxRepository
{
public AccountTaxRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public Dictionary<int, Model.Account.TaxCodeInfo> ReadTaxCodeInfo(bool? IsActive = null, List<string> taxcodeList = null, List<int> taxcodeIdList = null)
{
var resultList = new Dictionary<int, Model.Account.TaxCodeInfo>();
Data.Database.SqlWhereBuilder whereBuilder = new SqlWhereBuilder();
//build sql query
string sqlString = @"
SELECT
AccountTaxCodeID
,TaxCode
,TaxCodeName
,TaxCodeDescription
,TaxRatePercent
,IsMarginScheme
,IsValidOnExpense
,IsVailidOnIncome
,IsActive
,TaxType
FROM tblAccountTaxCode
WHERE 1=1 ";
// add where clauses
if (IsActive.HasValue)
{
whereBuilder.IsEqualTo("IsActive", IsActive.Value, "AND");
}
if (taxcodeList != null && taxcodeList.Count > 0)
{
whereBuilder.In("TaxCode", taxcodeList, "AND");
}
if (taxcodeIdList != null && taxcodeIdList.Count > 0)
{
whereBuilder.In("AccountTaxCodeID", taxcodeIdList, "AND");
}
if (whereBuilder.IsSetSqlWhereString)
{
sqlString = sqlString + whereBuilder.SqlWhereString;
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sqlString;
cmd.Transaction = _transaction as SqlTransaction;
if (whereBuilder.ParameterListIsSet)
{
whereBuilder.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int taxCodeId = reader.GetByte(0);
string taxCode = reader.GetString(1);
string name = reader.GetString(2);
string description = null;
if (!reader.IsDBNull(3)) { description = reader.GetString(3); }
decimal rate = reader.GetDecimal(4);
bool isMargin = reader.GetBoolean(5);
bool isValidOnExpense = reader.GetBoolean(6);
bool isValidOnIncome = reader.GetBoolean(7);
bool isActive = reader.GetBoolean(8);
string taxType = reader.GetString(9);
var result = new Model.Account.TaxCodeInfo(
taxCode,
name,
description,
rate,
isMargin,
isValidOnExpense,
isValidOnIncome,
taxType,
isActive);
resultList.Add(taxCodeId, result);
}
}
}
return resultList;
}
public Dictionary<string, string> GetTaxCodeBySkuNumber(List<string> skuNumberList)
{
var resultList = new Dictionary<string, string>();
if (skuNumberList == null || !skuNumberList.Any())
{
return resultList;
}
skuNumberList = skuNumberList.Distinct().ToList();
string sql = @"
SELECT tblSku.skuSkuNumber
,tblAccountTaxCode.TaxCode
FROM tblSku
INNER JOIN tblAccountTaxCode ON tblSku.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID ";
var whereBuilder = new Data.Database.SqlWhereBuilder();
whereBuilder.In("tblSku.skuSkuNumber", skuNumberList, "WHERE");
sql += whereBuilder.SqlWhereString;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (whereBuilder.ParameterListIsSet)
{
whereBuilder.AddParametersToSqlCommand(cmd);
}
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return resultList;
}
while (reader.Read())
{
resultList.Add(reader.GetString(0), reader.GetString(1));
}
}
}
return resultList;
}
public Dictionary<string, string> ReadTaxCodeByInvoiceLineItemCode(List<string> lineItemCode)
{
var resultList = new Dictionary<string, string>();
if (lineItemCode == null || !lineItemCode.Any())
{
return resultList;
}
lineItemCode = lineItemCode.Distinct().ToList();
string sql = @"
SELECT tblAccountInvoiceLineItem.ItemCode
,tblAccountTaxCode.TaxCode
FROM tblAccountInvoiceLineItem
LEFT OUTER JOIN tblAccountTaxCode ON tblAccountInvoiceLineItem.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
";
var whereBuilder = new Data.Database.SqlWhereBuilder();
whereBuilder.In("tblAccountInvoiceLineItem.ItemCode", lineItemCode, "WHERE");
sql += whereBuilder.SqlWhereString;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (whereBuilder.ParameterListIsSet)
{
whereBuilder.AddParametersToSqlCommand(cmd);
}
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return resultList;
}
while (reader.Read())
{
if (reader.IsDBNull(1)) { resultList.Add(reader.GetString(0), null); }
else { resultList.Add(reader.GetString(0), reader.GetString(1)); }
}
}
}
return resultList;
}
}
}
@@ -14,11 +14,11 @@ using System.Transactions;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class ImportAmazonRepository : _Base, IImportAmazonRepository
internal class AmazonSettlementRepository : _Base, IAmazonSettlementRepository
{
Logic.Log.LogEvent _log = new Logic.Log.LogEvent();
public ImportAmazonRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
public AmazonSettlementRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
@@ -368,13 +368,39 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
// Update Amazon Settlement Report
//
/// <summary>
/// Update the settlement report marketplace name by settlement Id (not table id)
/// </summary>
/// <param name="settlementId">Settlement id (not table/record id) of the settlement to update</param>
/// <param name="marketPlaceName">marketplace name</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public bool UpdateAmazonSettlementMarketPlaceName (string settlementId, Model.Amazon.MarketPlaceEnum marketPlace)
{
if (string.IsNullOrWhiteSpace(settlementId) || marketPlace == null)
{
throw new Exception("Settlement id or market place is invalid.");
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
UPDATE tblImportAmazonSettlementReport
SET [marketplace-name] = @marketPlaceName
WHERE [settlement-id] = @settlementId;";
cmd.Parameters.AddWithValue("@marketPlaceName", marketPlace.GetMarketplaceUrl());
cmd.Parameters.AddWithValue("@settlementId", settlementId);
cmd.Transaction = _transaction as SqlTransaction;
return cmd.ExecuteNonQuery() > 0;
}
}
/// <summary>
/// Set the IsProcessed flag to true or false for the specified settlement Ids.
/// </summary>
/// <param name="settlementIdList">List of settlement id (not table id)</param>
/// <param name="isProcessed">value to set the isProcessed to</param>
/// <returns>Number of rows effected</returns>
public int SetAmazonSettlementIsProcessed(List<string> settlementIdList, bool isProcessed)
public int UpdateAmazonSettlementIsProcessed(List<string> settlementIdList, bool isProcessed)
{
if (settlementIdList == null || !settlementIdList.Any())
{
@@ -1,4 +1,5 @@
using bnhtrade.Core.Data.Database.Repository.Interface;
using bnhtrade.Core.Logic.Account;
using bnhtrade.Core.Logic.Validate;
using Microsoft.Data.SqlClient;
using System;
@@ -164,7 +165,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
//
/// <summary>
/// Returns list of invoice numbers that have not yet been exported (i.e. IsComplete=True)
/// Returns list of invoice numbers that have not yet been exported (i.e. IsComplete=True), in InvoiceNumber asending order.
/// </summary>
/// <param name="invoiceType">Sales or Purchase</param>
/// <returns>Dictionary where key=ExportAccountInvoiceID, value=InvoiceNumber</returns>
@@ -176,7 +177,8 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
SELECT tblExportAccountInvoice.ExportAccountInvoiceID, [InvoiceNumber]
FROM tblExportAccountInvoice
WHERE (tblExportAccountInvoice.IsComplete = 0)
AND (tblExportAccountInvoice.ExportAccountInvoiceTypeID = @invoiceType);";
AND (tblExportAccountInvoice.ExportAccountInvoiceTypeID = @invoiceType)
ORDER BY [InvoiceNumber];";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
@@ -211,35 +213,35 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
}
// get the account and tax code objects
var taxcode = new Data.Database.Account.ReadTaxCode().GetAllActive();
var account = new Data.Database.Account.ReadAccountCode().All();
//var taxcode = new Data.Database.Account.ReadTaxCode().GetAllActive();
//var account = new Data.Database.Account.ReadAccountCode().All();
var taxcodeIds = new Dictionary<int, int>();
var accountIds = new Dictionary<int, int>();
var lineItemIds = new Dictionary<int, int>();
// build sql string
string sql = @"
SELECT tblExportAccountInvoice.ExportAccountInvoiceID
, tblExportAccountInvoice.ExportAccountInvoiceTypeID
, tblExportAccountInvoice.Contact
, tblExportAccountInvoice.InvoiceNumber
, tblExportAccountInvoice.InvoiceDate
, tblExportAccountInvoice.InvoiceDueDate
, tblExportAccountInvoice.Reference
, tblExportAccountInvoice.CurrencyCode
, tblExportAccountInvoice.InvoiceAmount
, tblExportAccountInvoice.IsComplete
, tblExportAccountInvoiceLine.ExportAccountInvoiceLineID
, tblAccountInvoiceLineItem.ItemName
, tblExportAccountInvoiceLine.AccountChartOfID
, tblExportAccountInvoiceLine.NetAmount
, tblExportAccountInvoiceLine.AccountTaxCodeID
, tblExportAccountInvoiceLine.TaxAmount
, tblExportAccountInvoice.LineUnitAmountIsTaxExclusive
FROM tblExportAccountInvoice
INNER JOIN
tblExportAccountInvoiceLine
ON tblExportAccountInvoice.ExportAccountInvoiceID = tblExportAccountInvoiceLine.ExportAccountInvoiceID
INNER JOIN
tblAccountInvoiceLineItem
ON tblExportAccountInvoiceLine.AccountInvoiceLineItemID = tblAccountInvoiceLineItem.AccountInvoiceLineItemID
SELECT tblExportAccountInvoice.ExportAccountInvoiceID,
tblExportAccountInvoice.ExportAccountInvoiceTypeID,
tblExportAccountInvoice.Contact,
tblExportAccountInvoice.InvoiceNumber,
tblExportAccountInvoice.InvoiceDate,
tblExportAccountInvoice.InvoiceDueDate,
tblExportAccountInvoice.Reference,
tblExportAccountInvoice.CurrencyCode,
tblExportAccountInvoice.InvoiceAmount,
tblExportAccountInvoice.IsComplete,
tblExportAccountInvoiceLine.ExportAccountInvoiceLineID,
tblExportAccountInvoiceLine.AccountInvoiceLineItemID,
tblExportAccountInvoiceLine.AccountChartOfID,
tblExportAccountInvoiceLine.NetAmount,
tblExportAccountInvoiceLine.AccountTaxCodeID,
tblExportAccountInvoiceLine.TaxAmount,
tblExportAccountInvoice.LineUnitAmountIsTaxExclusive
FROM tblExportAccountInvoice
INNER JOIN
tblExportAccountInvoiceLine
ON tblExportAccountInvoice.ExportAccountInvoiceID = tblExportAccountInvoiceLine.ExportAccountInvoiceID
";
var sqlWhere = new Data.Database.SqlWhereBuilder();
@@ -247,6 +249,7 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
sql = sql + sqlWhere.SqlWhereString + " ORDER BY tblExportAccountInvoice.ExportAccountInvoiceID, tblExportAccountInvoiceLine.ExportAccountInvoiceLineID; ";
int i = 0;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
@@ -265,8 +268,10 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
int? previousInvoiceId = null;
Model.Account.SalesInvoice invoice = null;
i = -1;
while (reader.Read())
{
i++;
invoiceId = reader.GetInt32(0);
// test for first/next invoice
@@ -301,11 +306,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
// add line info
var invoiceLine = new Model.Account.SalesInvoice.InvoiceLine(invoice);
int lineId = reader.GetInt32(10);
invoiceLine.ItemCode = reader.GetString(11);
invoiceLine.Account = account[Convert.ToUInt32(reader.GetInt32(12))];
lineItemIds.Add(i, reader.GetInt32(11));
accountIds.Add(i, reader.GetInt32(12));
invoiceLine.UnitAmount = reader.GetDecimal(13);
invoiceLine.Quantity = 1;
invoiceLine.TaxCode = taxcode[reader.GetByte(14)];
taxcodeIds.Add(i, reader.GetByte(14));
invoiceLine.SetTaxAdjustmentByTaxTotal(reader.GetDecimal(15));
invoice.InvoiceLineList.Add(invoiceLine);
@@ -316,6 +321,30 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
returnList.Add(invoiceId.Value, invoice);
}
}
// get and add account/tax/item objects to invoice
var dbTaxCodes = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, null, taxcodeIds.Values.ToList());
var dbAccountCodes = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountIds.Values.ToList());
var dbLineItems = new InvoiceRepository(_connection, _transaction).GetInvoiceLineItem(lineItemIds.Values.ToList());
i = -1;
foreach (var invoice in returnList.Values)
{
foreach (var line in invoice.InvoiceLineList)
{
i++;
line.TaxCode = dbTaxCodes[taxcodeIds[i]];
line.Account = dbAccountCodes[accountIds[i]];
// fill in missing data for line item, if required
var invoiceLineItem = dbLineItems[lineItemIds[i]];
line.ItemCode = invoiceLineItem.ItemCode;
if (string.IsNullOrEmpty(line.Description))
{
line.Description = invoiceLineItem.Name;
}
}
}
return returnList;
}
@@ -323,57 +352,36 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
// invoice update methods
//
/// <summary>
/// Update the 'IsComplete' field by invoice id
/// </summary>
/// <param name="updateDictionary">key=ExportAccountInvoiceTypeID, value=IsComplete</param>
/// <returns>Number of row effected</returns>
public int SetInvoiceIsCompleteValue(Dictionary<int, bool> updateDictionary)
public int UpdateInvoiceHeaderDetail(int invoiceId, string invoiceNumber = null, bool? isComplete = null)
{
int returnCount = 0;
foreach (var item in updateDictionary)
if (invoiceNumber == null && isComplete == null)
{
string sql = @"
UPDATE
tblExportAccountInvoice
SET
IsComplete = @isComplete
WHERE
ExportAccountInvoiceID = @id
";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@id", item.Key);
cmd.Parameters.AddWithValue("@isComplete", item.Value);
returnCount = returnCount + cmd.ExecuteNonQuery();
}
throw new ArgumentException("At least one of the parameters must be set to update invoice header details.");
}
// build the statement with my helper
var sqlupdate = new Core.Data.Database.SqlUpdateBuilder();
sqlupdate.SetTableName("tblExportAccountInvoice");
if (invoiceNumber != null)
sqlupdate.AddUpdateArugment("InvoiceNumber", invoiceNumber);
if (isComplete.HasValue)
sqlupdate.AddUpdateArugment("IsComplete", isComplete);
sqlupdate.AddWhereArugment("ExportAccountInvoiceID", invoiceId);
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = sqlupdate.GetSqlString();
sqlupdate.AddParametersToSqlCommand(cmd);
return cmd.ExecuteNonQuery();
}
return returnCount;
}
//
// Invoice Delete Methods
//
public int DeleteInvoiceLine(int invoiceLineId)
{
// only being able to delete one line at a time is a design/safety decision
// otherwise, delete whole invoice
if (invoiceLineId <= 0)
{
throw new ArgumentException("InvoiceLineId must be greater than zero.");
}
Core.Data.Database.SqlWhereBuilder sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
sqlWhereBuilder.In("ExportAccountInvoiceLineID", new List<int> { invoiceLineId });
return DeleteInvoiceExecuteInvoiceLine(sqlWhereBuilder);
}
public int DeleteInvoice(IEnumerable<int> invoiceIdList)
{
if (invoiceIdList == null || invoiceIdList.Count() == 0)
@@ -406,6 +414,19 @@ namespace bnhtrade.Core.Data.Database.Repository.Implementation
}
}
public int DeleteInvoiceLine(int invoiceLineId)
{
// only being able to delete one line at a time is a design/safety decision
// otherwise, delete whole invoice
if (invoiceLineId <= 0)
{
throw new ArgumentException("InvoiceLineId must be greater than zero.");
}
Core.Data.Database.SqlWhereBuilder sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
sqlWhereBuilder.In("ExportAccountInvoiceLineID", new List<int> { invoiceLineId });
return DeleteInvoiceExecuteInvoiceLine(sqlWhereBuilder);
}
/// <summary>
/// Helper method Only intended for use with ExecuteInvoice() or ExecuteInvoiceLine()
/// </summary>
@@ -0,0 +1,585 @@
using bnhtrade.Core.Data.Database.Repository.Interface;
using FikaAmazonAPI.AmazonSpApiSDK.Models.EasyShip20220323;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class InvoiceRepository : _Base, IInvoiceRepository
{
public InvoiceRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public int CreateDefaultInvoiceLineItem(string itemCode)
{
string sql = @"
INSERT INTO tblAccountInvoiceLineItem ( ItemName, ItemCode )
OUTPUT INSERTED.AccountInvoiceLineItemID
VALUES ( @itemName, @itemCode )
";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@itemName", itemCode);
cmd.Parameters.AddWithValue("@itemCode", itemCode);
object obj = cmd.ExecuteScalar();
if (obj == null || obj == DBNull.Value)
{
throw new Exception("Error inserting new defalt invoice line item into database");
}
return (int)obj;
}
}
/// <summary>
/// Retrieves a collection of invoice line items, optionally including account and tax information.
/// </summary>
/// <remarks>This method queries the database to retrieve invoice line items. If <paramref
/// name="includeAccountInfo"/> or <paramref name="includeTaxInfo"/> is set to <see langword="true"/>,
/// additional queries are performed to fetch the corresponding account and tax information, which may impact
/// performance.</remarks>
/// <param name="itemCodes">An optional collection of item codes to filter the results. If <see langword="null"/> or empty, all invoice
/// line items are retrieved.</param>
/// <param name="includeAccountInfo">A value indicating whether to include account information for each invoice line item. If <see
/// langword="true"/>, the default account code is populated for each item. Defaults to <see langword="true"/>.</param>
/// <param name="includeTaxInfo">A value indicating whether to include tax information for each invoice line item. If <see
/// langword="true"/>, the default tax code is populated for each item. Defaults to <see langword="true"/>.</param>
/// <returns>A dictionary where the key is the table record id of the invoice line item, and the value is the
/// corresponding <see cref="Model.Account.InvoiceLineItem"/> object. The dictionary will be empty if no
/// matching items are found.</returns>
public Dictionary<int, Model.Account.InvoiceLineItem> GetInvoiceLineItem(
IEnumerable<int> itemIds = null, IEnumerable<string> itemCodes = null, bool includeAccountInfo = true, bool includeTaxInfo = true
)
{
var sqlwhere = new SqlWhereBuilder();
var returnList = new Dictionary<int, Model.Account.InvoiceLineItem>();
var accountCodeIdList = new Dictionary<int, int>(); // key=LineItemID, value=AccountChartOfID
var taxCodeIdList = new Dictionary<int, int>(); // key=LineItemID, value=AccountTaxCodeID
string sql = @"
SELECT [AccountInvoiceLineItemID]
,[ItemName]
,[ItemCode]
,[ItemDescription]
,[IsNewReviewRequired]
,[InvoiceLineEntryEnable]
,[AccountChartOfID_Default]
,[AccountTaxCodeID_Default]
FROM [e2A].[dbo].[tblAccountInvoiceLineItem]
WHERE 1=1 ";
if (itemCodes != null && itemCodes.Any())
{
sqlwhere.In("ItemCode", itemCodes, "AND");
sql += sqlwhere.SqlWhereString;
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
sqlwhere.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var lineItem = new Model.Account.InvoiceLineItem();
int recordId = reader.GetInt32(0);
lineItem.Name = reader.GetString(1);
lineItem.ItemCode = reader.GetString(2);
if (!reader.IsDBNull(3)) { lineItem.Description = reader.GetString(3); }
lineItem.IsNewReviewRequired = reader.GetBoolean(4);
lineItem.InvoiceLineEntryEnabled = reader.GetBoolean(5);
if (!reader.IsDBNull(6))
{
accountCodeIdList.Add(recordId, reader.GetInt32(6));
}
if (!reader.IsDBNull(7))
{
taxCodeIdList.Add(recordId, reader.GetInt32(7));
}
returnList.Add(recordId, lineItem);
}
}
}
// get account codes and add to result list
if (includeAccountInfo)
{
var accountCodeDictionary = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountCodeIdList.Values.ToList());
foreach (var accountCode in accountCodeIdList)
{
returnList[accountCode.Key].DefaultAccountCode = accountCodeDictionary[accountCode.Value];
}
}
// get tax codes
if (includeTaxInfo)
{
var taxCodeDictionary = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, null, taxCodeIdList.Values.ToList());
foreach (var taxCode in taxCodeIdList)
{
returnList[taxCode.Key].DefaultTaxCode = taxCodeDictionary[taxCode.Value];
}
}
return returnList;
}
public Dictionary<int, Model.Account.PurchaseInvoice> ReadPurchaseInvoice(IEnumerable<int> purchaseInvoiceIdList)
{
var returnList = new Dictionary<int, Model.Account.PurchaseInvoice>();
SqlWhereBuilder sqlBuilder = new SqlWhereBuilder();
//build sql query
string sql = @"
SELECT tblPurchase.PurchaseID
,tblPurchase.PurchaseNumber
,tblPurchase.RecordID
,tblPurchase.PurchaseDate
,tblPurchase.ContactID
,tblPurchase.SupplierRef
,tblPurchase.PurchaseTotalAmount
,tblPurchase.VatInclusiveAmounts
,tblPurchase.RecordCreated
,tblPurchase.RecordModified
,tblPurchase.IsActive
,tblAccountCurrency.CurrencyCode
,tblPurchaseChannel.PurchaseChannelName
,tblPurchaseStatus.PurchaseStatus
FROM tblPurchase
LEFT OUTER JOIN tblAccountCurrency ON tblPurchase.AccountCurrencyID = tblAccountCurrency.AccountCurrencyID
LEFT OUTER JOIN tblPurchaseStatus ON tblPurchase.PurchaseStatusID = tblPurchaseStatus.PurchaseStatusID
LEFT OUTER JOIN tblPurchaseChannel ON tblPurchase.PurchaseChannelID = tblPurchaseChannel.PurchaseChannelID
WHERE 1 = 1
";
// build the where statments
if (purchaseInvoiceIdList.Any())
{
sqlBuilder.In("[PurchaseID]", purchaseInvoiceIdList, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// dictionary so we can fill in details afterwards
var invoiceContactDict = new Dictionary<int, int>();
var purchaseIdList = new List<int>();
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int purchaseID = reader.GetInt32(0);
int purchaseNumber = reader.GetInt32(1);
int? recordID = null;
if (!reader.IsDBNull(2)) { recordID = reader.GetInt32(2); }
DateTime purchaseDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
int? contactID = null;
if (!reader.IsDBNull(4)) { contactID = reader.GetInt32(4); }
string supplierRef = null;
if (!reader.IsDBNull(5)) { supplierRef = reader.GetString(5); }
decimal? purchaseTotalAmount = null;
if (!reader.IsDBNull(6)) { purchaseTotalAmount = reader.GetDecimal(6); }
bool vatInclusiveAmounts = reader.GetBoolean(7);
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc);
DateTime recordModified = DateTime.SpecifyKind(reader.GetDateTime(9), DateTimeKind.Utc);
bool isActive = reader.GetBoolean(10);
string currencyCode = reader.GetString(11);
string purchaseChannelName = reader.GetString(12);
string purchaseStatus = null;
if (!reader.IsDBNull(13)) { purchaseStatus = reader.GetString(13); }
var invoice = new Model.Account.PurchaseInvoice();
invoice.PurchaseID = purchaseID;
invoice.PurchaseNumber = purchaseNumber;
invoice.RecordID = recordID;
invoice.PurchaseDate = purchaseDate;
invoice.SupplierRef = supplierRef;
//invoice.PurchaseTotalAmount = purchaseTotalAmount;
invoice.VatInclusiveAmounts = vatInclusiveAmounts;
invoice.RecordCreated = recordCreated;
invoice.RecordModified = recordModified;
invoice.IsActive = isActive;
invoice.CurrencyCode = currencyCode;
invoice.PurchaseChannel = purchaseChannelName;
// is there contact info that needs to be added?
if (contactID != null)
{
invoiceContactDict.Add(purchaseID, (int)contactID);
}
purchaseIdList.Add(purchaseID);
returnList.Add(purchaseID, invoice);
}
}
}
}
// add contact info
if (invoiceContactDict.Any())
{
var readContact = new Data.Database.Account.ReadContact();
readContact.ContactIdList = invoiceContactDict.Values.ToList();
var contactDict = readContact.Read();
if (contactDict.Any())
{
foreach (var invoice in returnList)
{
if (invoiceContactDict.ContainsKey(invoice.Value.PurchaseID))
{
int contactId = invoiceContactDict[invoice.Value.PurchaseID];
invoice.Value.Contact = contactDict[contactId];
}
}
}
}
// add invoice lines
var lines = ReadPurchaseInvoiceLine(purchaseIdList);
foreach (var invoice in returnList.Values)
{
foreach (var line in lines.Values)
{
if (line.PurchaseId == invoice.PurchaseID)
{
if (invoice.InvoiceLines == null)
{
invoice.InvoiceLines = new List<Model.Account.PurchaseInvoice.Line>();
}
invoice.InvoiceLines.Add(line);
}
}
}
return returnList;
}
/// <summary>
/// Retrieves purchase invoice lines based on specified filters.
/// </summary>
/// <remarks>This method queries the database to retrieve purchase invoice line details that match
/// the provided filters. The filters include invoice IDs, invoice line IDs, statuses, and item descriptions.
/// The returned dictionary maps the purchase line ID to its corresponding <see
/// cref="Model.Account.PurchaseInvoice.Line"/> object.</remarks>
/// <param name="invoiceIdList">A list of purchase invoice IDs to filter the results. If empty, no filtering is applied.</param>
/// <param name="invoiceLineIdList">A list of purchase invoice line IDs to filter the results. If empty, no filtering is applied.</param>
/// <param name="statusList">A list of statuses to filter the results. If empty, no filtering is applied.</param>
/// <param name="itemDescription">Searches for the specificed phases within the item description. Uses the LIKE AND sql function. Partial matches are supported. If empty, no filtering is
/// applied.</param>
/// <returns>A dictionary where the key is the purchase line ID and the value is the corresponding
/// Model.Account.PurchaseInvoice.Line object containing detailed information about the purchase invoice line.</returns>
/// <exception cref="Exception">Thrown if a fail-safe condition is triggered, indicating an unexpected issue with tax code assignment.</exception>
public Dictionary<int, Model.Account.PurchaseInvoice.Line> ReadPurchaseInvoiceLine
(List<int> invoiceIdList = null, List<int> invoiceLineIdList = null, List<string> statusList = null, List<string> itemDescriptionList = null)
{
var returnList = new Dictionary<int, Model.Account.PurchaseInvoice.Line>();
var sqlBuilder = new SqlWhereBuilder();
//build sql query
string sql = @"
SELECT tblPurchaseLine.PurchaseLineID
,tblPurchaseLine.PurchaseID
,tblPurchaseLineStatus.PurchaseLineStatus
,tblPurchaseLine.SupplierRef
,tblPurchaseLine.CheckedIn
,tblPurchaseLine.ItemDescription
,tblPurchaseLine.ItemQuantity
,tblPurchaseLine.ItemGross
,tblPurchaseLine.ItemTax
,tblPurchaseLine.ShippingGross
,tblPurchaseLine.ShippingTax
,tblPurchaseLine.OtherGross
,tblPurchaseLine.OtherTax
,tblPurchaseLine.AccountTaxCodeID
,tblPurchaseLine.Tax_AccountTransactionID
,tblPurchaseLine.Net_AccountChartOfID
,tblPurchaseLine.Net_AccountTransactionID
,tblPurchaseLine.RecordCreated
,tblPurchaseLine.RecordModified
,tblPurchaseLine.IsActive
,tblAccountTaxCode.TaxCode
FROM tblPurchaseLine
INNER JOIN tblPurchaseLineStatus ON tblPurchaseLine.PurchaseLineStatusID = tblPurchaseLineStatus.PurchaseLineStatusID
LEFT OUTER JOIN tblAccountTaxCode ON tblPurchaseLine.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID
WHERE 1 = 1 ";
// build the where statments
if (invoiceIdList != null || invoiceIdList.Any())
{
sqlBuilder.In("PurchaseID", invoiceLineIdList, "AND");
}
if (invoiceLineIdList != null || invoiceLineIdList.Any())
{
sqlBuilder.In("PurchaseLineID", invoiceLineIdList, "AND");
}
if (statusList != null || statusList.Any())
{
sqlBuilder.In("PurchaseLineStatus", invoiceLineIdList, "AND");
}
if (itemDescriptionList != null || itemDescriptionList.Any())
{
sqlBuilder.LikeAnd("ItemDescription", itemDescriptionList, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// catch taxcode to add in after db read
var lineTaxCodeDict = new Dictionary<int, string>();
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int purchaseLineID = reader.GetInt32(0);
int purchaseID = reader.GetInt32(1);
string purchaseLineStatus = reader.GetString(2);
string supplierRef = null;
if (!reader.IsDBNull(3)) { supplierRef = reader.GetString(3); }
DateTime? checkedIn = null;
if (!reader.IsDBNull(4)) { checkedIn = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc); }
string itemDescription = null;
if (!reader.IsDBNull(5)) { itemDescription = reader.GetString(5); }
int itemQuantity = reader.GetInt32(6);
decimal itemGross = 0;
if (!reader.IsDBNull(7)) { itemGross = reader.GetDecimal(7); }
decimal itemTax = 0;
if (!reader.IsDBNull(8)) { itemTax = reader.GetDecimal(8); }
decimal shippingGross = 0;
if (!reader.IsDBNull(9)) { shippingGross = reader.GetDecimal(9); }
decimal shippingTax = 0;
if (!reader.IsDBNull(10)) { shippingTax = reader.GetDecimal(10); }
decimal otherGross = 0;
if (!reader.IsDBNull(11)) { otherGross = reader.GetDecimal(11); }
decimal otherTax = 0;
if (!reader.IsDBNull(12)) { otherTax = reader.GetDecimal(12); }
int accountTaxCodeID = reader.GetInt32(13);
int? tax_AccountTransactionID = null;
if (!reader.IsDBNull(14)) { tax_AccountTransactionID = reader.GetInt32(14); }
int net_AccountChartOfID = reader.GetInt32(15);
int? net_AccountTransactionID = null;
if (!reader.IsDBNull(16)) { net_AccountTransactionID = reader.GetInt32(16); }
DateTime recordModified;
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(17), DateTimeKind.Utc);
if (reader.IsDBNull(18)) { recordModified = recordCreated; }
else { recordModified = DateTime.SpecifyKind(reader.GetDateTime(18), DateTimeKind.Utc); }
bool isActive = reader.GetBoolean(19);
string accountTaxCode = reader.GetString(20);
var line = new Model.Account.PurchaseInvoice.Line();
line.PurchaseLineId = purchaseLineID;
line.PurchaseId = purchaseID;
line.Status = purchaseLineStatus;
line.SupplierRef = supplierRef;
line.CheckedIn = checkedIn;
line.ItemDescription = itemDescription;
line.ItemQuantity = itemQuantity;
line.ItemGross = itemGross;
line.ItemTax = itemTax;
line.ShippingGross = shippingGross;
line.ShippingTax = shippingTax;
line.OtherGross = otherGross;
line.OtherTax = otherTax;
line.Tax_AccountTransactionId = tax_AccountTransactionID;
line.Net_AccountChartOfId = net_AccountChartOfID;
line.Net_AccountTransactionId = net_AccountTransactionID;
line.RecordModified = recordModified;
line.RecordCreated = recordCreated;
line.IsActive = isActive;
returnList.Add(purchaseLineID, line);
lineTaxCodeDict.Add(purchaseLineID, accountTaxCode);
}
}
}
}
// read tax codes form db and add to return object
var taxcodeList = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, lineTaxCodeDict.Values.ToList()).Values.ToList();
foreach (var line in returnList.Values)
{
foreach (var taxcode in taxcodeList)
{
if (taxcode.TaxCode == lineTaxCodeDict[line.PurchaseLineId])
{
line.AccountTaxCode = taxcode;
break;
}
}
if (line.AccountTaxCode == null)
{
throw new Exception("Fail safe, this really shouodn't happen");
}
}
// all done
return returnList;
}
public Dictionary<int, Model.Account.PurchaseInvoiceLineStatus> ReadPurchaseInvoiceLineStatus()
{
var returnList = new Dictionary<int, Model.Account.PurchaseInvoiceLineStatus>();
string sql = @"
SELECT [PurchaseLineStatusID]
,[PurchaseLineStatus]
,[ListSort]
,[TimeStamp]
FROM [e2A].[dbo].[tblPurchaseLineStatus]
ORDER BY [ListSort]";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
// do something
}
else
{
while (reader.Read())
{
int id = reader.GetInt32(0);
string name = reader.GetString(1);
int lineSort = reader.GetInt32(2);
var returnItem = new Model.Account.PurchaseInvoiceLineStatus(id, name, lineSort);
returnList.Add(id, returnItem);
}
}
}
}
return returnList;
}
public List<Model.Account.PurchaseInvoiceLineSummary> ReadPurchaseInvoiceLineSummary(DateTime periodTo, string lineStatus, List<string> descriptionSearch)
{
var returnList = new List<Model.Account.PurchaseInvoiceLineSummary>();
var sqlBuilder = new bnhtrade.Core.Data.Database.SqlWhereBuilder();
//build sql query
string sql = @"
SELECT tblPurchase.PurchaseDate
,tblPurchase.PurchaseID
,tblPurchase.PurchaseNumber
,tblPurchaseLine.PurchaseLineID
,tblPurchaseLine.ItemDescription
,tblPurchaseLineStatus.PurchaseLineStatus
FROM tblPurchase
INNER JOIN tblPurchaseLine ON tblPurchase.PurchaseID = tblPurchaseLine.PurchaseID
INNER JOIN tblPurchaseLineStatus ON tblPurchaseLine.PurchaseLineStatusID = tblPurchaseLineStatus.PurchaseLineStatusID
WHERE tblPurchase.PurchaseDate <= @purchaseDate
";
if (lineStatus != null)
{
sql = sql + " AND PurchaseLineStatus = @purchaseLineStatus ";
}
// build the where statments
if (descriptionSearch.Any())
{
sqlBuilder.LikeAnd("ItemDescription", descriptionSearch, "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;
cmd.Parameters.AddWithValue("@purchaseDate", periodTo);
if (lineStatus != null)
{
cmd.Parameters.AddWithValue("@purchaseLineStatus", lineStatus);
}
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
DateTime purchaseDate = DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc);
int purchaseID = reader.GetInt32(1);
int purchaseNumber = reader.GetInt32(2);
int purchaseLineID = reader.GetInt32(3);
string itemDescription = reader.GetString(4);
string purchaseLineStatus = reader.GetString(5);
var item = new Model.Account.PurchaseInvoiceLineSummary();
item.PurchaseDate = purchaseDate;
item.PurchaseId = purchaseID;
item.PurchaseNumber = purchaseNumber;
item.PurchaseLineId = purchaseLineID;
item.ItemDescription = itemDescription;
item.LineStatus = purchaseLineStatus;
returnList.Add(item);
}
}
}
return returnList;
}
}
}
@@ -0,0 +1,372 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class JournalRepository : _Base, IJournalRepository
{
public JournalRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public Dictionary<int, Core.Model.Account.Journal> ReadJournal(List<int> journalIdList)
{
var sqlBuilder = new SqlWhereBuilder();
//build sql query
string sql = @"
SELECT tblAccountJournal.AccountJournalID
,tblAccountJournal.AccountJournalTypeID
,tblAccountJournal.EntryDate
,tblAccountJournal.PostDate
,tblAccountJournal.LastModified
,tblAccountJournal.IsLocked
,tblAccountJournalPost.AccountJournalPostID
,tblAccountJournalPost.AccountChartOfID
,tblAccountJournalPost.AmountGbp
FROM tblAccountJournal
INNER JOIN tblAccountJournalPost ON tblAccountJournal.AccountJournalID = tblAccountJournalPost.AccountJournalID
WHERE 1 = 1 ";
// build the where statments
if (journalIdList.Any())
{
sqlBuilder.In("tblAccountJournal.AccountJournalID", journalIdList, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// build tuple list
var dbJournalList = new List<(
int AccountJournalId
, int AccountJournalTypeId
, DateTime EntryDate
, DateTime PostDate
, DateTime LastModified
, bool IsLocked
)>();
var dbJournalPostList = new List<(
int AccountJournalId
, int AccountJournalPostId
, int AccountChartOfId
, decimal AmountGbp
)>();
bool hasRows = false;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (sqlBuilder.ParameterListIsSet)
{
sqlBuilder.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
hasRows = true;
int lastJournalId = 0;
while (reader.Read())
{
// read journal header
int journalId = reader.GetInt32(0);
if (journalId != lastJournalId)
{
lastJournalId = journalId;
(int AccountJournalId
, int AccountJournalTypeId
, DateTime EntryDate
, DateTime PostDate
, DateTime LastModified
, bool IsLocked
)
journal =
(journalId
, reader.GetInt32(1)
, DateTime.SpecifyKind(reader.GetDateTime(2), DateTimeKind.Utc)
, DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc)
, DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc)
, reader.GetBoolean(5)
);
dbJournalList.Add(journal);
}
// read journal posts
(int AccountJournalId
, int AccountJournalPostId
, int AccountChartOfId
, decimal AmountGbp
)
journalPost =
(journalId
, reader.GetInt32(6)
, reader.GetInt32(7)
, reader.GetDecimal(8)
);
dbJournalPostList.Add(journalPost);
}
}
}
}
var returnList = new Dictionary<int, Core.Model.Account.Journal>();
if (hasRows)
{
// build lists to filter db results by
var journalTypeIdList = new List<int>();
var accountIdList = new List<int>();
foreach (var item in dbJournalList)
{
journalTypeIdList.Add(item.AccountJournalTypeId);
}
foreach (var item in dbJournalPostList)
{
accountIdList.Add(item.AccountChartOfId);
}
// get journalTypes from db
var journalTypeDict = new JournalRepository(_connection, _transaction).ReadJournalType(journalTypeIdList);
// get accounts from db
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountIdList);
// build final return dictionary
foreach (var dbJournal in dbJournalList)
{
// build posts
var newPosts = new List<Core.Model.Account.Journal.Post>();
foreach (var dbJournalPost in dbJournalPostList)
{
if (dbJournalPost.AccountJournalId == dbJournal.AccountJournalId)
{
var newPost = new Core.Model.Account.Journal.Post(
dbJournalPost.AccountJournalPostId
, accountDict[dbJournalPost.AccountChartOfId]
, dbJournalPost.AmountGbp);
newPosts.Add(newPost);
}
}
// create the journal
var newJournal = new Core.Model.Account.Journal(
dbJournal.AccountJournalId
, journalTypeDict[dbJournal.AccountJournalTypeId]
, newPosts
, dbJournal.EntryDate
, dbJournal.PostDate
, dbJournal.LastModified
, dbJournal.IsLocked);
returnList.Add(dbJournal.AccountJournalId, newJournal);
}
}
// all done, return the list herevar
return returnList;
}
/// <summary>
/// Test for locked journal entry
/// </summary>
/// <returns>False on locked journal entry</returns>
public bool ReadJournalIsLocked(int journalId)
{
string sql = @"
SELECT
tblAccountJournal.IsLocked
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);
}
else
{
return (bool)obj;
}
}
}
public Dictionary<int, Model.Account.JournalType> ReadJournalType(List<int> journalTypeIds = null, List<string> typeTitles = null)
{
var sqlBuilder = new SqlWhereBuilder();
// create the return (emptyP list) here
var returnList = new Dictionary<int, Model.Account.JournalType>();
sqlBuilder.Init();
//build sql query
string sql = @"
SELECT [AccountJournalTypeID]
,[TypeTitle]
,[ChartOfAccountID_Debit]
,[ChartOfAccountID_Credit]
FROM [e2A].[dbo].[tblAccountJournalType]
WHERE 1 = 1 ";
// build the where statments
if (journalTypeIds.Any())
{
sqlBuilder.In("AccountJournalTypeID", journalTypeIds, "AND");
}
if (typeTitles.Any())
{
sqlBuilder.In("TypeTitle", typeTitles, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
// create dictionary to add credit/debit accounts on after db read
var creditDict = new Dictionary<int, int>();
var debitDict = new Dictionary<int, int>();
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (sqlBuilder.ParameterListIsSet)
{
sqlBuilder.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
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); }
// 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);
}
}
}
}
}
// 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;
}
/// <summary>
/// Old code needs sorting
/// </summary>
public bool DeleteJournal(int accountJournalId)
{
bool IsLocked = ReadJournalIsLocked(accountJournalId);
if (IsLocked == true)
{
return false;
}
// make the delete
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
DELETE FROM tblAccountJournalPost
WHERE AccountJournalID=@accountJournalId;";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
int rows = cmd.ExecuteNonQuery();
if (rows == 0)
{
throw new Exception("Journal entry and/or entry posts do not exist for AccountJournalId=" + accountJournalId);
}
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
DELETE FROM tblAccountJournal
WHERE AccountJournalID=@accountJournalId;";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
cmd.ExecuteNonQuery();
}
return true;
}
}
}
@@ -0,0 +1,117 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class SkuRepository : _Base, ISkuRepository
{
public SkuRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public int? ReadSkuId(int productId, int conditionId, int accountTaxCodeId)
{
int? returnId = null;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
SELECT
tblSku.skuSkuID
FROM
tblSku
WHERE
(((tblSku.skuProductID)=@productId) AND ((tblSku.skuSkuConditionID)=@conditionId) AND ((tblSku.AccountTaxCodeID)=@accountTaxCodeId));
";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@productId", productId);
cmd.Parameters.AddWithValue("@conditionId", conditionId);
cmd.Parameters.AddWithValue("@accountTaxCodeId", accountTaxCodeId);
object obj = cmd.ExecuteScalar();
if (obj != null || obj == DBNull.Value)
{
returnId = (int)obj;
}
}
return returnId;
}
public int InsertNewSku(int productId, int conditionId, int accountTaxCodeId)
{
// check tax code id is a valid for SKU
var taxCodeList = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, null, new List<int> { accountTaxCodeId });
if (taxCodeList.ContainsKey(accountTaxCodeId) == false)
{
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " doesn't exist!");
}
else if (taxCodeList[accountTaxCodeId].IsValidOnIncome == false)
{
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " is not a valid type for an SKU.");
}
// get info to create sku number
int skuCount;
int skuSuffix;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = "SELECT NEXT VALUE FOR SkuCountSequence;";
cmd.Transaction = _transaction as SqlTransaction;
skuCount = (int)cmd.ExecuteScalar();
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
SELECT tblSkuCondition.scnSkuNumberSuffix
FROM tblSkuCondition
WHERE (((tblSkuCondition.scnSkuConditionID)=@conditionId));";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@conditionId", conditionId);
try
{
skuSuffix = (int)cmd.ExecuteScalar();
}
catch (Exception ex)
{
throw new Exception("Error retriving SKU number suffix for SkuConditionID=" + conditionId + "." +
System.Environment.NewLine + "Error Message: " + ex.Message);
}
}
string skuNumber = skuCount.ToString("D6") + "-" + skuSuffix.ToString("D2");
// insert new sku
int skuId;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
INSERT INTO tblSku
(skuSkuNumber, skuProductID, skuSkuConditionID, AccountTaxCodeID)
OUTPUT INSERTED.skuSkuID
VALUES
(@skuNumber, @productId, @conditionId, @accountTaxCodeId)";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@skuNumber", skuNumber);
cmd.Parameters.AddWithValue("@productId", productId);
cmd.Parameters.AddWithValue("@conditionId", conditionId);
cmd.Parameters.AddWithValue("@accountTaxCodeId", accountTaxCodeId);
skuId = (int)cmd.ExecuteScalar();
}
return skuId;
}
}
}
@@ -0,0 +1,141 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class StockRepository : _Base, IStockRepository
{
public StockRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public List<Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null)
{
var sqlBuilder = new SqlWhereBuilder();
var returnList = new List<Model.Stock.Status>();
//build sql query
string sql = @"
SELECT [StockStatusID]
,[StatusCode]
,[StockStatus]
,[StockStatusTypeID]
,[Reference]
,[ForeignKeyID]
,[IsCreditOnly]
,[IsClosed]
,[RecordCreated]
FROM [e2A].[dbo].[tblStockStatus]
WHERE 1=1 ";
// build the where statments
if (statusIds.Any())
{
sqlBuilder.In("StockStatusID", statusIds, "AND");
}
if (statusTypeIds.Any())
{
sqlBuilder.In("StockStatusTypeID", statusTypeIds, "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())
{
var typeDict = new StockRepository(_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 newItem = new Model.Stock.Status(statusId
, statusCode
, stockStatus
, typeDict[typeId]
, reference
, foreignKeyId
, isCreditOnly
, isClosed
, recordCreated
);
returnList.Add(newItem);
}
}
}
return returnList;
}
public Dictionary<int, Model.Stock.StatusType> ReadStatusType()
{
var returnDict = new Dictionary<int, Model.Stock.StatusType>();
// get all account info before we start
var accountDict = new AccountCodeRepository(_connection, _transaction).ReadAccountCode();
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = @"
SELECT [StockStatusTypeID]
,[StatusTypeName]
,[ForeignKeyType]
,[ReferenceType]
,[AccountChartOfID]
FROM [e2A].[dbo].[tblStockStatusType]";
cmd.Transaction = _transaction as SqlTransaction;
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);
}
}
}
return returnDict;
}
}
}
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
abstract class _Base
public abstract class _Base
{
protected readonly IDbConnection _connection;
protected readonly IDbTransaction _transaction;
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IAccountCodeRepository
{
Dictionary<int, Model.Account.Account> ReadAccountCode(List<int> accountIdList = null, List<int> accountCodeList = null);
}
}
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IAccountTaxRepository
{
Dictionary<int, Model.Account.TaxCodeInfo> ReadTaxCodeInfo(bool? IsActive = null, List<string> taxcodeList = null, List<int> taxcodeIdList = null);
Dictionary<string, string> GetTaxCodeBySkuNumber(List<string> skuNumberList);
Dictionary<string, string> ReadTaxCodeByInvoiceLineItemCode(List<string> lineItemCode);
}
}
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IAmazonSettlementRepository
{
List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySettlementId(List<string> settlementIdList);
List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySpapiReportId(List<string> spapiReportIdList);
Dictionary<int, Model.Import.AmazonSettlement> ReadAmazonSettlements(
List<string> settlementIdList = null, List<string> marketPlaceNameList = null, bool? isProcessed = null,
bool descendingOrder = false, int? returnTop = null);
bool UpdateAmazonSettlementMarketPlaceName(string settlementId, Model.Amazon.MarketPlaceEnum marketPlace);
int UpdateAmazonSettlementIsProcessed(List<string> settlementIdList, bool isProcessed);
bool CreateAmazonSettlements(string filePath, string reportId);
int SetSpapiReportId(string settlementId, string spapiReportId);
}
}
@@ -8,11 +8,11 @@ namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IExportInvoiceRepository
{
internal Dictionary<int, Model.Account.SalesInvoice> InsertSalesInvoices(IEnumerable<Model.Account.SalesInvoice> invoiceList);
internal Dictionary<int, string> GetNewInvoiceNumbers(Model.Account.InvoiceType invoiceType);
internal Dictionary<int, Model.Account.SalesInvoice> GetSalesInvoiceById(IEnumerable<int> idList);
internal int SetInvoiceIsCompleteValue(Dictionary<int, bool> updateDictionary);
internal int DeleteInvoiceLine(int invoiceLineId);
internal int DeleteInvoice(IEnumerable<int> invoiceIdList);
Dictionary<int, Model.Account.SalesInvoice> InsertSalesInvoices(IEnumerable<Model.Account.SalesInvoice> invoiceList);
Dictionary<int, string> GetNewInvoiceNumbers(Model.Account.InvoiceType invoiceType);
Dictionary<int, Model.Account.SalesInvoice> GetSalesInvoiceById(IEnumerable<int> idList);
int UpdateInvoiceHeaderDetail(int invoiceId, string invoiceNumber = null, bool? isComplete = null);
int DeleteInvoiceLine(int invoiceLineId);
int DeleteInvoice(IEnumerable<int> invoiceIdList);
}
}
@@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IImportAmazonRepository
{
public List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySettlementId(List<string> settlementIdList);
public List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySpapiReportId(List<string> spapiReportIdList);
public Dictionary<int, Model.Import.AmazonSettlement> ReadAmazonSettlements(
List<string> settlementIdList = null, List<string> marketPlaceNameList = null, bool? isProcessed = null,
bool descendingOrder = false, int? returnTop = null);
public int SetAmazonSettlementIsProcessed(List<string> settlementIdList, bool isProcessed);
public bool CreateAmazonSettlements(string filePath, string reportId);
public int SetSpapiReportId(string settlementId, string spapiReportId);
}
}
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IInvoiceRepository
{
int CreateDefaultInvoiceLineItem(string itemCode);
Dictionary<int, Model.Account.InvoiceLineItem> GetInvoiceLineItem(
IEnumerable<int> itemIds = null, IEnumerable<string> itemCodes = null, bool includeAccountInfo = true, bool includeTaxInfo = true
);
Dictionary<int, Model.Account.PurchaseInvoice> ReadPurchaseInvoice(IEnumerable<int> purchaseInvoiceIdList);
Dictionary<int, Model.Account.PurchaseInvoice.Line> ReadPurchaseInvoiceLine
(List<int> invoiceIdList, List<int> invoiceLineIdList, List<string> statusList, List<string> itemDescriptionList);
Dictionary<int, Model.Account.PurchaseInvoiceLineStatus> ReadPurchaseInvoiceLineStatus();
List<Model.Account.PurchaseInvoiceLineSummary> ReadPurchaseInvoiceLineSummary(DateTime periodTo, string lineStatus, List<string> descriptionSearch);
}
}
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IJournalRepository
{
Dictionary<int, Core.Model.Account.Journal> ReadJournal(List<int> journalIdList);
bool ReadJournalIsLocked(int journalId);
Dictionary<int, Model.Account.JournalType> ReadJournalType(List<int> journalTypeIds = null, List<string> typeTitles = null);
bool DeleteJournal(int accountJournalId);
}
}
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface ISkuRepository
{
int? ReadSkuId(int productId, int conditionId, int accountTaxCodeId);
int InsertNewSku(int productId, int conditionId, int accountTaxCodeId);
}
}
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface IStockRepository
{
List<Model.Stock.Status> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null);
Dictionary<int, Model.Stock.StatusType> ReadStatusType();
}
}
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
namespace bnhtrade.Core.Data.Database.Sku
{
@@ -102,33 +102,7 @@ namespace bnhtrade.Core.Data.Database.Sku
/// <exception cref="Exception"></exception>
public int? ByParameters(int productId, int conditionId, int accountTaxCodeId)
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
int? returnId = null;
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT
tblSku.skuSkuID
FROM
tblSku
WHERE
(((tblSku.skuProductID)=@productId) AND ((tblSku.skuSkuConditionID)=@conditionId) AND ((tblSku.AccountTaxCodeID)=@accountTaxCodeId));
", conn))
{
cmd.Parameters.AddWithValue("@productId", productId);
cmd.Parameters.AddWithValue("@conditionId", conditionId);
cmd.Parameters.AddWithValue("@accountTaxCodeId", accountTaxCodeId);
object obj = cmd.ExecuteScalar();
if (obj != null || obj == DBNull.Value)
{
returnId = (int)obj;
}
}
return returnId;
}
throw new NotSupportedException("This method is not supported in GetSkuId. Use SkuRepository instead.");
}
}
}
@@ -1,85 +0,0 @@
using FikaAmazonAPI.AmazonSpApiSDK.Models.ProductPricing;
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Sku
{
internal class InsertSku : Connection
{
public int InsertNew(int productId, int conditionId, int accountTaxCodeId)
{
using (TransactionScope scope = new TransactionScope())
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
// check tax code id is a valid for SKU
var dbTax = new Data.Database.Account.ReadTaxCode();
var taxCodeList = dbTax.GetByTaxCodeId(new List<int> { accountTaxCodeId });
if (taxCodeList.ContainsKey(accountTaxCodeId) == false)
{
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " doesn't exist!");
}
else if (taxCodeList[accountTaxCodeId].IsValidOnIncome == false)
{
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " is not a valid type for an SKU.");
}
// get info to create sku number
int skuCount;
int skuSuffix;
using (SqlCommand cmd = new SqlCommand("SELECT NEXT VALUE FOR SkuCountSequence;", conn))
{
skuCount = (int)cmd.ExecuteScalar();
}
using (SqlCommand cmd = new SqlCommand(@"
SELECT tblSkuCondition.scnSkuNumberSuffix
FROM tblSkuCondition
WHERE (((tblSkuCondition.scnSkuConditionID)=@conditionId));
", conn))
{
cmd.Parameters.AddWithValue("@conditionId", conditionId);
try
{
skuSuffix = (int)cmd.ExecuteScalar();
}
catch (Exception ex)
{
throw new Exception("Error retriving SKU number suffix for SkuConditionID=" + conditionId + "." +
System.Environment.NewLine + "Error Message: " + ex.Message);
}
}
string skuNumber = skuCount.ToString("D6") + "-" + skuSuffix.ToString("D2");
// insert new sku
int skuId;
using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblSku
(skuSkuNumber, skuProductID, skuSkuConditionID, AccountTaxCodeID)
OUTPUT INSERTED.skuSkuID
VALUES
(@skuNumber, @productId, @conditionId, @accountTaxCodeId)
", conn))
{
cmd.Parameters.AddWithValue("@skuNumber", skuNumber);
cmd.Parameters.AddWithValue("@productId", productId);
cmd.Parameters.AddWithValue("@conditionId", conditionId);
cmd.Parameters.AddWithValue("@accountTaxCodeId", accountTaxCodeId);
skuId = (int)cmd.ExecuteScalar();
}
scope.Complete();
return skuId;
}
}
}
}
@@ -0,0 +1,132 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database
{
internal class SqlUpdateBuilder
{
private Dictionary<string, int> _usedUpdateFields = new Dictionary<string, int>();
private Dictionary<string, object> _parameterList = new Dictionary<string, object>();
private string _tableName = string.Empty;
private int _parameterCount = 0;
private string _sqlUpdate = string.Empty;
private string _sqlWhere = string.Empty;
private bool _updateIsSet = false;
private bool _whereIsSet = false;
public SqlUpdateBuilder() { }
public void Innit()
{
_usedUpdateFields.Clear();
_parameterList.Clear();
_tableName = string.Empty;
_parameterCount = 0;
_sqlUpdate = string.Empty;
_sqlWhere = string.Empty;
_updateIsSet = false;
_whereIsSet = false;
}
public void SetTableName(string tableName)
{
if (string.IsNullOrEmpty(tableName))
{
throw new ArgumentException("Table name cannot be null or empty.", nameof(tableName));
}
_tableName = tableName;
}
public void AddUpdateArugment(string columnName, object newValue)
{
if (string.IsNullOrEmpty(columnName) || newValue == null)
{
throw new ArgumentException("Column name and new value cannot be null or empty.");
}
if (_usedUpdateFields.ContainsKey(columnName))
{
throw new ArgumentException($"Column '{columnName}' already exists in the update arguments.", nameof(columnName));
}
// add the update arguments to sql string and parameter list
if (_updateIsSet)
{
_sqlUpdate += @",
";
}
else
{
_updateIsSet = true;
}
_parameterCount++;
_sqlUpdate += columnName + " = @parameter" + _parameterCount;
_parameterList.Add("@parameter" + _parameterCount, newValue);
}
public void AddWhereArugment(string columnName, object value)
{
if (string.IsNullOrEmpty(columnName) || value == null)
{
throw new ArgumentException("Column name and new value cannot be null or empty.");
}
// add the where arguments to sql string and parameter list
if (_whereIsSet)
{
_sqlWhere += @",
";
}
else
{
_whereIsSet = true;
}
_parameterCount++;
_sqlWhere += columnName + " = @parameter" + _parameterCount;
_parameterList.Add("@parameter" + _parameterCount, value);
}
public string GetSqlString()
{
if (_updateIsSet == false || _whereIsSet == false || string.IsNullOrEmpty(_tableName))
{
throw new InvalidOperationException("Table name, update arguments, and where arguments must be set before generating SQL string.");
}
string sql = @"
UPDATE "+ _tableName + @"
SET " + _sqlUpdate + @"
WHERE " + _sqlWhere + ";";
return sql;
}
public void AddParametersToSqlCommand(System.Data.SqlClient.SqlCommand cmd)
{
if (_parameterList != null)
{
foreach (var item in _parameterList)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
}
public void AddParametersToSqlCommand(Microsoft.Data.SqlClient.SqlCommand cmd)
{
if (_parameterList != null)
{
foreach (var item in _parameterList)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
}
}
}
@@ -63,6 +63,21 @@ namespace bnhtrade.Core.Data.Database
}
}
public bool ParameterListIsSet
{
get
{
if (ParameterList == null || ParameterList.Any() == false)
{
return false;
}
else
{
return true;
}
}
}
/// <summary>
/// Initialises the class
/// </summary>
@@ -154,7 +169,7 @@ namespace bnhtrade.Core.Data.Database
int listCount = distinctList.Count();
for (int i = 0; i < listCount; i++, parameterCount++)
for (int i = 0; i < listCount; i++)
{
if (i > 0)
{
@@ -170,15 +185,58 @@ namespace bnhtrade.Core.Data.Database
sqlWhere += " ( " + columnReference + " LIKE '%' + ";
string param = "@parameter" + parameterCount;
sqlWhere += param;
ParameterList.Add(param, distinctList[i]);
sqlWhere += " + '%' ) ";
sqlWhere = sqlWhere + GetSetParameter(distinctList[i]) + " + '%' ) ";
}
SqlWhereString = SqlWhereString + sqlWhere;
}
public void IsEqualTo(string columnReference, bool booleanValue, string wherePrefix = null)
{
string sqlWhereString = @"
";
if (wherePrefix != null)
{
sqlWhereString += wherePrefix;
}
sqlWhereString += " ( " + columnReference + " = ";
if (booleanValue)
{
sqlWhereString += "1 ) ";
}
else
{
sqlWhereString += "0 ) ";
}
SqlWhereString = SqlWhereString + sqlWhereString;
}
public void IsEqualTo(string columnReference, string stringValue, string wherePrefix = null)
{
if (string.IsNullOrEmpty(stringValue) || string.IsNullOrEmpty(columnReference))
{
throw new Exception(wherePrefix + " IsEqualTo method requires a valid column reference and string value.");
}
string sqlWhereString = @"
";
if (wherePrefix != null)
{
sqlWhereString += wherePrefix;
}
sqlWhereString += " ( " + columnReference + " = " + GetSetParameter(stringValue) + " ) ";
SqlWhereString = SqlWhereString + sqlWhereString;
}
/// <summary>
/// Append an 'In' statement and parameter list to the class properties
/// </summary>
@@ -205,16 +263,14 @@ namespace bnhtrade.Core.Data.Database
sqlWhere += " " + columnReference + " IN ( ";
int listCount = distinctList.Count();
for (int i = 0; i < listCount; i++, parameterCount++)
for (int i = 0; i < listCount; i++)
{
if (i > 0)
{
sqlWhere += ", ";
}
string param = "@parameter" + parameterCount;
sqlWhere += param;
ParameterList.Add(param, distinctList[i]);
sqlWhere = sqlWhere + GetSetParameter(distinctList[i].ToString());
}
sqlWhere += " ) ";
@@ -298,5 +354,19 @@ namespace bnhtrade.Core.Data.Database
In(columnReference, objectList, wherePrefix);
}
/// <summary>
/// Adds a string value to the ParameterList and returns '@parameterN' that is then appended to the SQL statement
/// i.e. @parameter1, @parameter2, etc.
/// </summary>
/// <param name="value">parameter string that is then appended to the SQL statement</param>
/// <returns></returns>
private string GetSetParameter(string value)
{
parameterCount++;
string parameterString = "@parameter" + parameterCount;
ParameterList.Add(parameterString, value);
return parameterString;
}
}
}
@@ -1,115 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static bnhtrade.Core.Data.Database.Constants;
namespace bnhtrade.Core.Data.Database.Stock
{
internal class Status : Connection
{
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
public List<int> StatusIds { get; set; }
public List<int> StatusTypeIds { get; set; }
public Status ()
{
Init();
}
public void Init()
{
sqlBuilder = new SqlWhereBuilder();
StatusIds = new List<int>();
StatusTypeIds = new List<int>();
}
public List<Model.Stock.Status> Read()
{
var returnList = new List<Model.Stock.Status>();
sqlBuilder.Init();
//build sql query
string sql = @"
SELECT [StockStatusID]
,[StatusCode]
,[StockStatus]
,[StockStatusTypeID]
,[Reference]
,[ForeignKeyID]
,[IsCreditOnly]
,[IsClosed]
,[RecordCreated]
FROM [e2A].[dbo].[tblStockStatus]
WHERE 1=1 ";
// build the where statments
if (StatusIds.Any())
{
sqlBuilder.In("StockStatusID", StatusIds, "AND");
}
if (StatusTypeIds.Any())
{
sqlBuilder.In("StockStatusTypeID", StatusTypeIds, "AND");
}
// append where string to the sql
if (sqlBuilder.IsSetSqlWhereString)
{
sql = sql + sqlBuilder.SqlWhereString;
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
sqlBuilder.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
var typeDict = new Data.Database.Stock.StatusType().Read();
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 newItem = new Model.Stock.Status(statusId
, statusCode
, stockStatus
, typeDict[typeId]
, reference
, foreignKeyId
, isCreditOnly
, isClosed
, recordCreated
);
returnList.Add(newItem);
}
}
}
}
}
return returnList;
}
}
}
@@ -1,63 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Stock
{
public class StatusType : Connection
{
public StatusType()
{
}
/// <summary>
/// Reads all Status Types from database
/// </summary>
/// <returns></returns>
public Dictionary<int, Model.Stock.StatusType> Read()
{
var returnDict = new Dictionary<int, Model.Stock.StatusType>();
// get all account info before we start
var accountDict = new Data.Database.Account.ReadAccountCode().All();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT [StockStatusTypeID]
,[StatusTypeName]
,[ForeignKeyType]
,[ReferenceType]
,[AccountChartOfID]
FROM [e2A].[dbo].[tblStockStatusType]
", conn))
{
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[accountId]);
returnDict.Add(statusTypeId, statusType);
}
}
}
}
return returnDict;
}
}
}
@@ -8,7 +8,7 @@ using System.Configuration;
namespace bnhtrade.Core.Data.Database.UnitOfWork
{
internal class Connection
public class Connection
{
//protected readonly string SqlConnectionString;
private Model.Credentials.bnhtradeDB _dbCredentials;
@@ -10,10 +10,16 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
internal interface IUnitOfWork : IDisposable
{
// Properties for repositories, add here for each repository
public ICurrencyRepository CurrencyRepository { get; }
IAccountCodeRepository AccountCodeRepository { get; }
IAccountTaxRepository AccountTaxRepository { get; }
ICurrencyRepository CurrencyRepository { get; }
IExportInvoiceRepository ExportInvoiceRepository { get; }
IImportAmazonRepository ImportAmazonRepository { get; }
IAmazonSettlementRepository AmazonSettlementRepository { get; }
IInvoiceRepository InvoiceRepository { get; }
IJournalRepository JournalRepository { get; }
ISequenceGenerator SequenceGenerator { get; }
ISkuRepository SkuRepository { get; }
IStockRepository StockRepository { get; }
// Methods to manage the transaction
void Commit();
@@ -18,18 +18,60 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
private bool _disposed;
// Private field for lazy loading, add here for each repository
private IAccountCodeRepository _accountCodeRepository;
private IAccountTaxRepository _accountTaxRepository;
private IAmazonSettlementRepository _amazonSettlementRepository;
private ICurrencyRepository _currencyRepository;
private IExportInvoiceRepository _exportInvoiceRepository;
private IImportAmazonRepository _importAmazonRepository;
private IInvoiceRepository _invoiceRepository;
private IJournalRepository _journalRepository;
private ISequenceGenerator _sequenceGenerator;
private ISkuRepository _skuRepository;
private IStockRepository _stockRepository;
public UnitOfWork()
internal UnitOfWork()
{
_connection = new SqlConnection(this.SqlConnectionString);
_connection.Open();
_transaction = _connection.BeginTransaction();
}
public IAccountCodeRepository AccountCodeRepository
{
get
{
if (_accountCodeRepository == null)
{
_accountCodeRepository = new AccountCodeRepository(_connection, _transaction);
}
return _accountCodeRepository;
}
}
public IAccountTaxRepository AccountTaxRepository
{
get
{
if (_accountTaxRepository == null)
{
_accountTaxRepository = new AccountTaxRepository(_connection, _transaction);
}
return _accountTaxRepository;
}
}
public IAmazonSettlementRepository AmazonSettlementRepository
{
get
{
if (_amazonSettlementRepository == null)
{
_amazonSettlementRepository = new AmazonSettlementRepository(_connection, _transaction);
}
return _amazonSettlementRepository;
}
}
// Properties for repositories, add here for each repository
public ICurrencyRepository CurrencyRepository
{
@@ -55,15 +97,26 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
}
}
public IImportAmazonRepository ImportAmazonRepository
public IInvoiceRepository InvoiceRepository {
get
{
if (_invoiceRepository == null)
{
_invoiceRepository = new InvoiceRepository(_connection, _transaction);
}
return _invoiceRepository;
}
}
public IJournalRepository JournalRepository
{
get
{
if (_importAmazonRepository == null)
if (_journalRepository == null)
{
_importAmazonRepository = new ImportAmazonRepository(_connection, _transaction);
_journalRepository = new JournalRepository(_connection, _transaction);
}
return _importAmazonRepository;
return _journalRepository;
}
}
@@ -79,6 +132,30 @@ namespace bnhtrade.Core.Data.Database.UnitOfWork
}
}
public ISkuRepository SkuRepository
{
get
{
if (_skuRepository == null)
{
_skuRepository = new SkuRepository(_connection, _transaction);
}
return _skuRepository;
}
}
public IStockRepository StockRepository
{
get
{
if (_stockRepository == null)
{
_stockRepository = new StockRepository(_connection, _transaction);
}
return _stockRepository;
}
}
public void Commit()
{
try
+2 -6
View File
@@ -94,10 +94,8 @@ namespace bnhtrade.Core.Data.Xero
public string BrandingTheme { get; set; }
}
internal void ExportToCsv(List<Core.Model.Account.SalesInvoice> salesInvoiceList, int startingInvoiceNumber, string savePath, bool unitAmountIsTaxExclusive = true)
internal void ExportToCsv(List<Core.Model.Account.SalesInvoice> salesInvoiceList, string savePath, bool unitAmountIsTaxExclusive = true)
{
int invoiceNumberCount = startingInvoiceNumber;
// convert invoice to unitAmountIsTaxExclusive = true
foreach (var invoice in salesInvoiceList)
{
@@ -123,7 +121,7 @@ namespace bnhtrade.Core.Data.Xero
}
string contactName = invoice.ContactName;
string invoiceNumber = "INV-" + invoiceNumberCount.ToString("000000");
string invoiceNumber = invoice.InvoiceNumber;
string reference = invoice.InvoiceReference;
string invoiceDate = invoice.InvoiceDate.GetValueOrDefault().ToString("dd MMM yyyy", CultureInfo.InvariantCulture);
string dueDate = invoice.InvoiceDueDate.GetValueOrDefault().ToString("dd MMM yyyy", CultureInfo.InvariantCulture);
@@ -153,8 +151,6 @@ namespace bnhtrade.Core.Data.Xero
csvLineList.Add(csvLine);
}
invoiceNumberCount++;
}
var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.CurrentCulture);