Added invoice export function and started implementation of unitofwork pattern (#43)

* complete read invoices from db

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* updated nuget package spapi

* WIP

* wip, now test

* wip, jut need to fix tax inclusive line amounts not supported

* wip

* wip, before I f everything up

* no, it complies now, this is the one before I f everything up

* wip

* wip

* wip, logic ready for testing

* wip it builds!!!!

* wip tested, working, need to complete the gui section

* wip

* wip

* wip - created export invoice data delete, time for testing

* wip testing phase

* wip - delete function fully tested and working

* wip on to sorting out the issue with settlement invoices not tallying

* wip

* wip

* wip

* wip

* wip before I complete change the ReadInvoiceLineItem sections

* that appears to have worked, on with the main quest

* no it's doesn't work, saving before i remove the confusing cache system (just use a dictionary!!)

* wipping picadilli

* wip

* wip

* implemented uow on inovice export, now for testing

* wip

* wip all tested do invoice currency convertion fearure

* wip

* pretty much done so long as xero accepts the exported invoices

* Complete!
This commit is contained in:
Bobbie Hodgetts
2025-06-26 23:29:22 +01:00
committed by GitHub
parent 8bbf885a48
commit 29f9fae508
82 changed files with 4606 additions and 2837 deletions

View File

@@ -162,7 +162,7 @@ namespace bnhtrade.Core.Data.Database.Account
// currency conversion
if (currencyCode != "GBP")
{
amount = new Logic.Account.Currency().CurrencyConvertToGbp(currencyCode, amount, entryDate);
amount = new Logic.Account.CurrencyService().CurrencyConvertToGbp(currencyCode, amount, entryDate);
}
// ensure decimal is rounded

View File

@@ -1,262 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentOutbound;
using System.Data;
namespace bnhtrade.Core.Data.Database.Account
{
internal class Currency : Connection
{
/// <summary>
/// Returns excahnge rate, in decimal format, for a given currency and datetime
/// </summary>
/// <param name="currencyCode">currency code</param>
/// <param name="date">dat and time</param>
/// <returns></returns>
public decimal? ReadExchangeRate(string currencyCode, DateTime date)
{
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT CurrencyUnitsPerGBP
FROM tblAccountExchangeRate
WHERE CurrencyCode=@currencyCode AND StartDate<=@conversionDate AND EndDate>@conversionDate
", sqlConn))
{
cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
cmd.Parameters.AddWithValue("@conversionDate", date);
object result = cmd.ExecuteScalar();
if (result != null)
{
return Convert.ToDecimal(result);
}
else
{
return null;
}
}
}
}
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRate(List<Model.Account.CurrencyCode> currencyCodeList = null, DateTime date = default(DateTime))
{
throw new NotImplementedException("Complete, but untested");
var returnList = new List<Model.Account.CurrencyExchangeRate>();
string sql = @"
SELECT AccountEchangeRateID, ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate
FROM tblAccountExchangeRate
WHERE 1=1 ";
if (date != default(DateTime))
{
sql = sql + " AND (@dateTime >= StartDate AND @dateTime < endDate) ";
}
var sqlWhere = new Data.Database.SqlWhereBuilder();
// create string list
List<string> stringList = new List<string>();
if (currencyCodeList != null)
{
stringList = currencyCodeList.ConvertAll(f => f.ToString());
if (stringList.Any())
{
sqlWhere.In("CurrencyCode", stringList, "AND");
}
}
sql = sql + sqlWhere.SqlWhereString;
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand(sql))
{
if (date != default(DateTime))
{
cmd.Parameters.AddWithValue("@dateTime", date);
}
if (stringList.Any())
{
sqlWhere.AddParametersToSqlCommand(cmd);
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(0);
int exchangeRateSource = reader.GetInt32(1);
string currencyCodeString = reader.GetString(2);
decimal currencyUnitsPerGBP = reader.GetDecimal(3);
DateTime startDate = DateTime.SpecifyKind( reader.GetDateTime(4), DateTimeKind.Utc);
DateTime endDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
// convert string to enum
if (Enum.TryParse(currencyCodeString, out Model.Account.CurrencyCode currencyCode) == false)
{
throw new Exception("Failed converting database string to enum");
}
var item = new Model.Account.CurrencyExchangeRate(
currencyCode
, exchangeRateSource
, startDate
, endDate
);
returnList.Add(item);
}
}
}
}
return returnList;
}
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRateLatest(List<Model.Account.CurrencyCode> currencyCodeList = null)
{
var returnList = new List<Model.Account.CurrencyExchangeRate>();
string sql = @"
SELECT t1.AccountExchangeRateID, t1.ExchangeRateSource, t1.CurrencyCode, t1.CurrencyUnitsPerGBP, t1.StartDate, t1.EndDate,
t2.maxdate
FROM tblAccountExchangeRate AS t1
INNER JOIN
(SELECT max(StartDate) AS maxdate,
CurrencyCode
FROM tblAccountExchangeRate
GROUP BY CurrencyCode
";
// add any filters
var sqlWhere = new Data.Database.SqlWhereBuilder();
var codeStringList = new List<string>();
if (currencyCodeList != null && currencyCodeList.Any() == true)
{
// convert to string list
foreach ( var currencyCode in currencyCodeList)
{
codeStringList.Add(currencyCode.ToString());
}
// add to where statement
sqlWhere.In("CurrencyCode", codeStringList, "HAVING");
sql = sql + sqlWhere.SqlWhereString;
}
sql = sql + @" ) AS t2
ON t1.CurrencyCode = t2.CurrencyCode
AND t1.StartDate = t2.maxdate
ORDER BY t1.CurrencyCode;";
//query db
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand(sql, sqlConn))
{
if (codeStringList.Any())
{
sqlWhere.AddParametersToSqlCommand(cmd);
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(0);
int exchangeRateSource = reader.GetInt32(1);
string currencyCodeString = reader.GetString(2);
decimal currencyUnitsPerGBP = reader.GetDecimal(3);
DateTime startDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
DateTime endDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
// convert string to enum
if (Enum.TryParse(currencyCodeString, out Model.Account.CurrencyCode currencyCode) == false)
{
throw new Exception("Failed converting database string to enum");
}
var item = new Model.Account.CurrencyExchangeRate(
currencyCode
, exchangeRateSource
, startDate
, endDate
);
returnList.Add(item);
}
}
}
}
return returnList;
}
public int InsertExchangeRate(int exchangeRateSource, Model.Account.CurrencyCode currencyCode,
decimal currencyUnitsPerGbp, DateTime periodStartUtc, DateTime periodEnd, bool checkOverride = false)
{
// checks
if (periodStartUtc.Kind != DateTimeKind.Utc || periodEnd.Kind != DateTimeKind.Utc)
{
throw new FormatException("Currency date time kind must be UTC");
}
currencyUnitsPerGbp = decimal.Round(currencyUnitsPerGbp, 4);
// CHECKS
if (periodEnd <= periodStartUtc)
{
throw new Exception("Invalid date period.");
}
if (checkOverride == false && (periodEnd - periodStartUtc).Days > 31)
{
throw new Exception("Date period is greater than 31 days.");
}
// make the insert
DateTime? periodEndLast = null;
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
int recordId = 0;
using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblAccountExchangeRate (ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate)
OUTPUT INSERTED.AccountExchangeRateID
VALUES (@exchangeRateSource, @currencyCode, @currencyUnitsPerGbp, @periodStart, @periodEnd);
", sqlConn))
{
cmd.Parameters.AddWithValue("@exchangeRateSource", exchangeRateSource);
cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
cmd.Parameters.AddWithValue("@currencyUnitsPerGbp", currencyUnitsPerGbp);
cmd.Parameters.AddWithValue("@periodStart", periodStartUtc);
cmd.Parameters.AddWithValue("@periodEnd", periodEnd);
recordId = (int)cmd.ExecuteScalar();
if (recordId < 1)
{
throw new Exception("Error inserting record, did not retrive new record ID.");
}
}
return recordId;
}
}
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -8,63 +8,61 @@ using System.Transactions;
namespace bnhtrade.Core.Data.Database.Account
{
public class ReadInvoiceLineItem : Connection
internal class ReadInvoiceLineItem : Connection
{
public ReadInvoiceLineItem()
{
Innit();
}
public Dictionary<string, int> AccountCodeList { get; private set; }
public Dictionary<string, string> TaxCodeList { get; private set; }
private void Innit()
/// <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()
{
AccountCodeList = new Dictionary<string, int>();
TaxCodeList = new Dictionary<string, string>();
return Execute();
}
public Model.Account.InvoiceLineItem ByItemCode(string itemCode)
/// <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 (string.IsNullOrWhiteSpace(itemCode)) { return null; }
var result = ByItemCode(new List<string>{ itemCode });
if (!result.Any())
{
return null;
}
else
{
return result[itemCode];
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);
}
public Dictionary<string, Model.Account.InvoiceLineItem> ByItemCode(List<string> itemCodeList)
private Dictionary<int, Model.Account.InvoiceLineItem> Execute(SqlWhereBuilder sqlwhere = null)
{
Innit();
var resultList = new Dictionary<string, Model.Account.InvoiceLineItem>();
if (itemCodeList == null || !itemCodeList.Any())
{ return resultList; }
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 tblAccountInvoiceLineItem.ItemCode
,tblAccountInvoiceLineItem.ItemName
,tblAccountInvoiceLineItem.ItemDescription
,tblAccountInvoiceLineItem.IsNewReviewRequired
,tblAccountInvoiceLineItem.InvoiceLineEntryEnable
,tblAccountChartOf.AccountCode
,tblAccountTaxCode.TaxCode
FROM tblAccountInvoiceLineItem
LEFT OUTER JOIN tblAccountTaxCode ON tblAccountInvoiceLineItem.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
LEFT OUTER JOIN tblAccountChartOf ON tblAccountInvoiceLineItem.AccountChartOfID_Default = tblAccountChartOf.AccountChartOfID
WHERE ";
SELECT [AccountInvoiceLineItemID]
,[ItemName]
,[ItemCode]
,[ItemDescription]
,[IsNewReviewRequired]
,[InvoiceLineEntryEnable]
,[AccountChartOfID_Default]
,[AccountTaxCodeID_Default]
FROM [e2A].[dbo].[tblAccountInvoiceLineItem]
WHERE 1=1 ";
var whereBuilder = new SqlWhereBuilder();
whereBuilder.In("tblAccountInvoiceLineItem.ItemCode", itemCodeList);
sql += whereBuilder.SqlWhereString;
if (sqlwhere != null)
{
sql += sqlwhere.SqlWhereString;
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
@@ -72,41 +70,53 @@ namespace bnhtrade.Core.Data.Database.Account
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
foreach (var param in whereBuilder.ParameterList)
if (sqlwhere != null)
{
cmd.Parameters.AddWithValue(param.Key, param.Value);
sqlwhere.AddParametersToSqlCommand(cmd);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
while (reader.Read())
{
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))
{
var result = new Model.Account.InvoiceLineItem();
result.ItemCode = reader.GetString(0);
result.Name = reader.GetString(1);
if (!reader.IsDBNull(2)) { result.Description = reader.GetString(2); }
result.IsNewReviewRequired = reader.GetBoolean(3);
result.InvoiceLineEntryEnabled = reader.GetBoolean(4);
if (!reader.IsDBNull(5))
{
AccountCodeList.Add(result.ItemCode, reader.GetInt32(5));
}
if (!reader.IsDBNull(6))
{
TaxCodeList.Add(result.ItemCode, reader.GetString(6));
}
resultList.Add(result.ItemCode, result);
accountCodeIdList.Add(lineItemId, (uint)reader.GetInt32(6));
}
if (!reader.IsDBNull(7))
{
taxCodeIdList.Add(lineItemId, reader.GetInt32(7));
}
}
return resultList;
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;
}
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -8,11 +8,11 @@ using static System.ComponentModel.Design.ObjectSelectorEditor;
namespace bnhtrade.Core.Data.Database.Account
{
public class ReadPurchaseInvoice : Connection
internal class ReadPurchaseInvoice : Connection
{
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
public List<int> PurchaseInvoiceIdList { get; set; }
public IEnumerable<int> PurchaseInvoiceIdList { get; set; }
public ReadPurchaseInvoice()
{

View File

@@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Account
{
public class ReadTaxCode : Connection
internal class ReadTaxCode : Connection
{
private Data.Database.SqlWhereBuilder whereBuilder = new SqlWhereBuilder();
@@ -15,14 +15,15 @@ namespace bnhtrade.Core.Data.Database.Account
{
}
private List<Model.Account.TaxCodeInfo> Execute(string sqlWhere, Dictionary<string, object> parameters)
private Dictionary<int, Model.Account.TaxCodeInfo> Execute(string sqlWhere, Dictionary<string, object> parameters)
{
var resultList = new List<Model.Account.TaxCodeInfo>();
var resultList = new Dictionary<int, Model.Account.TaxCodeInfo>();
//build sql query
string sqlString = @"
SELECT
TaxCode
AccountTaxCodeID
,TaxCode
,TaxCodeName
,TaxCodeDescription
,TaxRatePercent
@@ -52,19 +53,20 @@ namespace bnhtrade.Core.Data.Database.Account
{
while (reader.Read())
{
string taxCodeId = reader.GetString(0);
string name = reader.GetString(1);
int taxCodeId = reader.GetByte(0);
string taxCode = reader.GetString(1);
string name = reader.GetString(2);
string description = null;
if (!reader.IsDBNull(2)) { description = reader.GetString(2); }
decimal rate = reader.GetDecimal(3);
bool isMargin = reader.GetBoolean(4);
bool isValidOnExpense = reader.GetBoolean(5);
bool isValidOnIncome = reader.GetBoolean(6);
bool isActive = reader.GetBoolean(7);
string taxType = reader.GetString(8);
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(
taxCodeId,
taxCode,
name,
description,
rate,
@@ -74,7 +76,7 @@ namespace bnhtrade.Core.Data.Database.Account
taxType,
isActive);
resultList.Add(result);
resultList.Add(taxCodeId, result);
}
}
}
@@ -97,12 +99,13 @@ namespace bnhtrade.Core.Data.Database.Account
whereBuilder.Init();
whereBuilder.In("TaxCode", taxcodeList, "WHERE");
return Execute(whereBuilder.SqlWhereString, whereBuilder.ParameterList);
var dic = Execute(whereBuilder.SqlWhereString, whereBuilder.ParameterList);
return dic.Values.ToList();
}
public List<Model.Account.TaxCodeInfo> GetByTaxCodeId(List<int> taxcodeIdList)
public Dictionary<int, Model.Account.TaxCodeInfo> GetByTaxCodeId(List<int> taxcodeIdList)
{
var resultList = new List<Model.Account.TaxCodeInfo>();
var resultList = new Dictionary<int, Model.Account.TaxCodeInfo>();
if (taxcodeIdList == null || !taxcodeIdList.Any())
{
@@ -117,7 +120,12 @@ namespace bnhtrade.Core.Data.Database.Account
return Execute(whereBuilder.SqlWhereString, whereBuilder.ParameterList);
}
public List<Model.Account.TaxCodeInfo> GetAllActive()
/// <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;";

View File

@@ -11,11 +11,11 @@ namespace bnhtrade.Core.Data.Database
public class Connection
{
//protected readonly string SqlConnectionString;
private Model.Credentials.bnhtradeDB dbCredentials;
private Model.Credentials.bnhtradeDB _dbCredentials;
protected string SqlConnectionString
{
get { return dbCredentials.ConnectionString; }
get { return _dbCredentials.ConnectionString; }
}
public Connection()
@@ -44,7 +44,7 @@ namespace bnhtrade.Core.Data.Database
}
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
this.dbCredentials = dbCredentials;
this._dbCredentials = dbCredentials;
}
catch (Exception ex)
{
@@ -76,7 +76,7 @@ namespace bnhtrade.Core.Data.Database
}
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
this.dbCredentials = dbCredentials;
this._dbCredentials = dbCredentials;
}
catch(Exception ex)
{
@@ -91,7 +91,7 @@ namespace bnhtrade.Core.Data.Database
{
throw new Exception("DB credentials object is null");
}
this.dbCredentials = dbCredentials;
this._dbCredentials = dbCredentials;
}
}
}

View File

@@ -1,102 +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.Consistency
{
public class ImportAmazonSettlement : Connection
{
public ImportAmazonSettlement()
{
}
public List<string> ErrorMessage { get; private set; }
public bool ErrorMessageIsSet
{
get
{
if (ErrorMessage == null || !ErrorMessage.Any()) { return false; }
else { return true; }
}
}
public bool PeriodDateGaps()
{
ErrorMessage = null;
using (var sqlConn = new SqlConnection(SqlConnectionString))
{
var log = new Logic.Log.LogEvent();
sqlConn.Open();
// get list of marketplace names
var marketplaces = new List<string>();
using (SqlCommand cmd = new SqlCommand(@"
SELECT DISTINCT tblImportAmazonSettlementReport.ImportAmazonSettlementReportID
,tblImportAmazonSettlementReport.[marketplace-name]
,tblImportAmazonSettlementReport.[settlement-start-date]
,tblImportAmazonSettlementReport.[settlement-end-date]
FROM tblImportAmazonSettlementReport
ORDER BY tblImportAmazonSettlementReport.[marketplace-name]
,tblImportAmazonSettlementReport.[settlement-start-date]
,tblImportAmazonSettlementReport.[settlement-end-date];
", sqlConn))
{
using(var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
ErrorMessage.Add("No data found. Is the table empty?");
return false;
}
int i = 0;
string marketplace = "some-random-string-7posadlnvl2oaweoh3amol5o5irv8nl2aoqefl";
DateTime endDate = DateTime.SpecifyKind(default(DateTime), DateTimeKind.Utc);
while (reader.Read())
{
if (reader.IsDBNull(1))
{
log.LogError(
"Action required: Enter market place name for settlelment report id " + reader.GetInt32(0) + "."
, "Unable to process settlement data from one settlement report '" + reader.GetInt32(0) +
"'. Report header table requires a market place name, which is not supplied in original " +
"report from Amazon. This is useually inferred from settlement lines. " +
"However, in this case, it was not not possible. Manual edit/entry for database table required."
);
return false;
}
string newMarketPlace = reader.GetString(1);
DateTime startDate = DateTime.SpecifyKind( reader.GetDateTime(2), DateTimeKind.Utc);
if (marketplace != newMarketPlace)
{
marketplace = newMarketPlace;
i = 0;
}
if (i > 0 && startDate != endDate)
{
log.LogError("Inconsistancy in DB data found, break in settlement period dates.",
marketplace + " at ID=" + reader.GetInt32(0) + " start-date is not the same as the previous period end-date."
+ Environment.NewLine + "If it's a missing settlement report and it's over 90 days ago, you may need to go to"
+ " 'Seller Central' > 'Payments' > 'All Statements' and manually 'Request Report' for each missing settlement.");
return false;
}
endDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
i++;
}
}
}
}
return true;
}
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
@@ -8,9 +8,9 @@ using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Export
{
public class CreateAmazonFeedSubmission : Connection
internal class AmazonFeedSubmissionInsert : Connection
{
public CreateAmazonFeedSubmission ()
public AmazonFeedSubmissionInsert ()
{
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -8,9 +8,9 @@ using Dapper;
namespace bnhtrade.Core.Data.Database.Export
{
public class ReadAmazonFeedSubmission : Connection
internal class AmazonFeedSubmissionRead : Connection
{
public ReadAmazonFeedSubmission()
public AmazonFeedSubmissionRead()
{
}

View File

@@ -1,15 +1,15 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.Export
{
public class UpdateAmazonFeedSubmission : Connection
internal class AmazonFeedSubmissionUpdate : Connection
{
public UpdateAmazonFeedSubmission()
public AmazonFeedSubmissionUpdate()
{
}

View File

@@ -1,120 +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.Export
{
public class CreateSalesInvoice : Connection
{
public CreateSalesInvoice()
{
}
public void Execute(List<Model.Account.SalesInvoice> invoiceList)
{
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
// make the inserts
for (int i = 0; i < invoiceList.Count(); i++)
{
int invoiceId = 0;
using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblExportAccountInvoice (
ExportAccountInvoiceTypeID
,Contact
,InvoiceDate
,InvoiceDueDate
,InvoiceNumber
,Reference
,CurrencyCode
,InvoiceAmount
,IsComplete
)
OUTPUT INSERTED.ExportAccountInvoiceID
VALUES (
@invoiceTypeId
,@contact
,@invoiceDate
,@invoiceDueDate
,@invoiceNumber
,@reference
,@currencyCode
,@invoiceAmount
,@markComplete
);
", sqlConn))
{
cmd.Parameters.AddWithValue("@invoiceTypeId", 2);
cmd.Parameters.AddWithValue("@contact", invoiceList[i].ContactName);
cmd.Parameters.AddWithValue("@invoiceDate", invoiceList[i].InvoiceDate);
cmd.Parameters.AddWithValue("@invoiceDueDate", invoiceList[i].InvoiceDueDate);
cmd.Parameters.AddWithValue("@reference", invoiceList[i].InvoiceReference);
cmd.Parameters.AddWithValue("@currencyCode", invoiceList[i].InvoiceCurrencyCode);
cmd.Parameters.AddWithValue("@markComplete", false);
cmd.Parameters.AddWithValue("@invoiceNumber", invoiceList[i].InvoiceNumber);
cmd.Parameters.AddWithValue("@invoiceAmount", invoiceList[i].InvoiceTotalAmount);
invoiceId = (int)cmd.ExecuteScalar();
}
for (int j = 0; j < invoiceList[i].InvoiceLineList.Count(); j++)
{
// insert record
using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblExportAccountInvoiceLine (
ExportAccountInvoiceID
,AccountInvoiceLineItemID
,NetAmount
,AccountChartOfID
,TaxAmount
,AccountTaxCodeID
)
OUTPUT INSERTED.ExportAccountInvoiceLineID
VALUES (
@invoiceId
,(
SELECT AccountInvoiceLineItemID
FROM tblAccountInvoiceLineItem
WHERE ItemCode = @itemCode
)
,@netAmount
,(
SELECT AccountChartOfID
FROM tblAccountChartOf
WHERE AccountCode = @accountCode
)
,@taxAmount
,(
SELECT AccountTaxCodeID
FROM tblAccountTaxCode
WHERE TaxCode = @taxCode
)
);
", sqlConn))
{
cmd.Parameters.AddWithValue("@invoiceID", invoiceId);
cmd.Parameters.AddWithValue("@itemCode", invoiceList[i].InvoiceLineList[j].ItemCode);
cmd.Parameters.AddWithValue("@netAmount", invoiceList[i].InvoiceLineList[j].UnitAmount);
cmd.Parameters.AddWithValue("@accountCode", (int)invoiceList[i].InvoiceLineList[j].AccountCode.AccountCode);
cmd.Parameters.AddWithValue("@taxAmount", invoiceList[i].InvoiceLineList[j].TaxAmount);
cmd.Parameters.AddWithValue("@taxCode", invoiceList[i].InvoiceLineList[j].TaxCode.TaxCode);
int lineId = (int)cmd.ExecuteScalar();
}
}
}
}
scope.Complete();
}
}
}
}

View File

@@ -1,294 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace bnhtrade.Core.Data.Database.Import
{
public class AmazonSettlementHeaderRead : Connection
{
private Dictionary<string, int> dicTablePkBySettlementId = new Dictionary<string, int>();
private int? returnTop = null;
private List<string> settlementIdList;
private List<string> spapiReportId;
protected bool FilterOutIsProcessed { get; set; }
public bool DescendingOrder { get; set; }
public int ReturnTop
{
get { return (int)returnTop; }
set
{
if (value > 0)
{ returnTop = value; }
else
{ returnTop = null; }
}
}
public bool ReturnTopIsSet
{
get { return returnTop != null; }
}
private List<string> SettlementIdList
{
get { return settlementIdList; }
set
{
if (value.Any())
{ settlementIdList = value; }
}
}
private List<string> SpapiReportIdList
{
get { return spapiReportId; }
set
{
if (value.Any())
{ spapiReportId = value; }
}
}
private bool SettlementIdListIsSet
{
get { return SettlementIdList != null; }
}
private bool SpapiReportIdIsSet
{
get { return SpapiReportIdList != null; }
}
public AmazonSettlementHeaderRead()
{
Innit();
}
private void Innit()
{
DescendingOrder = false;
FilterOutIsProcessed = false;
ReturnTop = 0;
settlementIdList = null;
spapiReportId = null;
}
public List<Model.Import.AmazonSettlementHeader> AllUnprocessed()
{
Innit();
FilterOutIsProcessed = true;
return ReadHeaderList();
}
public Model.Import.AmazonSettlementHeader BySettlementId(string settlementId)
{
Innit();
// create settlement list
var idList = new List<string>();
idList.Add(settlementId);
var settlementList = BySettlementId(idList);
// return answer
if (settlementList == null || !settlementList.Any())
{ return null; }
else
{ return settlementList.First(); }
}
public List<Model.Import.AmazonSettlementHeader> BySettlementId(List<string> settlementIdList)
{
Innit();
if (settlementIdList == null || !settlementIdList.Any())
{ return new List<Model.Import.AmazonSettlementHeader>(); }
SettlementIdList = settlementIdList;
return ReadHeaderList();
}
public List<Model.Import.AmazonSettlementHeader> BySpapiReportId(List<string> spapiReportIdList)
{
Innit();
if (spapiReportIdList == null || !spapiReportIdList.Any())
{ return new List<Model.Import.AmazonSettlementHeader>(); }
SpapiReportIdList = spapiReportIdList;
return ReadHeaderList();
}
private List<Model.Import.AmazonSettlementHeader> ReadHeaderList()
{
var returnHeaderList = new List<Model.Import.AmazonSettlementHeader>();
// build the sql string
string sqlString = "SELECT ";
if (ReturnTopIsSet)
{
sqlString = sqlString + "TOP " + ReturnTop + " ";
}
sqlString = sqlString + @"
ImportAmazonSettlementReportID
,[marketplace-name]
,[settlement-id]
,[settlement-start-date]
,[settlement-end-date]
,[deposit-date]
,[total-amount]
,currency
,IsProcessed
,SpapiReportId
FROM tblImportAmazonSettlementReport
WHERE 1 = 1";
if (FilterOutIsProcessed)
{
sqlString = sqlString + @"
AND IsProcessed = 0";
}
// build dictionary of parameter and values for settlementid
var dicSettlementIdByParameterString = new Dictionary<string, string>();
if (SettlementIdListIsSet)
{
int count = 0;
foreach (string item in SettlementIdList)
{
if (!string.IsNullOrWhiteSpace(item))
{
count = count + 1;
string parameterString = "@settlementId" + count;
dicSettlementIdByParameterString.Add(parameterString, item);
}
}
}
if (dicSettlementIdByParameterString.Any())
{
int count = 0;
foreach (var item in dicSettlementIdByParameterString)
{
count = count + 1;
if (count == 1)
{
sqlString = sqlString + @"
AND ( [settlement-id] = " + item.Key;
}
else
{
sqlString = sqlString + @"
OR [settlement-id] = " + item.Key;
}
}
sqlString = sqlString + " )";
}
// build dictionary of parameter and values for SP-API Report Id
var dicSpapiReportIdByParameterString = new Dictionary<string, string>();
if (SpapiReportIdIsSet)
{
int count = 0;
foreach (string item in SpapiReportIdList)
{
if (!string.IsNullOrWhiteSpace(item))
{
count = count + 1;
string parameterString = "@SpapiReportId" + count;
dicSpapiReportIdByParameterString.Add(parameterString, item);
}
}
}
if (dicSpapiReportIdByParameterString.Any())
{
int count = 0;
foreach (var item in dicSpapiReportIdByParameterString)
{
count = count + 1;
if (count == 1)
{
sqlString = sqlString + @"
AND ( SpapiReportId = " + item.Key;
}
else
{
sqlString = sqlString + @"
OR SpapiReportId = " + item.Key;
}
}
sqlString = sqlString + " )";
}
sqlString = sqlString + @"
ORDER BY [settlement-start-date] ";
if (DescendingOrder) { sqlString = sqlString + " DESC"; }
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
if (dicSettlementIdByParameterString.Any())
{
foreach (var item in dicSettlementIdByParameterString)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
if (dicSpapiReportIdByParameterString.Any())
{
foreach (var item in dicSpapiReportIdByParameterString)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var header = new Model.Import.AmazonSettlementHeader();
int tablePk = reader.GetInt32(0);
if (!reader.IsDBNull(1)) { header.MarketPlaceName = reader.GetString(1); }
header.SettlementId = reader.GetString(2);
header.StartDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
header.EndDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
header.DepositDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
header.TotalAmount = reader.GetDecimal(6);
header.CurrencyCode = reader.GetString(7);
header.IsProcessed = reader.GetBoolean(8);
if (!reader.IsDBNull(9)) { header.SpapiReportId = reader.GetString(9); }
// update dictionary
if (!dicTablePkBySettlementId.ContainsKey(header.SettlementId))
{
dicTablePkBySettlementId.Add(header.SettlementId, tablePk);
}
// add header to list
returnHeaderList.Add(header);
}
}
}
}
return returnHeaderList;
}
}
}

View File

@@ -1,330 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Import
{
public class AmazonSettlementInsert : Connection
{
Logic.Log.LogEvent log = new Logic.Log.LogEvent();
public AmazonSettlementInsert ()
{
}
/// <summary>
///
/// </summary>
/// <param name="filePath"></param>
/// <param name="reportId">The unique Amazon SP-API report id (not settlement id)</param>
/// <returns></returns>
public bool ByFlatFile(string filePath, string reportId)
{
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
int settlementReportId = 0;
string settlementRef = "";
bool marketPlaceUpdated = false;
decimal settlementAmount = 0m;
int lineNumber = 2;
int lineSkip = 0;
using (var reader = new StreamReader(filePath))
{
//read file one line at a time and insert data into table if required
// read header and retrive information
string headerRow = reader.ReadLine();
string[] headers = headerRow.Split('\t');
int columnCount = headers.Length;
int indexSettlementId = Array.IndexOf(headers, "settlement-id");
int indexSettlementStartDate = Array.IndexOf(headers, "settlement-start-date");
int indexSettlementEndDate = Array.IndexOf(headers, "settlement-end-date");
int indexDepositDate = Array.IndexOf(headers, "deposit-date");
int indexTotalAmount = Array.IndexOf(headers, "total-amount");
int indexCurrency = Array.IndexOf(headers, "currency");
int indexTransactionType = Array.IndexOf(headers, "transaction-type");
int indexOrderId = Array.IndexOf(headers, "order-id");
int indexMerchantOrderId = Array.IndexOf(headers, "merchant-order-id");
int indexAdjustmentId = Array.IndexOf(headers, "adjustment-id");
int indexShipmentId = Array.IndexOf(headers, "shipment-id");
int indexMarketplaceName = Array.IndexOf(headers, "marketplace-name");
int indexAmountType = Array.IndexOf(headers, "amount-type");
int indexAmountDescription = Array.IndexOf(headers, "amount-description");
int indexAmount = Array.IndexOf(headers, "amount");
int indexFulfillmentId = Array.IndexOf(headers, "fulfillment-id");
// int indexPostedDate = Array.IndexOf(headers, "posted-date");
int indexPostedDateTime = Array.IndexOf(headers, "posted-date-time");
int indexOrderItemCode = Array.IndexOf(headers, "order-item-code");
int indexMerchantOrderItemId = Array.IndexOf(headers, "merchant-order-item-id");
int indexMerchantAdjustmentItemId = Array.IndexOf(headers, "merchant-adjustment-item-id");
int indexSku = Array.IndexOf(headers, "sku");
int indexQuantityPurchased = Array.IndexOf(headers, "quantity-purchased");
int indexPromotionId = Array.IndexOf(headers, "promotion-id");
string currency = "";
string fileRow;
while ((fileRow = reader.ReadLine()) != null)
{
Console.Write("\rParsing record: " + lineNumber);
//split line into array
string[] items = fileRow.Split('\t');
if (items.Length != columnCount)
{
// skip line
lineSkip = lineSkip + 1;
log.LogWarning(
"Line #" + lineNumber + " skipped due to no enough element in row.",
filePath
);
}
else if (lineNumber == 2)
{
// check if settlement has already been imported
using (SqlCommand sqlCommand = new SqlCommand(
"SELECT COUNT(*) FROM tblImportAmazonSettlementReport WHERE [settlement-id]=@settlementId;"
, sqlConn))
{
sqlCommand.Parameters.AddWithValue("@settlementId", items[indexSettlementId]);
int recordCount = (int)sqlCommand.ExecuteScalar();
if (recordCount > 0)
{
UpdateSpapiReportId(items[indexSettlementId], reportId);
log.LogInformation("Settlement report already imported, skipping...");
scope.Complete();
return true;
}
}
//set currencyId
//currencyId = GeneralQueries.GetCurrencyId(items[5]);
//set currency
currency = items[indexCurrency];
settlementAmount = decimal.Parse(items[indexTotalAmount].Replace(",", "."));
// insert
using (SqlCommand sqlCommand = new SqlCommand(@"
INSERT INTO tblImportAmazonSettlementReport (
[settlement-id]
,[settlement-start-date]
,[settlement-end-date]
,[deposit-date]
,[total-amount]
,[currency]
,SpapiReportId
)
OUTPUT INSERTED.ImportAmazonSettlementReportID
VALUES (
@settlementId
,@settlementStartDate
,@settlementEndDate
,@depositDate
,@settlementotalAmounttId
,@currency
,@reportId
);
", sqlConn))
{
// add parameters
if (indexSettlementId == -1 || items[indexSettlementId].Length == 0) { sqlCommand.Parameters.AddWithValue("@settlementId", DBNull.Value); }
else
{
settlementRef = items[indexSettlementId];
sqlCommand.Parameters.AddWithValue("@settlementId", settlementRef);
}
var parseDateTime = new Core.Logic.Utilities.DateTime();
if (indexSettlementStartDate == -1 || items[indexSettlementStartDate].Length == 0) { sqlCommand.Parameters.AddWithValue("@settlementStartDate", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@settlementStartDate", parseDateTime.ParseIsoDateTimeString(items[indexSettlementStartDate])); }
if (indexSettlementEndDate == -1 || items[indexSettlementEndDate].Length == 0) { sqlCommand.Parameters.AddWithValue("@settlementEndDate", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@settlementEndDate", parseDateTime.ParseIsoDateTimeString(items[indexSettlementEndDate])); }
if (indexDepositDate == -1 || items[indexDepositDate].Length == 0) { sqlCommand.Parameters.AddWithValue("@depositDate", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@depositDate", parseDateTime.ParseIsoDateTimeString(items[indexDepositDate])); }
if (indexTotalAmount == -1 || items[indexTotalAmount].Length == 0) { sqlCommand.Parameters.AddWithValue("@totalAmount", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@settlementotalAmounttId", settlementAmount); }
if (string.IsNullOrWhiteSpace(reportId)) { sqlCommand.Parameters.AddWithValue("@reportId", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@reportId", reportId); }
sqlCommand.Parameters.AddWithValue("@currency", currency);
//if (currencyId == -1) { sqlCommand.Parameters.AddWithValue("@currencyId", DBNull.Value); }
//else { sqlCommand.Parameters.AddWithValue("@currencyId", currencyId); }
//execute and retrive id
settlementReportId = (int)sqlCommand.ExecuteScalar();
}
}
else
{
//update market place name in main table, if required
if (marketPlaceUpdated == false && settlementReportId > 0 && items[indexMarketplaceName].Length > 1)
{
using (SqlCommand sqlCommand = new SqlCommand(@"
UPDATE tblImportAmazonSettlementReport
SET [marketplace-name]=@MarketplaceName
WHERE ImportAmazonSettlementReportID=@ImportAmazonSettlementReportID
", sqlConn))
{
sqlCommand.Parameters.AddWithValue("@MarketplaceName", items[indexMarketplaceName]);
sqlCommand.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
sqlCommand.ExecuteNonQuery();
marketPlaceUpdated = true;
}
}
//insert report items
using (SqlCommand sqlCommand = new SqlCommand(
"INSERT INTO tblImportAmazonSettlementReportLine ( " +
"ImportAmazonSettlementReportID, [transaction-type], [order-id], [merchant-order-id], [adjustment-id], [shipment-id], [marketplace-name], " +
"[amount-type], [amount-description], [currency], [amount], [fulfillment-id], [posted-date-time], [order-item-code], " +
"[merchant-order-item-id], [merchant-adjustment-item-id], [sku], [quantity-purchased], [promotion-id] ) " +
"VALUES ( " +
"@ImportAmazonSettlementReportID, @TransactionType, @orderRef, @merchantOrderRef, @AdjustmentRef, @ShipmentRef, @MarketplaceName, " +
"@AmountType, @AmountDescription, @currency, @Amount, @FulfillmentRef, @PostedDateTimeUTC, @OrderItemCode, " +
"@MerchantOrderItemRef, @MerchantAdjustmentItemRef, @SkuNumber, @QuantityPurchased, @PromotionRef );"
, sqlConn))
{
// add parameters
sqlCommand.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
sqlCommand.Parameters.AddWithValue("@currency", currency);
if (indexTransactionType == -1 || items[indexTransactionType].Length == 0) { sqlCommand.Parameters.AddWithValue("@TransactionType", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@TransactionType", items[indexTransactionType]); }
if (indexOrderId == -1 || items[indexOrderId].Length == 0) { sqlCommand.Parameters.AddWithValue("@orderRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@orderRef", items[indexOrderId]); }
if (indexMerchantOrderId == -1 || items[indexMerchantOrderId].Length == 0) { sqlCommand.Parameters.AddWithValue("@merchantOrderRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@merchantOrderRef", items[indexMerchantOrderId]); }
if (indexAdjustmentId == -1 || items[indexAdjustmentId].Length == 0) { sqlCommand.Parameters.AddWithValue("@AdjustmentRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@AdjustmentRef", items[indexAdjustmentId]); }
if (indexShipmentId == -1 || items[indexShipmentId].Length == 0) { sqlCommand.Parameters.AddWithValue("@ShipmentRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@ShipmentRef", items[indexShipmentId]); }
if (indexMarketplaceName == -1 || items[indexMarketplaceName].Length == 0) { sqlCommand.Parameters.AddWithValue("@MarketplaceName", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@MarketplaceName", items[indexMarketplaceName]); }
if (indexAmountType == -1 || items[indexAmountType].Length == 0) { sqlCommand.Parameters.AddWithValue("@AmountType", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@AmountType", items[indexAmountType]); }
if (indexAmountDescription == -1 || items[indexAmountDescription].Length == 0) { sqlCommand.Parameters.AddWithValue("@AmountDescription", DBNull.Value); }
else
{
string amountDescription = items[indexAmountDescription];
if (amountDescription.Length > 100) { amountDescription = amountDescription.Substring(0, 100); }
sqlCommand.Parameters.AddWithValue("@AmountDescription", amountDescription);
}
if (indexAmount == -1 || items[indexAmount].Length == 0) { sqlCommand.Parameters.AddWithValue("@Amount", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@Amount", decimal.Parse(items[indexAmount].Replace(",", "."))); }
if (indexFulfillmentId == -1 || items[indexFulfillmentId].Length == 0) { sqlCommand.Parameters.AddWithValue("@FulfillmentRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@FulfillmentRef", items[indexFulfillmentId]); }
if (indexPostedDateTime == -1 || items[indexPostedDateTime].Length == 0) { sqlCommand.Parameters.AddWithValue("@PostedDateTimeUTC", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@PostedDateTimeUTC", new Logic.Utilities.DateTime().ParseIsoDateTimeString(items[indexPostedDateTime])); }
if (indexOrderItemCode == -1 || items[indexOrderItemCode].Length == 0) { sqlCommand.Parameters.AddWithValue("@OrderItemCode", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@OrderItemCode", long.Parse(items[indexOrderItemCode])); }
if (indexMerchantOrderItemId == -1 || items[indexMerchantOrderItemId].Length == 0) { sqlCommand.Parameters.AddWithValue("@MerchantOrderItemRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@MerchantOrderItemRef", long.Parse(items[indexMerchantOrderItemId])); }
if (indexMerchantAdjustmentItemId == -1 || items[indexMerchantAdjustmentItemId].Length == 0) { sqlCommand.Parameters.AddWithValue("@MerchantAdjustmentItemRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@MerchantAdjustmentItemRef", items[indexMerchantAdjustmentItemId]); }
if (indexSku == -1 || items[indexSku].Length == 0) { sqlCommand.Parameters.AddWithValue("@SkuNumber", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@SkuNumber", items[indexSku]); }
if (indexQuantityPurchased == -1 || items[indexQuantityPurchased].Length == 0) { sqlCommand.Parameters.AddWithValue("@QuantityPurchased", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@QuantityPurchased", int.Parse(items[indexQuantityPurchased])); }
if (indexPromotionId == -1 || items[indexPromotionId].Length == 0) { sqlCommand.Parameters.AddWithValue("@PromotionRef", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@PromotionRef", items[indexPromotionId]); }
sqlCommand.ExecuteNonQuery();
}
}
lineNumber = lineNumber + 1;
}
}
//final check - settlement amount matches sum of inserted settlement lines
using (SqlCommand sqlCommand = new SqlCommand(@"
SELECT Sum(tblImportAmazonSettlementReportLine.amount) AS SumOfAmount
FROM tblImportAmazonSettlementReportLine
WHERE ImportAmazonSettlementReportID=@ImportAmazonSettlementReportID;
", sqlConn))
{
decimal sumOfAmount = -1.12345m;
sqlCommand.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
sumOfAmount = (decimal)sqlCommand.ExecuteScalar();
if (sumOfAmount != settlementAmount)
{
log.LogError("Error importing settlement id'" + settlementRef + "'. Sum of inserted settlement lines (" + sumOfAmount +
") does not match settlement amount (" + settlementAmount + ").");
return false;
}
}
scope.Complete();
Console.Write("\r");
log.LogInformation((lineNumber - (2 + lineSkip)) + " total settlement items inserted");
if (lineSkip > 0)
{
log.LogError(lineSkip + " total line(s) where skipped due to insufficent number of cells on row");
}
}
}
return true;
}
public void UpdateSpapiReportId (string settlementId, string spapiReportId)
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
UPDATE
tblImportAmazonSettlementReport
SET
SpapiReportId = @spapiReportId
WHERE
[settlement-id] = @settlementId
", conn))
{
cmd.Parameters.AddWithValue("@spapiReportId", spapiReportId);
cmd.Parameters.AddWithValue("@settlementId", settlementId);
cmd.ExecuteNonQuery();
}
}
}
}
}

View File

@@ -1,462 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace bnhtrade.Core.Data.Database.Import
{
public class AmazonSettlementRead : Connection
{
private Data.Database.SqlWhereBuilder whereBuilder = new SqlWhereBuilder();
public List<Model.Import.AmazonSettlement> BySettlementIdList(List<string> settlementIdList)
{
var settlementList = new List<Model.Import.AmazonSettlement>();
// build sql statement
string sql = @"
SELECT tblImportAmazonSettlementReport.[settlement-id]
,tblImportAmazonSettlementReportLine.[transaction-type]
,tblImportAmazonSettlementReportLine.[order-id]
,tblImportAmazonSettlementReportLine.[merchant-order-id]
,tblImportAmazonSettlementReportLine.[adjustment-id]
,tblImportAmazonSettlementReportLine.[shipment-id]
,tblImportAmazonSettlementReportLine.[marketplace-name]
,tblImportAmazonSettlementReportLine.[amount-type]
,tblImportAmazonSettlementReportLine.[amount-description]
,tblImportAmazonSettlementReportLine.amount
,tblImportAmazonSettlementReportLine.currency
,tblImportAmazonSettlementReportLine.[fulfillment-id]
,tblImportAmazonSettlementReportLine.[posted-date-time]
,tblImportAmazonSettlementReportLine.[order-item-code]
,tblImportAmazonSettlementReportLine.[merchant-order-item-id]
,tblImportAmazonSettlementReportLine.[merchant-adjustment-item-id]
,tblImportAmazonSettlementReportLine.sku
,tblImportAmazonSettlementReportLine.[quantity-purchased]
,tblImportAmazonSettlementReportLine.[promotion-id]
,tblImportAmazonSettlementReportLine.IsProcessed
,tblImportAmazonSettlementReportLine.ExportAccountInvoiceLineID
FROM tblImportAmazonSettlementReport
INNER JOIN tblImportAmazonSettlementReportLine ON tblImportAmazonSettlementReport.ImportAmazonSettlementReportID = tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportID
WHERE ";
whereBuilder.Init();
whereBuilder.In("tblImportAmazonSettlementReport.[settlement-id]", settlementIdList);
sql += whereBuilder.SqlWhereString;
sql += @"
ORDER BY tblImportAmazonSettlementReport.[settlement-id]
,tblImportAmazonSettlementReportLine.[posted-date-time] ";
// set variables
bool firstRecord = true;
string settlementId = "";
var lineList = new List<Model.Import.AmazonSettlement.SettlementLine>();
var LineListDic = new Dictionary<string, List<Model.Import.AmazonSettlement.SettlementLine>>();
var headerList = new List<Model.Import.AmazonSettlementHeader>();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
whereBuilder.AddParametersToSqlCommand(cmd);
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return settlementList;
}
// get the header list
headerList = new Data.Database.Import.AmazonSettlementHeaderRead().BySettlementId(settlementIdList);
// loop through table to build dictionary
while (reader.Read())
{
if (reader.GetString(0) != settlementId)
{
if (firstRecord)
{
firstRecord = false;
settlementId = reader.GetString(0);
}
else
{
LineListDic.Add(settlementId, lineList);
settlementId = reader.GetString(0);
lineList = new List<Model.Import.AmazonSettlement.SettlementLine>();
}
}
var line = new Model.Import.AmazonSettlement.SettlementLine();
line.TransactionType = reader.GetString(1);
if (!reader.IsDBNull(2)) { line.OrderId = reader.GetString(2); }
if (!reader.IsDBNull(3)) { line.MerchantOrderId = reader.GetString(3); }
if (!reader.IsDBNull(4)) { line.AdjustmentId = reader.GetString(4); }
if (!reader.IsDBNull(5)) { line.ShipmentId = reader.GetString(5); }
if (!reader.IsDBNull(6)) { line.MarketPlaceName = reader.GetString(6); }
line.AmountType = reader.GetString(7);
line.AmountDescription = reader.GetString(8);
line.Amount = reader.GetDecimal(9);
line.CurrenyCode = reader.GetString(10);
if (!reader.IsDBNull(11)) { line.FulfillmentId = reader.GetString(11); }
line.PostDateTime = DateTime.SpecifyKind(reader.GetDateTime(12), DateTimeKind.Utc);
if (!reader.IsDBNull(13)) { line.OrderItemCode = reader.GetString(13); }
if (!reader.IsDBNull(14)) { line.MerchantOrderItemId = reader.GetString(14); }
if (!reader.IsDBNull(15)) { line.MerchantAdjustmentItemId = reader.GetString(15); }
if (!reader.IsDBNull(16)) { line.Sku = reader.GetString(16); }
if (!reader.IsDBNull(17)) { line.QuantityPurchased = reader.GetInt32(17); }
if (!reader.IsDBNull(18)) { line.PromotionId = reader.GetString(18); }
line.IsProcessed = reader.GetBoolean(19);
if (!reader.IsDBNull(20)) { int exportAccountInvoiceLineId = reader.GetInt32(20); }
lineList.Add(line);
}
LineListDic.Add(settlementId, lineList);
}
}
}
//create return list
foreach(var item in headerList)
{
var settlementReport = new Model.Import.AmazonSettlement(item);
settlementReport.SettlementLineList = LineListDic[item.SettlementId];
settlementList.Add(settlementReport);
}
return settlementList;
}
public void ByHeaderList()
{
}
public void BySettlementId()
{
}
private Dictionary<string, int> dicTablePkBySettlementId = new Dictionary<string, int>();
private int? returnTop = null;
private List<string> settlementIdList;
private bool FilterOutIsProcessed { get; set; }
public bool DescendingOrder { get; set; }
public int ReturnTop
{
get { return (int)returnTop; }
set
{
if (value > 0)
{ returnTop = value; }
else
{ returnTop = null; }
}
}
public bool ReturnTopIsSet
{
get { return returnTop != null; }
}
private List<string> SettlementIdList
{
get { return settlementIdList; }
set
{
if (value.Any())
{ settlementIdList = value; }
}
}
private bool SettlementIdListIsSet
{
get { return SettlementIdList != null; }
}
public AmazonSettlementRead()
{
Innit();
}
private void Innit()
{
DescendingOrder = false;
FilterOutIsProcessed = false;
ReturnTop = 0;
settlementIdList = null;
}
public List<Model.Import.AmazonSettlement> AllUnprocessed()
{
Innit();
FilterOutIsProcessed = true;
return ExecuteDbQuery();
}
public Model.Import.AmazonSettlement BySettlementId(string settlementId)
{
Innit();
// create settlement list
var idList = new List<string>();
idList.Add(settlementId);
var settlementList = BySettlementId(idList);
// return answer
if (settlementList == null || !settlementList.Any())
{ return null; }
else
{ return settlementList.First(); }
}
public List<Model.Import.AmazonSettlement> BySettlementId(List<string> settlementIdList)
{
Innit();
if (settlementIdList == null || !settlementIdList.Any())
{ return null; }
SettlementIdList = settlementIdList;
return ExecuteDbQuery();
}
private List<Model.Import.AmazonSettlement> ExecuteDbQuery()
{
// get header info
var settlementList = ReadHeaderList();
if (settlementList == null || !settlementList.Any())
{
return null;
}
// add lines to header
foreach (var item in settlementList)
{
if (!dicTablePkBySettlementId.ContainsKey(item.SettlementId))
{
throw new Exception("This shouldnt' happen!");
}
int tablePk = dicTablePkBySettlementId[item.SettlementId];
item.SettlementLineList = ReadLineList(tablePk);
}
return settlementList;
}
private List<Model.Import.AmazonSettlement> ReadHeaderList()
{
// build the sql string
string sqlString = "SELECT ";
if (ReturnTopIsSet)
{
sqlString = sqlString + "TOP " + ReturnTop + " ";
}
sqlString = sqlString + @"
ImportAmazonSettlementReportID
,[marketplace-name]
,[settlement-id]
,[settlement-start-date]
,[settlement-end-date]
,[deposit-date]
,[total-amount]
,currency
,IsProcessed
FROM tblImportAmazonSettlementReport
WHERE 1 = 1";
if (FilterOutIsProcessed)
{
sqlString = sqlString + @"
AND IsProcessed = 0";
}
// build dictionary of parameter and values
var dicSettlementIdByParameterString = new Dictionary<string, string>();
if (SettlementIdListIsSet)
{
int count = 0;
foreach (string item in SettlementIdList)
{
if (!string.IsNullOrWhiteSpace(item))
{
count = count + 1;
string parameterString = "@settlementId" + count;
dicSettlementIdByParameterString.Add(parameterString, item);
}
}
}
if (dicSettlementIdByParameterString.Any())
{
int count = 0;
foreach (var item in dicSettlementIdByParameterString)
{
count = count + 1;
if (count == 1)
{
sqlString = sqlString + @"
AND ( [settlement-id] = " + item.Key;
}
else
{
sqlString = sqlString + @"
OR [settlement-id] = " + item.Key;
}
}
sqlString = sqlString + " )";
}
sqlString = sqlString + @"
ORDER BY [settlement-start-date] ";
if (DescendingOrder) { sqlString = sqlString + " DESC"; }
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
if (dicSettlementIdByParameterString.Any())
{
foreach (var item in dicSettlementIdByParameterString)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return null;
}
var headerList = new List<Model.Import.AmazonSettlement>();
while (reader.Read())
{
var header = new Model.Import.AmazonSettlement();
int tablePk = reader.GetInt32(0);
if (!reader.IsDBNull(1)) { header.MarketPlaceName = reader.GetString(1); }
header.SettlementId = reader.GetString(2);
header.StartDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
header.EndDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
header.DepositDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
header.TotalAmount = reader.GetDecimal(6);
header.CurrencyCode = reader.GetString(7);
header.IsProcessed = reader.GetBoolean(8);
// update dictionary
if (!dicTablePkBySettlementId.ContainsKey(header.SettlementId))
{
dicTablePkBySettlementId.Add(header.SettlementId, tablePk);
}
// add header to list
headerList.Add(header);
}
return headerList;
}
}
}
}
private List<Model.Import.AmazonSettlement.SettlementLine> ReadLineList(int settlementPk)
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT ImportAmazonSettlementReportLineID
,[transaction-type]
,[order-id]
,[merchant-order-id]
,[adjustment-id]
,[shipment-id]
,[marketplace-name]
,[amount-type]
,[amount-description]
,amount
,currency
,[fulfillment-id]
,[posted-date-time]
,[order-item-code]
,[merchant-order-item-id]
,[merchant-adjustment-item-id]
,sku
,[quantity-purchased]
,[promotion-id]
,IsProcessed
,ExportAccountInvoiceLineID
FROM tblImportAmazonSettlementReportLine
WHERE ImportAmazonSettlementReportID = @settlementPk
ORDER BY [posted-date-time]
", conn))
{
cmd.Parameters.AddWithValue("@settlementPk", settlementPk);
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return null;
}
var lineList = new List<Model.Import.AmazonSettlement.SettlementLine>();
while (reader.Read())
{
var line = new Model.Import.AmazonSettlement.SettlementLine();
int tablePk = reader.GetInt32(0);
line.TransactionType = reader.GetString(1);
if (!reader.IsDBNull(2)) { line.OrderId = reader.GetString(2); }
if (!reader.IsDBNull(3)) { line.MerchantOrderId = reader.GetString(3); }
if (!reader.IsDBNull(4)) { line.AdjustmentId = reader.GetString(4); }
if (!reader.IsDBNull(5)) { line.ShipmentId = reader.GetString(5); }
if (!reader.IsDBNull(6)) { line.MarketPlaceName = reader.GetString(6); }
line.AmountType = reader.GetString(7);
line.AmountDescription = reader.GetString(8);
line.Amount = reader.GetDecimal(9);
line.CurrenyCode = reader.GetString(10);
if (!reader.IsDBNull(11)) { line.FulfillmentId = reader.GetString(11); }
line.PostDateTime = DateTime.SpecifyKind(reader.GetDateTime(12), DateTimeKind.Utc);
if (!reader.IsDBNull(13)) { line.OrderItemCode = reader.GetString(13); }
if (!reader.IsDBNull(14)) { line.MerchantOrderItemId = reader.GetString(14); }
if (!reader.IsDBNull(15)) { line.MerchantAdjustmentItemId = reader.GetString(15); }
if (!reader.IsDBNull(16)) { line.Sku = reader.GetString(16); }
if (!reader.IsDBNull(17)) { line.QuantityPurchased = reader.GetInt32(17); }
if (!reader.IsDBNull(18)) { line.PromotionId = reader.GetString(18); }
line.IsProcessed = reader.GetBoolean(19);
if (!reader.IsDBNull(20)) { int exportAccountInvoiceLineId = reader.GetInt32(20); }
lineList.Add(line);
}
return lineList;
}
}
}
}
}
}

View File

@@ -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.Import
{
public class AmazonSettlementUpdate : Connection
{
public AmazonSettlementUpdate()
{
}
public void SetIsProcessedTrue(List<string> settlementIdList)
{
if (settlementIdList == null || !settlementIdList.Any())
{
throw new Exception("Settlement ID list is empty.");
}
string sqlString = @"
UPDATE tblImportAmazonSettlementReport
SET IsProcessed = 1
WHERE (1=0)";
for (int i = 0; i < settlementIdList.Count(); i++)
{
sqlString += @"
OR ([settlement-id] = @settlementId" + i + ")";
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
for (int i = 0; i < settlementIdList.Count(); i++)
{
cmd.Parameters.AddWithValue("@settlementId" + i, settlementIdList[i]);
}
if (cmd.ExecuteNonQuery() == 0)
{
throw new Exception("Something went wrong updating settlement status.");
}
}
}
}
}
}

View File

@@ -1,49 +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.Programmability
{
public class Sequence : Connection
{
public Sequence ()
{
}
public int GetNext(string sequenceName)
{
if (string.IsNullOrWhiteSpace(sequenceName))
{
throw new Exception("Sequence name is null or whitespace.");
}
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT NEXT VALUE FOR " + sequenceName
, conn))
{
//cmd.Parameters.AddWithValue("@sequenceName", sequenceName);
// it wouldn't let me use parameters
object obj = cmd.ExecuteScalar();
try
{
//string whaaaat = (string)obj;
return Convert.ToInt32(obj);
}
catch (Exception ex)
{
throw new Exception("Error returning next value in sequence: " + ex.Message);
}
}
}
}
}
}

View File

@@ -0,0 +1,267 @@
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 CurrencyRepository : _Base, ICurrencyRepository
{
public CurrencyRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
/// <summary>
/// Returns excahnge rate, in decimal format, for a given currency and datetime
/// </summary>
/// <param name="currencyCode">currency code</param>
/// <param name="date">dat and time</param>
/// <returns></returns>
public decimal? ReadExchangeRate(Model.Account.CurrencyCode currencyCode, DateTime date)
{
string sql = @"
SELECT CurrencyUnitsPerGBP
FROM tblAccountExchangeRate
WHERE CurrencyCode=@currencyCode AND StartDate<=@conversionDate AND EndDate>@conversionDate
";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
cmd.Parameters.AddWithValue("@conversionDate", date);
object result = cmd.ExecuteScalar();
if (result != null)
{
return Convert.ToDecimal(result);
}
else
{
return null;
}
}
}
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRate(List<Model.Account.CurrencyCode> currencyCodeList = null, DateTime date = default(DateTime))
{
//throw new NotImplementedException("Complete, but untested");
var returnList = new List<Model.Account.CurrencyExchangeRate>();
string sql = @"
SELECT AccountExchangeRateID, ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate
FROM tblAccountExchangeRate
WHERE 1=1 ";
if (date != default(DateTime))
{
sql = sql + " AND (@dateTime >= StartDate AND @dateTime < endDate) ";
}
var sqlWhere = new Data.Database.SqlWhereBuilder();
// create string list
List<string> stringList = new List<string>();
if (currencyCodeList != null)
{
stringList = currencyCodeList.ConvertAll(f => f.ToString());
if (stringList.Any())
{
sqlWhere.In("CurrencyCode", stringList, "AND");
}
}
sql = sql + sqlWhere.SqlWhereString;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (date != default(DateTime))
{
cmd.Parameters.AddWithValue("@dateTime", date);
}
if (stringList.Any())
{
sqlWhere.AddParametersToSqlCommand(cmd);
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(0);
int exchangeRateSource = reader.GetInt32(1);
string currencyCodeString = reader.GetString(2);
decimal currencyUnitsPerGBP = reader.GetDecimal(3);
DateTime startDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
DateTime endDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
// convert string to enum
if (Enum.TryParse(currencyCodeString, out Model.Account.CurrencyCode currencyCode) == false)
{
throw new Exception("Failed converting database string to enum");
}
var item = new Model.Account.CurrencyExchangeRate(
currencyCode
, exchangeRateSource
, currencyUnitsPerGBP
, startDate
, endDate
);
returnList.Add(item);
}
}
}
return returnList;
}
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRateLatest(List<Model.Account.CurrencyCode> currencyCodeList = null)
{
var returnList = new List<Model.Account.CurrencyExchangeRate>();
string sql = @"
SELECT t1.AccountExchangeRateID, t1.ExchangeRateSource, t1.CurrencyCode, t1.CurrencyUnitsPerGBP, t1.StartDate, t1.EndDate,
t2.maxdate
FROM tblAccountExchangeRate AS t1
INNER JOIN
(SELECT max(StartDate) AS maxdate,
CurrencyCode
FROM tblAccountExchangeRate
GROUP BY CurrencyCode
";
// add any filters
var sqlWhere = new Data.Database.SqlWhereBuilder();
var codeStringList = new List<string>();
if (currencyCodeList != null && currencyCodeList.Any() == true)
{
// convert to string list
foreach (var currencyCode in currencyCodeList)
{
codeStringList.Add(currencyCode.ToString());
}
// add to where statement
sqlWhere.In("CurrencyCode", codeStringList, "HAVING");
sql = sql + sqlWhere.SqlWhereString;
}
sql = sql + @" ) AS t2
ON t1.CurrencyCode = t2.CurrencyCode
AND t1.StartDate = t2.maxdate
ORDER BY t1.CurrencyCode;";
//query db
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
if (codeStringList.Any())
{
sqlWhere.AddParametersToSqlCommand(cmd);
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(0);
int exchangeRateSource = reader.GetInt32(1);
string currencyCodeString = reader.GetString(2);
decimal currencyUnitsPerGBP = reader.GetDecimal(3);
DateTime startDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
DateTime endDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
// convert string to enum
if (Enum.TryParse(currencyCodeString, out Model.Account.CurrencyCode currencyCode) == false)
{
throw new Exception("Failed converting database string to enum");
}
var item = new Model.Account.CurrencyExchangeRate(
currencyCode
, exchangeRateSource
, currencyUnitsPerGBP
, startDate
, endDate
);
returnList.Add(item);
}
}
}
return returnList;
}
public int InsertExchangeRate(int exchangeRateSource, Model.Account.CurrencyCode currencyCode,
decimal currencyUnitsPerGbp, DateTime periodStartUtc, DateTime periodEnd, bool checkOverride = false)
{
// checks
if (periodStartUtc.Kind != DateTimeKind.Utc || periodEnd.Kind != DateTimeKind.Utc)
{
throw new FormatException("Currency date time kind must be UTC");
}
currencyUnitsPerGbp = decimal.Round(currencyUnitsPerGbp, 4);
// CHECKS
if (periodEnd <= periodStartUtc)
{
throw new Exception("Invalid date period.");
}
if (checkOverride == false && (periodEnd - periodStartUtc).Days > 31)
{
throw new Exception("Date period is greater than 31 days.");
}
string sql = @"
INSERT INTO tblAccountExchangeRate (ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate)
OUTPUT INSERTED.AccountExchangeRateID
VALUES (@exchangeRateSource, @currencyCode, @currencyUnitsPerGbp, @periodStart, @periodEnd);
";
// make the insert
DateTime? periodEndLast = null;
int recordId = 0;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@exchangeRateSource", exchangeRateSource);
cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
cmd.Parameters.AddWithValue("@currencyUnitsPerGbp", currencyUnitsPerGbp);
cmd.Parameters.AddWithValue("@periodStart", periodStartUtc);
cmd.Parameters.AddWithValue("@periodEnd", periodEnd);
recordId = (int)cmd.ExecuteScalar();
if (recordId < 1)
{
throw new Exception("Error inserting record, did not retrive new record ID.");
}
}
return recordId;
}
}
}

View File

@@ -0,0 +1,451 @@
using bnhtrade.Core.Data.Database.Repository.Interface;
using bnhtrade.Core.Logic.Validate;
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 ExportInvoiceRepository : _Base, IExportInvoiceRepository
{
public ExportInvoiceRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
//
// invoice Insert methods
//
/// <summary>
/// Don't call this directly, use the logic layer instead (for validation and other checks).
/// </summary>
/// <param name="invoiceList">list of sales invoices to insert</param>
/// <returns>dectionary, key= invoice id, value= new invoice </returns>
public Dictionary<int, Model.Account.SalesInvoice> InsertSalesInvoices(IEnumerable<Model.Account.SalesInvoice> invoiceList)
{
var result = InsertBaseExecute(invoiceList);
var returnList = new Dictionary<int, Model.Account.SalesInvoice>();
foreach (var item in result)
{
returnList.Add(item.Key, (Model.Account.SalesInvoice)item.Value);
}
return returnList;
}
private Dictionary<int, Model.Account.Invoice> InsertBaseExecute(IEnumerable<Model.Account.Invoice> invoiceList)
{
if (invoiceList == null)
{
throw new ArgumentException("Invoice list is null");
}
var returnList = new Dictionary<int, Model.Account.Invoice>();
int invoiceCount = invoiceList.Count();
// make the inserts
foreach (var invoice in invoiceList)
{
int? invoiceId = null;
string sql = @"
INSERT INTO tblExportAccountInvoice (
ExportAccountInvoiceTypeID
,Contact
,InvoiceDate
,InvoiceDueDate
,InvoiceNumber
,Reference
,CurrencyCode
,LineUnitAmountIsTaxExclusive
,InvoiceAmount
,IsComplete
)
OUTPUT INSERTED.ExportAccountInvoiceID
VALUES (
@invoiceTypeId
,@contact
,@invoiceDate
,@invoiceDueDate
,@invoiceNumber
,@reference
,@currencyCode
,@lineUnitAmountIsTaxExclusive
,@invoiceAmount
,@markComplete
);";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@invoiceTypeId", (int)invoice.InvoiceType);
cmd.Parameters.AddWithValue("@contact", invoice.ContactName);
cmd.Parameters.AddWithValue("@invoiceDate", invoice.InvoiceDate);
cmd.Parameters.AddWithValue("@invoiceDueDate", invoice.InvoiceDueDate);
cmd.Parameters.AddWithValue("@reference", invoice.InvoiceReference);
cmd.Parameters.AddWithValue("@currencyCode", invoice.InvoiceCurrencyCode.ToString());
cmd.Parameters.AddWithValue("@lineUnitAmountIsTaxExclusive", invoice.InvoiceLineUnitAmountIsTaxExclusive);
cmd.Parameters.AddWithValue("@markComplete", false);
cmd.Parameters.AddWithValue("@invoiceNumber", invoice.InvoiceNumber);
cmd.Parameters.AddWithValue("@invoiceAmount", invoice.InvoiceTotalAmount);
invoiceId = (int)cmd.ExecuteScalar();
}
foreach (var line in invoice.InvoiceLineList)
{
string lineSql = @"
INSERT INTO tblExportAccountInvoiceLine (
ExportAccountInvoiceID
,AccountInvoiceLineItemID
,NetAmount
,AccountChartOfID
,TaxAmount
,AccountTaxCodeID
)
OUTPUT INSERTED.ExportAccountInvoiceLineID
VALUES (
@invoiceId
,(
SELECT AccountInvoiceLineItemID
FROM tblAccountInvoiceLineItem
WHERE ItemCode = @itemCode
)
,@netAmount
,(
SELECT AccountChartOfID
FROM tblAccountChartOf
WHERE AccountCode = @accountCode
)
,@taxAmount
,(
SELECT AccountTaxCodeID
FROM tblAccountTaxCode
WHERE TaxCode = @taxCode
)
);";
// insert record
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) // Use _connection.CreateCommand()
{
cmd.CommandText = lineSql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@invoiceID", invoiceId);
cmd.Parameters.AddWithValue("@itemCode", line.ItemCode);
cmd.Parameters.AddWithValue("@netAmount", line.UnitAmount);
cmd.Parameters.AddWithValue("@accountCode", (int)line.Account.AccountCode);
cmd.Parameters.AddWithValue("@taxAmount", line.TaxAmountTotal);
cmd.Parameters.AddWithValue("@taxCode", line.TaxCode.TaxCode);
int lineId = (int)cmd.ExecuteScalar();
}
}
returnList.Add(invoiceId.Value, invoice);
}
if (returnList.Count != invoiceCount)
{
throw new Exception("Not all invoices were inserted into the export table. Expected: " + invoiceCount + ", Actual: " + returnList.Count);
}
else
{
return returnList;
}
}
//
// invoice read methods
//
/// <summary>
/// Returns list of invoice numbers that have not yet been exported (i.e. IsComplete=True)
/// </summary>
/// <param name="invoiceType">Sales or Purchase</param>
/// <returns>Dictionary where key=ExportAccountInvoiceID, value=InvoiceNumber</returns>
public Dictionary<int, string> GetNewInvoiceNumbers(Model.Account.InvoiceType invoiceType)
{
var returnList = new Dictionary<int, string>();
string sql = @"
SELECT tblExportAccountInvoice.ExportAccountInvoiceID, [InvoiceNumber]
FROM tblExportAccountInvoice
WHERE (tblExportAccountInvoice.IsComplete = 0)
AND (tblExportAccountInvoice.ExportAccountInvoiceTypeID = @invoiceType);";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@invoiceType", (int)invoiceType);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
returnList.Add(reader.GetInt32(0), reader.GetString(1));
}
}
}
return returnList;
}
/// <summary>
/// Get list of invoices by invoice id
/// </summary>
/// <param name="idList">list of invoice ids</param>
/// <returns>dictionary key=id, value=invoice-model</returns>
public Dictionary<int, Model.Account.SalesInvoice> GetSalesInvoiceById(IEnumerable<int> idList)
{
var returnList = new Dictionary<int, Model.Account.SalesInvoice>();
if (idList.Any() == false)
{
return returnList;
}
// get the account and tax code objects
var taxcode = new Data.Database.Account.ReadTaxCode().GetAllActive();
var account = new Data.Database.Account.ReadAccountCode().All();
// 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
";
var sqlWhere = new Data.Database.SqlWhereBuilder();
sqlWhere.In("tblExportAccountInvoice.ExportAccountInvoiceID", idList, "WHERE");
sql = sql + sqlWhere.SqlWhereString + " ORDER BY tblExportAccountInvoice.ExportAccountInvoiceID, tblExportAccountInvoiceLine.ExportAccountInvoiceLineID; ";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
sqlWhere.AddParametersToSqlCommand(cmd);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows == false)
{
return returnList;
}
int? invoiceId = null;
int? previousInvoiceId = null;
Model.Account.SalesInvoice invoice = null;
while (reader.Read())
{
invoiceId = reader.GetInt32(0);
// test for first/next invoice
if (invoice == null || previousInvoiceId.Value != invoiceId.Value)
{
// if next invoice, add previous to return list
if (previousInvoiceId.HasValue)
{
// invoice complete, add to return list
returnList.Add(previousInvoiceId.Value, invoice);
}
// add header info to new invoice
invoice = new Model.Account.SalesInvoice(reader.GetBoolean(16));
int invoiceType = reader.GetInt32(1);
invoice.ContactName = reader.GetString(2);
invoice.InvoiceNumber = reader.GetString(3);
invoice.InvoiceDate = reader.GetDateTime(4);
invoice.InvoiceDueDate = reader.GetDateTime(5);
if (!reader.IsDBNull(6)) { invoice.InvoiceReference = reader.GetString(6); }
invoice.InvoiceCurrencyCode = Enum.Parse<Model.Account.CurrencyCode>(reader.GetString(7));
if (!reader.IsDBNull(8)) { invoice.InvoiceTotalAmount = reader.GetDecimal(8); }
bool isComplete = reader.GetBoolean(9);
// set credit note
if (invoice.InvoiceTotalAmount < 0)
{
invoice.IsCreditNote = true;
}
}
// 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))];
invoiceLine.UnitAmount = reader.GetDecimal(13);
invoiceLine.Quantity = 1;
invoiceLine.TaxCode = taxcode[reader.GetByte(14)];
invoiceLine.SetTaxAdjustmentByTaxTotal(reader.GetDecimal(15));
invoice.InvoiceLineList.Add(invoiceLine);
previousInvoiceId = invoiceId.Value;
}
// complete final invoice and add to list
returnList.Add(invoiceId.Value, invoice);
}
}
return returnList;
}
//
// 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)
{
int returnCount = 0;
foreach (var item in updateDictionary)
{
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();
}
}
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)
{
throw new ArgumentException("InvoiceIdList is empty, nothing to delete.");
}
int invoiceToDelete = invoiceIdList.Distinct().Count();
int invoiceEffected = 0;
// delete lines first
Core.Data.Database.SqlWhereBuilder sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
sqlWhereBuilder.In("ExportAccountInvoiceID", invoiceIdList);
int lineCount = DeleteInvoiceExecuteInvoiceLine(sqlWhereBuilder);
// then delete invoice
sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
sqlWhereBuilder.In("ExportAccountInvoiceID", invoiceIdList);
invoiceEffected = DeleteInvoiceExecuteInvoice(sqlWhereBuilder);
if (invoiceEffected == invoiceToDelete)
{
return invoiceEffected;
}
else
{
throw new Exception("Error: "
+ invoiceToDelete + " number invoices requested for deletion, "
+ invoiceEffected + " number invoices effected. Changes rolled back.");
}
}
/// <summary>
/// Helper method Only intended for use with ExecuteInvoice() or ExecuteInvoiceLine()
/// </summary>
/// <param name="sql">the full sql statement</param>
/// <param name="sqlWhereBuilder">instance of the sql where builder helper</param>
/// <returns>Number of row effected (deleted)</returns>
private int DeleteInvoiceExecuteHelper(string sql, Core.Data.Database.SqlWhereBuilder sqlWhereBuilder)
{
// Only intended for ExecuteInvoice() or ExecuteInvoiceLine()
// important checks
if (sqlWhereBuilder.IsSetSqlWhereString == false)
{
throw new ArgumentException("SqlWhereBuilder is not set, set the SqlWhereBuilder before calling this method.");
}
if (sqlWhereBuilder.ParameterListCount == 0)
{
throw new Exception("Parameter list count is zero, this could delete all records in table, operation cancelled");
}
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction; // Assign the shared transaction
sqlWhereBuilder.AddParametersToSqlCommand(cmd);
return cmd.ExecuteNonQuery();
}
}
private int DeleteInvoiceExecuteInvoice(Core.Data.Database.SqlWhereBuilder sqlWhereBuilder)
{
string sql = "DELETE FROM tblExportAccountInvoice WHERE " + sqlWhereBuilder.SqlWhereString;
return DeleteInvoiceExecuteHelper(sql, sqlWhereBuilder);
}
private int DeleteInvoiceExecuteInvoiceLine(Core.Data.Database.SqlWhereBuilder sqlWhereBuilder)
{
string sql = "DELETE FROM tblExportAccountInvoiceLine WHERE " + sqlWhereBuilder.SqlWhereString;
return DeleteInvoiceExecuteHelper(sql, sqlWhereBuilder);
}
}
}

View File

@@ -0,0 +1,713 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using bnhtrade.Core.Model.Amazon;
using Microsoft.Data.SqlClient;
using Microsoft.VisualBasic.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class ImportAmazonRepository : _Base, IImportAmazonRepository
{
Logic.Log.LogEvent _log = new Logic.Log.LogEvent();
public ImportAmazonRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
//
// Read Amazon Settlement Header Information
//
public List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySettlementId(List<string> settlementIdList)
{
if (settlementIdList == null || !settlementIdList.Any())
{ return new List<Model.Import.AmazonSettlementHeader>(); }
return ReadAmazonSettlementHeaders(settlementIdList);
}
public List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySpapiReportId(List<string> spapiReportIdList)
{
if (spapiReportIdList == null || !spapiReportIdList.Any())
{ return new List<Model.Import.AmazonSettlementHeader>(); }
return ReadAmazonSettlementHeaders(null, spapiReportIdList);
}
private List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaders(
List<string> settlementIdList = null, List<string> spapiReportIdList = null, bool filterOutIsProcessed = false,
bool DescendingOrder = false, int? returnTop = null)
{
var returnHeaderList = new List<Model.Import.AmazonSettlementHeader>();
Dictionary<string, int> dicTablePkBySettlementId = new Dictionary<string, int>();
// build the sql string
string sqlString = "SELECT ";
if (returnTop != null)
{
sqlString = sqlString + "TOP " + returnTop.Value + " ";
}
sqlString = sqlString + @"
ImportAmazonSettlementReportID
,[marketplace-name]
,[settlement-id]
,[settlement-start-date]
,[settlement-end-date]
,[deposit-date]
,[total-amount]
,currency
,IsProcessed
,SpapiReportId
FROM tblImportAmazonSettlementReport
WHERE 1 = 1";
if (filterOutIsProcessed)
{
sqlString = sqlString + @"
AND IsProcessed = 0";
}
// build dictionary of parameter and values for settlementid
var dicSettlementIdByParameterString = new Dictionary<string, string>();
if (settlementIdList != null)
{
int count = 0;
foreach (string item in settlementIdList)
{
if (!string.IsNullOrWhiteSpace(item))
{
count = count + 1;
string parameterString = "@settlementId" + count;
dicSettlementIdByParameterString.Add(parameterString, item);
}
}
}
if (dicSettlementIdByParameterString.Any())
{
int count = 0;
foreach (var item in dicSettlementIdByParameterString)
{
count = count + 1;
if (count == 1)
{
sqlString = sqlString + @"
AND ( [settlement-id] = " + item.Key;
}
else
{
sqlString = sqlString + @"
OR [settlement-id] = " + item.Key;
}
}
sqlString = sqlString + " )";
}
// build dictionary of parameter and values for SP-API Report Id
var dicSpapiReportIdByParameterString = new Dictionary<string, string>();
if (spapiReportIdList != null && spapiReportIdList.Any())
{
int count = 0;
foreach (string item in spapiReportIdList)
{
if (!string.IsNullOrWhiteSpace(item))
{
count = count + 1;
string parameterString = "@SpapiReportId" + count;
dicSpapiReportIdByParameterString.Add(parameterString, item);
}
}
}
if (dicSpapiReportIdByParameterString.Any())
{
int count = 0;
foreach (var item in dicSpapiReportIdByParameterString)
{
count = count + 1;
if (count == 1)
{
sqlString = sqlString + @"
AND ( SpapiReportId = " + item.Key;
}
else
{
sqlString = sqlString + @"
OR SpapiReportId = " + item.Key;
}
}
sqlString = sqlString + " )";
}
sqlString = sqlString + @"
ORDER BY [settlement-start-date] ";
if (DescendingOrder) { sqlString = sqlString + " DESC"; }
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sqlString;
cmd.Transaction = _transaction as SqlTransaction;
if (dicSettlementIdByParameterString.Any())
{
foreach (var item in dicSettlementIdByParameterString)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
if (dicSpapiReportIdByParameterString.Any())
{
foreach (var item in dicSpapiReportIdByParameterString)
{
cmd.Parameters.AddWithValue(item.Key, item.Value);
}
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var header = new Model.Import.AmazonSettlementHeader();
int tablePk = reader.GetInt32(0);
if (!reader.IsDBNull(1)) { header.MarketPlace = MarketPlaceEnumExtensions.FromMarketplaceUrl(reader.GetString(1)); }
header.SettlementId = reader.GetString(2);
header.StartDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
header.EndDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
header.DepositDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
header.TotalAmount = reader.GetDecimal(6);
header.CurrencyCode = reader.GetString(7);
header.IsProcessed = reader.GetBoolean(8);
if (!reader.IsDBNull(9)) { header.SpapiReportId = reader.GetString(9); }
// update dictionary
if (!dicTablePkBySettlementId.ContainsKey(header.SettlementId))
{
dicTablePkBySettlementId.Add(header.SettlementId, tablePk);
}
// add header to list
returnHeaderList.Add(header);
}
}
}
return returnHeaderList;
}
//
// Read Amazon Settlement Report
//
/// <summary>
/// Gets Amazon settlement report information from the database.
/// </summary>
/// <returns>Dictionary where key=id and value=settlement</returns>
public Dictionary<int, Model.Import.AmazonSettlement> ReadAmazonSettlements(
List<string> settlementIdList = null, List<string> marketPlaceNameList = null, bool? isProcessed = null,
bool descendingOrder = false, int? returnTop = null )
{
var returnList = new Dictionary<int, Model.Import.AmazonSettlement>();
var whereBuilder = new Data.Database.SqlWhereBuilder();
// build the sql string
string sqlString = "SELECT ";
if (returnTop != null)
{
sqlString = sqlString + "TOP " + returnTop.Value + " ";
}
sqlString = sqlString + @"
tblImportAmazonSettlementReport.ImportAmazonSettlementReportID,
tblImportAmazonSettlementReport.[marketplace-name],
tblImportAmazonSettlementReport.[settlement-id],
tblImportAmazonSettlementReport.[settlement-start-date],
tblImportAmazonSettlementReport.[settlement-end-date],
tblImportAmazonSettlementReport.[deposit-date],
tblImportAmazonSettlementReport.[total-amount],
tblImportAmazonSettlementReport.currency,
tblImportAmazonSettlementReport.IsProcessed,
tblImportAmazonSettlementReport.SpapiReportId,
tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportLineID,
tblImportAmazonSettlementReportLine.[transaction-type],
tblImportAmazonSettlementReportLine.[order-id],
tblImportAmazonSettlementReportLine.[merchant-order-id],
tblImportAmazonSettlementReportLine.[adjustment-id],
tblImportAmazonSettlementReportLine.[shipment-id],
tblImportAmazonSettlementReportLine.[marketplace-name] AS Expr1,
tblImportAmazonSettlementReportLine.[amount-type],
tblImportAmazonSettlementReportLine.[amount-description],
tblImportAmazonSettlementReportLine.amount,
tblImportAmazonSettlementReportLine.currency,
tblImportAmazonSettlementReportLine.[fulfillment-id],
tblImportAmazonSettlementReportLine.[posted-date-time],
tblImportAmazonSettlementReportLine.[order-item-code],
tblImportAmazonSettlementReportLine.[merchant-order-item-id],
tblImportAmazonSettlementReportLine.[merchant-adjustment-item-id],
tblImportAmazonSettlementReportLine.sku,
tblImportAmazonSettlementReportLine.[quantity-purchased],
tblImportAmazonSettlementReportLine.[promotion-id],
tblImportAmazonSettlementReportLine.IsProcessed,
tblImportAmazonSettlementReportLine.ExportAccountInvoiceLineID
FROM tblImportAmazonSettlementReport
INNER JOIN
tblImportAmazonSettlementReportLine
ON tblImportAmazonSettlementReport.ImportAmazonSettlementReportID = tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportID
WHERE 1 = 1 ";
if (isProcessed != null)
{
if (isProcessed.Value == true)
{
sqlString = sqlString + @"
AND tblImportAmazonSettlementReport.IsProcessed = 1";
}
else
{
sqlString = sqlString + @"
AND tblImportAmazonSettlementReport.IsProcessed = 0";
}
}
if (settlementIdList != null && settlementIdList.Any() == true)
{
whereBuilder.In("tblImportAmazonSettlementReport.ImportAmazonSettlementReportID", settlementIdList, "AND");
}
if (marketPlaceNameList != null && marketPlaceNameList.Any() == true)
{
whereBuilder.In("tblImportAmazonSettlementReport.[marketplace-name]", marketPlaceNameList, "AND");
}
sqlString = sqlString + whereBuilder.SqlWhereString;
// add the order by clause(s)
sqlString = sqlString + @"
ORDER BY tblImportAmazonSettlementReport.[marketplace-name] ASC, tblImportAmazonSettlementReport.[settlement-start-date] ";
if (descendingOrder) { sqlString = sqlString + " DESC"; }
else { sqlString = sqlString + " ASC"; }
sqlString = sqlString + ", tblImportAmazonSettlementReport.ImportAmazonSettlementReportID ASC, tblImportAmazonSettlementReportLine.[posted-date-time] ASC, "
+ "tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportLineID ASC;";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sqlString;
cmd.Transaction = _transaction as SqlTransaction;
whereBuilder.AddParametersToSqlCommand(cmd);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int tableId = reader.GetInt32(0);
if (returnList.ContainsKey(tableId) == false)
{
var settlement = new Model.Import.AmazonSettlement();
if (!reader.IsDBNull(1)) { settlement.MarketPlace = MarketPlaceEnumExtensions.FromMarketplaceUrl(reader.GetString(1)); }
settlement.SettlementId = reader.GetString(2);
settlement.StartDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
settlement.EndDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
settlement.DepositDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
settlement.TotalAmount = reader.GetDecimal(6);
settlement.CurrencyCode = reader.GetString(7);
settlement.IsProcessed = reader.GetBoolean(8);
if (!reader.IsDBNull(9)) { settlement.SpapiReportId = reader.GetString(9); }
returnList.Add(tableId, settlement);
}
// add lines to settlement
var line = new Model.Import.AmazonSettlement.SettlementLine();
line.TransactionType = reader.GetString(11);
if (!reader.IsDBNull(12)) { line.OrderId = reader.GetString(12); }
if (!reader.IsDBNull(13)) { line.MerchantOrderId = reader.GetString(13); }
if (!reader.IsDBNull(14)) { line.AdjustmentId = reader.GetString(14); }
if (!reader.IsDBNull(15)) { line.ShipmentId = reader.GetString(15); }
if (!reader.IsDBNull(16)) { line.MarketPlaceName = reader.GetString(16); }
line.AmountType = reader.GetString(17);
line.AmountDescription = reader.GetString(18);
line.Amount = reader.GetDecimal(19);
line.CurrenyCode = reader.GetString(20);
if (!reader.IsDBNull(21)) { line.FulfillmentId = reader.GetString(21); }
line.PostDateTime = DateTime.SpecifyKind(reader.GetDateTime(22), DateTimeKind.Utc);
if (!reader.IsDBNull(23)) { line.OrderItemCode = reader.GetString(23); }
if (!reader.IsDBNull(24)) { line.MerchantOrderItemId = reader.GetString(24); }
if (!reader.IsDBNull(25)) { line.MerchantAdjustmentItemId = reader.GetString(25); }
if (!reader.IsDBNull(26)) { line.Sku = reader.GetString(26); }
if (!reader.IsDBNull(27)) { line.QuantityPurchased = reader.GetInt32(27); }
if (!reader.IsDBNull(28)) { line.PromotionId = reader.GetString(28); }
line.IsProcessed = reader.GetBoolean(29);
if (!reader.IsDBNull(30)) { line.ExportAccountInvoiceLineId = reader.GetInt32(30); }
returnList[tableId].SettlementLineList.Add(line);
}
return returnList;
}
}
}
//
// Update Amazon Settlement Report
//
/// <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)
{
if (settlementIdList == null || !settlementIdList.Any())
{
throw new Exception("Settlement ID list is empty.");
}
string sqlString = @"
UPDATE tblImportAmazonSettlementReport ";
sqlString = sqlString + @"
SET IsProcessed = " + (isProcessed ? "1" : "0");
var whereBuilder = new Data.Database.SqlWhereBuilder();
whereBuilder.In("tblImportAmazonSettlementReport.[settlement-id]", settlementIdList, "WHERE");
sqlString = sqlString + whereBuilder.SqlWhereString;
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sqlString;
cmd.Transaction = _transaction as SqlTransaction;
whereBuilder.AddParametersToSqlCommand(cmd);
return cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Takes a Settlement Report flat file from Amazon and imports it into the database.
/// </summary>
/// <param name="filePath">path to the Amazon report flat file</param>
/// <param name="reportId">The unique Amazon SP-API report id (not settlement id)</param>
/// <returns></returns>
public bool CreateAmazonSettlements(string filePath, string reportId)
{
int settlementReportId = 0;
string settlementRef = "";
bool marketPlaceUpdated = false;
decimal settlementAmount = 0m;
int lineNumber = 2;
int lineSkip = 0;
using (var reader = new StreamReader(filePath))
{
//read file one line at a time and insert data into table if required
// read header and retrive information
string headerRow = reader.ReadLine();
string[] headers = headerRow.Split('\t');
int columnCount = headers.Length;
int indexSettlementId = Array.IndexOf(headers, "settlement-id");
int indexSettlementStartDate = Array.IndexOf(headers, "settlement-start-date");
int indexSettlementEndDate = Array.IndexOf(headers, "settlement-end-date");
int indexDepositDate = Array.IndexOf(headers, "deposit-date");
int indexTotalAmount = Array.IndexOf(headers, "total-amount");
int indexCurrency = Array.IndexOf(headers, "currency");
int indexTransactionType = Array.IndexOf(headers, "transaction-type");
int indexOrderId = Array.IndexOf(headers, "order-id");
int indexMerchantOrderId = Array.IndexOf(headers, "merchant-order-id");
int indexAdjustmentId = Array.IndexOf(headers, "adjustment-id");
int indexShipmentId = Array.IndexOf(headers, "shipment-id");
int indexMarketplaceName = Array.IndexOf(headers, "marketplace-name");
int indexAmountType = Array.IndexOf(headers, "amount-type");
int indexAmountDescription = Array.IndexOf(headers, "amount-description");
int indexAmount = Array.IndexOf(headers, "amount");
int indexFulfillmentId = Array.IndexOf(headers, "fulfillment-id");
// int indexPostedDate = Array.IndexOf(headers, "posted-date");
int indexPostedDateTime = Array.IndexOf(headers, "posted-date-time");
int indexOrderItemCode = Array.IndexOf(headers, "order-item-code");
int indexMerchantOrderItemId = Array.IndexOf(headers, "merchant-order-item-id");
int indexMerchantAdjustmentItemId = Array.IndexOf(headers, "merchant-adjustment-item-id");
int indexSku = Array.IndexOf(headers, "sku");
int indexQuantityPurchased = Array.IndexOf(headers, "quantity-purchased");
int indexPromotionId = Array.IndexOf(headers, "promotion-id");
string currency = "";
string fileRow;
while ((fileRow = reader.ReadLine()) != null)
{
Console.Write("\rParsing record: " + lineNumber);
//split line into array
string[] items = fileRow.Split('\t');
if (items.Length != columnCount)
{
// skip line
lineSkip = lineSkip + 1;
_log.LogWarning(
"Line #" + lineNumber + " skipped due to no enough element in row.",
filePath
);
}
else if (lineNumber == 2)
{
// check if settlement has already been imported
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = "SELECT COUNT(*) FROM tblImportAmazonSettlementReport WHERE [settlement-id]=@settlementId;";
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@settlementId", items[indexSettlementId]);
int recordCount = (int)cmd.ExecuteScalar();
if (recordCount > 0)
{
SetSpapiReportId(items[indexSettlementId], reportId);
_log.LogInformation("Settlement report already imported, skipping...");
return true;
}
}
//set currencyId
//currencyId = GeneralQueries.GetCurrencyId(items[5]);
//set currency
currency = items[indexCurrency];
settlementAmount = decimal.Parse(items[indexTotalAmount].Replace(",", "."));
// insert
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
INSERT INTO tblImportAmazonSettlementReport (
[settlement-id]
,[settlement-start-date]
,[settlement-end-date]
,[deposit-date]
,[total-amount]
,[currency]
,SpapiReportId
)
OUTPUT INSERTED.ImportAmazonSettlementReportID
VALUES (
@settlementId
,@settlementStartDate
,@settlementEndDate
,@depositDate
,@settlementotalAmounttId
,@currency
,@reportId
);";
// add parameters
if (indexSettlementId == -1 || items[indexSettlementId].Length == 0) { cmd.Parameters.AddWithValue("@settlementId", DBNull.Value); }
else
{
settlementRef = items[indexSettlementId];
cmd.Parameters.AddWithValue("@settlementId", settlementRef);
}
var parseDateTime = new Core.Logic.Utilities.DateTime();
if (indexSettlementStartDate == -1 || items[indexSettlementStartDate].Length == 0) { cmd.Parameters.AddWithValue("@settlementStartDate", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@settlementStartDate", parseDateTime.ParseIsoDateTimeString(items[indexSettlementStartDate])); }
if (indexSettlementEndDate == -1 || items[indexSettlementEndDate].Length == 0) { cmd.Parameters.AddWithValue("@settlementEndDate", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@settlementEndDate", parseDateTime.ParseIsoDateTimeString(items[indexSettlementEndDate])); }
if (indexDepositDate == -1 || items[indexDepositDate].Length == 0) { cmd.Parameters.AddWithValue("@depositDate", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@depositDate", parseDateTime.ParseIsoDateTimeString(items[indexDepositDate])); }
if (indexTotalAmount == -1 || items[indexTotalAmount].Length == 0) { cmd.Parameters.AddWithValue("@totalAmount", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@settlementotalAmounttId", settlementAmount); }
if (string.IsNullOrWhiteSpace(reportId)) { cmd.Parameters.AddWithValue("@reportId", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@reportId", reportId); }
cmd.Parameters.AddWithValue("@currency", currency);
//if (currencyId == -1) { sqlCommand.Parameters.AddWithValue("@currencyId", DBNull.Value); }
//else { sqlCommand.Parameters.AddWithValue("@currencyId", currencyId); }
//execute and retrive id
settlementReportId = (int)cmd.ExecuteScalar();
}
}
else
{
//update market place name in main table, if required
if (marketPlaceUpdated == false && settlementReportId > 0 && items[indexMarketplaceName].Length > 1)
{
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
UPDATE tblImportAmazonSettlementReport
SET [marketplace-name]=@MarketplaceName
WHERE ImportAmazonSettlementReportID=@ImportAmazonSettlementReportID;";
cmd.Parameters.AddWithValue("@MarketplaceName", items[indexMarketplaceName]);
cmd.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
cmd.ExecuteNonQuery();
marketPlaceUpdated = true;
}
}
//insert report items
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText =
"INSERT INTO tblImportAmazonSettlementReportLine ( " +
"ImportAmazonSettlementReportID, [transaction-type], [order-id], [merchant-order-id], [adjustment-id], [shipment-id], [marketplace-name], " +
"[amount-type], [amount-description], [currency], [amount], [fulfillment-id], [posted-date-time], [order-item-code], " +
"[merchant-order-item-id], [merchant-adjustment-item-id], [sku], [quantity-purchased], [promotion-id] ) " +
"VALUES ( " +
"@ImportAmazonSettlementReportID, @TransactionType, @orderRef, @merchantOrderRef, @AdjustmentRef, @ShipmentRef, @MarketplaceName, " +
"@AmountType, @AmountDescription, @currency, @Amount, @FulfillmentRef, @PostedDateTimeUTC, @OrderItemCode, " +
"@MerchantOrderItemRef, @MerchantAdjustmentItemRef, @SkuNumber, @QuantityPurchased, @PromotionRef );";
// add parameters
cmd.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
cmd.Parameters.AddWithValue("@currency", currency);
if (indexTransactionType == -1 || items[indexTransactionType].Length == 0) { cmd.Parameters.AddWithValue("@TransactionType", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@TransactionType", items[indexTransactionType]); }
if (indexOrderId == -1 || items[indexOrderId].Length == 0) { cmd.Parameters.AddWithValue("@orderRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@orderRef", items[indexOrderId]); }
if (indexMerchantOrderId == -1 || items[indexMerchantOrderId].Length == 0) { cmd.Parameters.AddWithValue("@merchantOrderRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@merchantOrderRef", items[indexMerchantOrderId]); }
if (indexAdjustmentId == -1 || items[indexAdjustmentId].Length == 0) { cmd.Parameters.AddWithValue("@AdjustmentRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@AdjustmentRef", items[indexAdjustmentId]); }
if (indexShipmentId == -1 || items[indexShipmentId].Length == 0) { cmd.Parameters.AddWithValue("@ShipmentRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@ShipmentRef", items[indexShipmentId]); }
if (indexMarketplaceName == -1 || items[indexMarketplaceName].Length == 0) { cmd.Parameters.AddWithValue("@MarketplaceName", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@MarketplaceName", items[indexMarketplaceName]); }
if (indexAmountType == -1 || items[indexAmountType].Length == 0) { cmd.Parameters.AddWithValue("@AmountType", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@AmountType", items[indexAmountType]); }
if (indexAmountDescription == -1 || items[indexAmountDescription].Length == 0) { cmd.Parameters.AddWithValue("@AmountDescription", DBNull.Value); }
else
{
string amountDescription = items[indexAmountDescription];
if (amountDescription.Length > 100) { amountDescription = amountDescription.Substring(0, 100); }
cmd.Parameters.AddWithValue("@AmountDescription", amountDescription);
}
if (indexAmount == -1 || items[indexAmount].Length == 0) { cmd.Parameters.AddWithValue("@Amount", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@Amount", decimal.Parse(items[indexAmount].Replace(",", "."))); }
if (indexFulfillmentId == -1 || items[indexFulfillmentId].Length == 0) { cmd.Parameters.AddWithValue("@FulfillmentRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@FulfillmentRef", items[indexFulfillmentId]); }
if (indexPostedDateTime == -1 || items[indexPostedDateTime].Length == 0) { cmd.Parameters.AddWithValue("@PostedDateTimeUTC", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@PostedDateTimeUTC", new Logic.Utilities.DateTime().ParseIsoDateTimeString(items[indexPostedDateTime])); }
if (indexOrderItemCode == -1 || items[indexOrderItemCode].Length == 0) { cmd.Parameters.AddWithValue("@OrderItemCode", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@OrderItemCode", long.Parse(items[indexOrderItemCode])); }
if (indexMerchantOrderItemId == -1 || items[indexMerchantOrderItemId].Length == 0) { cmd.Parameters.AddWithValue("@MerchantOrderItemRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@MerchantOrderItemRef", long.Parse(items[indexMerchantOrderItemId])); }
if (indexMerchantAdjustmentItemId == -1 || items[indexMerchantAdjustmentItemId].Length == 0) { cmd.Parameters.AddWithValue("@MerchantAdjustmentItemRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@MerchantAdjustmentItemRef", items[indexMerchantAdjustmentItemId]); }
if (indexSku == -1 || items[indexSku].Length == 0) { cmd.Parameters.AddWithValue("@SkuNumber", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@SkuNumber", items[indexSku]); }
if (indexQuantityPurchased == -1 || items[indexQuantityPurchased].Length == 0) { cmd.Parameters.AddWithValue("@QuantityPurchased", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@QuantityPurchased", int.Parse(items[indexQuantityPurchased])); }
if (indexPromotionId == -1 || items[indexPromotionId].Length == 0) { cmd.Parameters.AddWithValue("@PromotionRef", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@PromotionRef", items[indexPromotionId]); }
cmd.ExecuteNonQuery();
}
}
lineNumber = lineNumber + 1;
}
}
//final check - settlement amount matches sum of inserted settlement lines
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.Transaction = _transaction as SqlTransaction;
cmd.CommandText = @"
SELECT Sum(tblImportAmazonSettlementReportLine.amount) AS SumOfAmount
FROM tblImportAmazonSettlementReportLine
WHERE ImportAmazonSettlementReportID=@ImportAmazonSettlementReportID;";
decimal sumOfAmount = -1.12345m;
cmd.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
sumOfAmount = (decimal)cmd.ExecuteScalar();
if (sumOfAmount != settlementAmount)
{
_log.LogError("Error importing settlement id'" + settlementRef + "'. Sum of inserted settlement lines (" + sumOfAmount +
") does not match settlement amount (" + settlementAmount + ").");
return false;
}
}
Console.Write("\r");
_log.LogInformation((lineNumber - (2 + lineSkip)) + " total settlement items inserted");
if (lineSkip > 0)
{
_log.LogError(lineSkip + " total line(s) where skipped due to insufficent number of cells on row");
}
return true;
}
public int SetSpapiReportId(string settlementId, string spapiReportId)
{
string sqlString = @"
UPDATE
tblImportAmazonSettlementReport
SET
SpapiReportId = @spapiReportId
WHERE
[settlement-id] = @settlementId;";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sqlString;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@spapiReportId", spapiReportId);
cmd.Parameters.AddWithValue("@settlementId", settlementId);
return cmd.ExecuteNonQuery();
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using bnhtrade.Core.Data.Database.Repository.Interface;
namespace bnhtrade.Core.Data.Database.Repository.Implementation
{
internal class SequenceGenerator : _Base, ISequenceGenerator
{
public SequenceGenerator (IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public int GetNext(string sequenceName)
{
if (string.IsNullOrWhiteSpace(sequenceName))
{
throw new Exception("Sequence name is null or whitespace.");
}
string sql = $"SELECT NEXT VALUE FOR {sequenceName};";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
object obj = cmd.ExecuteScalar();
try
{
return Convert.ToInt32(obj);
}
catch (Exception ex)
{
// Provide more context in the exception
throw new InvalidOperationException($"Error retrieving next value for sequence '{sequenceName}'. " +
$"Raw value: '{obj}'. Inner exception: {ex.Message}", ex);
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
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
{
abstract class _Base
{
protected readonly IDbConnection _connection;
protected readonly IDbTransaction _transaction;
public _Base(IDbConnection connection, IDbTransaction transaction)
{
_connection = connection ?? throw new ArgumentNullException(nameof(connection));
_transaction = transaction; // Transaction can be null if not needed for read-only ops
// But for NEXT VALUE FOR, it implies a modification/dependency within a transaction
}
}
}

View File

@@ -0,0 +1,131 @@
using bnhtrade.Core.Data.Database._BoilerPlate;
using bnhtrade.Core.Data.Database.Repository.Interface;
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentOutbound;
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 _BoilerPlate : _Base, _IBoilerPlate
{
public _BoilerPlate(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
{
}
public Dictionary<int, string> SelectByList(List<string> selectList)
{
var returnList = new Dictionary<int, string>();
// check input list for items
if (selectList == null)
{
throw new ArgumentNullException("Method argument cannot be null");
}
// build SQL string
string sql = @"
SELECT
column01
,column02
FROM
tblTable
";
var sqlwhere = new Data.Database.SqlWhereBuilder();
sqlwhere.In("column03", selectList, "WHERE");
sql = 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())
{
int id = reader.GetInt32(0);
string data = reader.GetString(1);
returnList.Add(id, data);
}
}
}
return returnList;
}
public int Insert()
{
string sql = @"
INSERT INTO tblTable (
column01
,column02
,column03
,column04
)
OUTPUT INSERTED.TablePk
VALUES (
@value01
,@value02
,@value03
,@value04
)
";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
int newId = (int)cmd.ExecuteScalar();
return newId;
}
}
public int Update()
{
string sql = @"
UPDATE
tblTable
SET
column01 = @value01
column02 = @value02
column03 = @value03
column04 = @value04
WHERE
column05 = @value05
";
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
{
cmd.CommandText = sql;
cmd.Transaction = _transaction as SqlTransaction;
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
int recordsEffected = cmd.ExecuteNonQuery();
return recordsEffected;
}
}
}
}

View File

@@ -0,0 +1,17 @@
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 ICurrencyRepository
{
public decimal? ReadExchangeRate(Model.Account.CurrencyCode currencyCode, DateTime date);
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRate(List<Model.Account.CurrencyCode> currencyCodeList = null, DateTime date = default(DateTime));
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRateLatest(List<Model.Account.CurrencyCode> currencyCodeList = null);
public int InsertExchangeRate(int exchangeRateSource, Model.Account.CurrencyCode currencyCode,
decimal currencyUnitsPerGbp, DateTime periodStartUtc, DateTime periodEnd, bool checkOverride = false);
}
}

View File

@@ -0,0 +1,18 @@
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 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);
}
}

View File

@@ -0,0 +1,25 @@
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);
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace bnhtrade.Core.Data.Database.Repository.Interface
{
internal interface ISequenceGenerator
{
int GetNext(string sequenceName);
}
}

View File

@@ -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 _IBoilerPlate
{
internal Dictionary<int, string> SelectByList(List<string> selectList);
internal int Insert();
internal int Update();
}
}

View File

@@ -1,7 +1,7 @@
using FikaAmazonAPI.AmazonSpApiSDK.Models.ProductPricing;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -22,11 +22,11 @@ namespace bnhtrade.Core.Data.Database.Sku
var dbTax = new Data.Database.Account.ReadTaxCode();
var taxCodeList = dbTax.GetByTaxCodeId(new List<int> { accountTaxCodeId });
if (!taxCodeList.Any())
if (taxCodeList.ContainsKey(accountTaxCodeId) == false)
{
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " doesn't exist!");
}
else if (taxCodeList[0].IsValidOnIncome == false)
else if (taxCodeList[accountTaxCodeId].IsValidOnIncome == false)
{
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " is not a valid type for an SKU.");
}

View File

@@ -5,6 +5,7 @@ using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
namespace bnhtrade.Core.Data.Database
{
@@ -12,9 +13,12 @@ namespace bnhtrade.Core.Data.Database
/// Step 1: Call the methods for each where clause you want to create. This can be done multiple times to create an sql where string. Pay attention
/// to the prefixes that you'll require between each where clause, as each time a method is called the sql statement will be appended to the previous sql
/// string.
///
/// Step 2: Appened the created sql string to your sql statement, NB the WHERE statemet is not included by default.
///
/// Step 3: Once you've created your sql command object, add the parameters to it using the method contained within this class.
/// STep 4: exceute your sql commend.
///
/// Step 4: exceute your sql commend.
/// </summary>
public class SqlWhereBuilder
{
@@ -44,6 +48,21 @@ namespace bnhtrade.Core.Data.Database
public Dictionary<string, object> ParameterList { get; private set; }
public int ParameterListCount
{
get
{
if (ParameterList == null || ParameterList.Any() == false)
{
return 0;
}
else
{
return ParameterList.Count();
}
}
}
/// <summary>
/// Initialises the class
/// </summary>
@@ -83,7 +102,7 @@ namespace bnhtrade.Core.Data.Database
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="phraseList">List of phrases to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void LikeAnd(string columnReference, List<string> phraseList, string wherePrefix = null)
public void LikeAnd(string columnReference, IEnumerable<string> phraseList, string wherePrefix = null)
{
Like(columnReference, phraseList, true, wherePrefix);
}
@@ -94,12 +113,12 @@ namespace bnhtrade.Core.Data.Database
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="phraseList">List of phrases to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void LikeOr(string columnReference, List<string> phraseList, string wherePrefix = null)
public void LikeOr(string columnReference, IEnumerable<string> phraseList, string wherePrefix = null)
{
Like(columnReference, phraseList, false, wherePrefix);
}
private void Like(string columnReference, List<string> phraseList, bool isAnd, string wherePrefix = null)
private void Like(string columnReference, IEnumerable<string> phraseList, bool isAnd, string wherePrefix = null)
{
if (phraseList == null || !phraseList.Any())
{
@@ -107,7 +126,7 @@ namespace bnhtrade.Core.Data.Database
}
// ensure no values are repeated
var distinctList = phraseList.ToList();
var distinctList = phraseList.Distinct().ToList();
// clean the list
for (int i = 0; i < distinctList.Count; i++)
@@ -166,7 +185,7 @@ namespace bnhtrade.Core.Data.Database
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, List<string> orValueList, string wherePrefix = null)
public void In(string columnReference, IEnumerable<object> orValueList, string wherePrefix = null)
{
if (orValueList == null || !orValueList.Any())
{
@@ -208,19 +227,19 @@ namespace bnhtrade.Core.Data.Database
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, List<int> orValueList, string wherePrefix = null)
public void In(string columnReference, IEnumerable<string> orValueList, string wherePrefix = null)
{
var stringList = new List<string>();
var objectList = new List<object>();
if (orValueList != null || !orValueList.Any())
if (orValueList != null && orValueList.Any())
{
foreach (int value in orValueList)
foreach (string value in orValueList)
{
stringList.Add(value.ToString());
objectList.Add(value.ToString());
}
}
In(columnReference, stringList, wherePrefix);
In(columnReference, objectList, wherePrefix);
}
/// <summary>
@@ -229,19 +248,55 @@ namespace bnhtrade.Core.Data.Database
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, List<uint> orValueList, string wherePrefix = null)
public void In(string columnReference, IEnumerable<int> orValueList, string wherePrefix = null)
{
var stringList = new List<string>();
var objectList = new List<object>();
if (orValueList != null || !orValueList.Any())
if (orValueList != null && orValueList.Any())
{
foreach (uint value in orValueList)
foreach (var value in orValueList)
{
stringList.Add(value.ToString());
objectList.Add(value.ToString());
}
}
In(columnReference, stringList, wherePrefix);
In(columnReference, objectList, wherePrefix);
}
/// <summary>
/// Append an 'In' statement and parameter list to the class properties
/// </summary>
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
/// <param name="orValueList">List of values to test in condition statement</param>
/// <param name="wherePrefix">Optional prefix that gets added to the sql string result</param>
public void In(string columnReference, IEnumerable<uint> orValueList, string wherePrefix = null)
{
var objectList = new List<object>();
if (orValueList != null && orValueList.Any())
{
foreach (var value in orValueList)
{
objectList.Add(value.ToString());
}
}
In(columnReference, objectList, wherePrefix);
}
public void In(string columnReference, IEnumerable<DateTime> orValueList, string wherePrefix = null)
{
var objectList = new List<object>();
if (orValueList != null && orValueList.Any())
{
foreach(var value in orValueList)
{
objectList.Add(value.ToString());
}
}
In(columnReference, objectList, wherePrefix);
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Configuration;
namespace bnhtrade.Core.Data.Database.UnitOfWork
{
internal class Connection
{
//protected readonly string SqlConnectionString;
private Model.Credentials.bnhtradeDB _dbCredentials;
protected string SqlConnectionString
{
get { return _dbCredentials.ConnectionString; }
}
public Connection()
{
var config = new Config().GetConfiguration();
// attempt to retrive credentials from app.local.config
try
{
string dataSource = config.AppSettings.Settings["DbDataSource"].Value;
string userId = config.AppSettings.Settings["DbUserId"].Value;
string pass = config.AppSettings.Settings["DbUserPassword"].Value;
// check
if (string.IsNullOrEmpty(dataSource))
{
throw new ArgumentException("Could not retrive 'DbDataSource' from config file");
}
else if (string.IsNullOrEmpty(userId))
{
throw new ArgumentException("Could not retrive 'DbUserId' from config file");
}
else if (string.IsNullOrEmpty(pass))
{
throw new ArgumentException("Could not retrive 'DbUserPassword' from config file");
}
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
this._dbCredentials = dbCredentials;
}
catch (Exception ex)
{
throw new Exception("Unable to retirve DB credentials: " + ex.Message);
}
}
}
}

View File

@@ -0,0 +1,23 @@
using bnhtrade.Core.Data.Database.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database.UnitOfWork
{
internal interface IUnitOfWork : IDisposable
{
// Properties for repositories, add here for each repository
public ICurrencyRepository CurrencyRepository { get; }
IExportInvoiceRepository ExportInvoiceRepository { get; }
IImportAmazonRepository ImportAmazonRepository { get; }
ISequenceGenerator SequenceGenerator { get; }
// Methods to manage the transaction
void Commit();
void Rollback();
}
}

View File

@@ -0,0 +1,136 @@
using bnhtrade.Core.Data.Database.Repository.Implementation;
using bnhtrade.Core.Data.Database.Repository.Interface;
using bnhtrade.Core.Data.Database.UnitOfWork;
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.UnitOfWork
{
internal class UnitOfWork : Connection, IUnitOfWork
{
private IDbConnection _connection;
private IDbTransaction _transaction;
private bool _disposed;
// Private field for lazy loading, add here for each repository
private ICurrencyRepository _currencyRepository;
private IExportInvoiceRepository _exportInvoiceRepository;
private IImportAmazonRepository _importAmazonRepository;
private ISequenceGenerator _sequenceGenerator;
public UnitOfWork()
{
_connection = new SqlConnection(this.SqlConnectionString);
_connection.Open();
_transaction = _connection.BeginTransaction();
}
// Properties for repositories, add here for each repository
public ICurrencyRepository CurrencyRepository
{
get
{
if (_currencyRepository == null)
{
_currencyRepository = new CurrencyRepository(_connection, _transaction);
}
return _currencyRepository;
}
}
public IExportInvoiceRepository ExportInvoiceRepository
{
get
{
if (_exportInvoiceRepository == null)
{
_exportInvoiceRepository = new ExportInvoiceRepository(_connection, _transaction);
}
return _exportInvoiceRepository;
}
}
public IImportAmazonRepository ImportAmazonRepository
{
get
{
if (_importAmazonRepository == null)
{
_importAmazonRepository = new ImportAmazonRepository(_connection, _transaction);
}
return _importAmazonRepository;
}
}
public ISequenceGenerator SequenceGenerator
{
get
{
if (_sequenceGenerator == null)
{
_sequenceGenerator = new SequenceGenerator(_connection, _transaction);
}
return _sequenceGenerator;
}
}
public void Commit()
{
try
{
_transaction.Commit();
}
catch
{
_transaction.Rollback();
throw;
}
finally
{
Dispose();
}
}
public void Rollback()
{
_transaction.Rollback();
Dispose();
}
// IDisposable implementation (ensure proper disposal of connection and transaction)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose the transaction first
if (_transaction != null)
{
_transaction.Dispose();
_transaction = null;
}
// Then close and dispose the connection
if (_connection != null)
{
_connection.Close();
_connection.Dispose();
_connection = null;
}
}
_disposed = true;
}
}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Data.Database._BoilerPlate
{
class ClassFromSql
{
/* copy the following code in SSMS query, set variables and execute
DECLARE @TableName VARCHAR(MAX) = 'tblOrder' -- Replace 'tblOrder' with your table name
DECLARE @TableSchema VARCHAR(MAX) = NULL -- If required, replace NULL with your schema name i.e. 'Markets'
DECLARE @result varchar(max) = ''
SET @result = @result + 'using System;' + CHAR(13) + CHAR(13)
IF (@TableSchema IS NOT NULL)
BEGIN
SET @result = @result + 'namespace ' + @TableSchema + CHAR(13) + '{' + CHAR(13)
END
SET @result = @result + 'public class ' + @TableName + CHAR(13) + '{'
SELECT
@result = @result + CHAR(13)
+ ' public ' + ColumnType + ' ' + ColumnName + ' { get; set; } '
FROM (SELECT
c.COLUMN_NAME AS ColumnName,
CASE c.DATA_TYPE
WHEN 'bigint' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'Int64?'
ELSE 'Int64'
END
WHEN 'binary' THEN 'Byte[]'
WHEN 'bit' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'bool?'
ELSE 'bool'
END
WHEN 'char' THEN 'string'
WHEN 'date' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'DateTime?'
ELSE 'DateTime'
END
WHEN 'datetime' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'DateTime?'
ELSE 'DateTime'
END
WHEN 'datetime2' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'DateTime?'
ELSE 'DateTime'
END
WHEN 'datetimeoffset' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'DateTimeOffset?'
ELSE 'DateTimeOffset'
END
WHEN 'decimal' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'decimal?'
ELSE 'decimal'
END
WHEN 'float' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'Single?'
ELSE 'Single'
END
WHEN 'image' THEN 'Byte[]'
WHEN 'int' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'int?'
ELSE 'int'
END
WHEN 'money' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'decimal?'
ELSE 'decimal'
END
WHEN 'nchar' THEN 'string'
WHEN 'ntext' THEN 'string'
WHEN 'numeric' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'decimal?'
ELSE 'decimal'
END
WHEN 'nvarchar' THEN 'string'
WHEN 'real' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'Double?'
ELSE 'Double'
END
WHEN 'smalldatetime' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'DateTime?'
ELSE 'DateTime'
END
WHEN 'smallint' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'Int16?'
ELSE 'Int16'
END
WHEN 'smallmoney' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'decimal?'
ELSE 'decimal'
END
WHEN 'text' THEN 'string'
WHEN 'time' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'TimeSpan?'
ELSE 'TimeSpan'
END
WHEN 'timestamp' THEN 'Byte[]'
WHEN 'tinyint' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'Byte?'
ELSE 'Byte'
END
WHEN 'uniqueidentifier' THEN CASE C.IS_NULLABLE
WHEN 'YES' THEN 'Guid?'
ELSE 'Guid'
END
WHEN 'varbinary' THEN 'Byte[]'
WHEN 'varchar' THEN 'string'
ELSE 'Object'
END AS ColumnType,
c.ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME = @TableName
AND ISNULL(@TableSchema, c.TABLE_SCHEMA) = c.TABLE_SCHEMA) t
ORDER BY t.ORDINAL_POSITION
SET @result = @result + CHAR(13)
SET @result = @result + '}' + CHAR(13)
IF (@TableSchema IS NOT NULL)
BEGIN
SET @result = @result + CHAR(13) + '}'
END
PRINT @result
*/
}
class ourputy
{
}
}

View File

@@ -0,0 +1,198 @@
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._BoilerPlate
{
internal class Sql
{
private string SqlConnectionString = "";
internal List<string> Select()
{
var returnList = new List<string>();
string sql = @"
SELECT
column01
,column02
,column03
,column04
FROM tblTable
WHERE
column01 = @value01
OR column01 = @value02
OR column01 = @value03
OR column01 = @value04; ";
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
returnList.Add("");
}
}
}
}
return returnList;
}
internal string SelectByList(List<string> stringList)
{
// check input list for items
if (stringList == null || !stringList.Any())
{
return null;
}
// build SQL string
string sqlString = @"
SELECT
value01
,value02
FROM
tblTable
WHERE
";
var parameterValueList = new List<Tuple<string, string>>();
foreach (var item in stringList)
{
if (!string.IsNullOrWhiteSpace(item))
{
int count = parameterValueList.Count;
var parameterValue = new Tuple<string, string>("@parameter" + count, item);
parameterValueList.Add(parameterValue);
if (count == 0)
{
sqlString = sqlString + @"
value01 = " + parameterValue.Item1;
}
else
{
sqlString = sqlString + @"
OR value01 = " + parameterValue.Item1;
}
}
}
if (parameterValueList.Count == 0)
{
return null;
}
// execute query and build result list
var skuTaxCodeList = new List<Tuple<string, string>>();
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
foreach (var item in parameterValueList)
{
cmd.Parameters.AddWithValue(item.Item1, item.Item2);
}
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
return null;
}
while (reader.Read())
{
// read data and build return object
}
}
}
}
return "Complete"; // return object
}
internal void Insert()
{
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblTable (
column01
,column02
,column03
,column04
)
OUTPUT INSERTED.TablePk
VALUES (
@value01
,@value02
,@value03
,@value04
)
", conn))
{
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
int tablePk = (int)cmd.ExecuteScalar();
}
}
scope.Complete();
}
}
internal void Update()
{
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(@"
UPDATE
tblTable
SET
column01 = @value01
column02 = @value02
column03 = @value03
column04 = @value04
WHERE
column05 = @value05
", conn))
{
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
cmd.ExecuteNonQuery();
}
}
scope.Complete();
}
}
}
}

View File

@@ -0,0 +1,94 @@
using bnhtrade.Core.Data.Database;
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._BoilerPlate
{
internal class xxxxxxxYourClassNameHerexxxxxxxx : Connection
{
private SqlWhereBuilder sqlBuilder;
/// <summary>
/// Results filter
/// </summary>
public List<int> ColumnTitle1List { get; set; }
/// <summary>
/// Searches for the specificed phases within the item description. Uses the LIKE AND sql function
/// </summary>
public List<string> ColumnTitle2List { get; set; }
public xxxxxxxYourClassNameHerexxxxxxxx()
{
Init();
}
public void Init()
{
sqlBuilder = new SqlWhereBuilder();
ColumnTitle1List = new List<int>();
ColumnTitle2List = new List<string>();
}
/// <summary>
///
/// </summary>
/// <returns>Dictionary were key is the table primary key</returns>
public Dictionary<int, string> Read()
{
// create the return (emptyP list) here
var returnList = new Dictionary<int, string>();
sqlBuilder.Init();
//build sql query
string sql = @"
SELECT item1, item2, item3
FROM tblPurchaseLine
WHERE 1 = 1 ";
// build the where statments
if (ColumnTitle1List.Any())
{
sqlBuilder.In("xxxxxxxxxxxxxxColumnTitle1xxxxxxxxxxxxxxxxxx", ColumnTitle1List, "AND");
}
if (ColumnTitle2List.Any())
{
sqlBuilder.In("xxxxxxxxxxxxxxColumnTitle2xxxxxxxxxxxxxxxxxx", ColumnTitle2List, "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)
{
while (reader.Read())
{
// read from db and create object
// and add to return list
}
}
}
}
}
// all done, return the list here
return returnList;
}
}
}