mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-03-19 06:27:15 +00:00
feature exchange rate update automation
Automated downloading exchange rates from HMRC and updating the database. Added function call to the console and form applications. Also added a form to show the console output in form application.
This commit is contained in:
@@ -54,8 +54,7 @@ namespace bnhtrade.ComTypeLib
|
||||
public int CurrencyExchangeRateInsert(ConnectionCredential sqlConnCred, int exchangeRateSource, string currencyCode,
|
||||
[MarshalAs(UnmanagedType.Currency)] decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
|
||||
{
|
||||
return new Core.Logic.Account.Currency().CurrencyExchangeRateInsert(exchangeRateSource, currencyCode,
|
||||
currencyUnitsPerGbp, periodStart, periodEnd, checkOverride);
|
||||
throw new Exception("This function has been retired, now handled by nightly routines");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
// currency conversion
|
||||
if (currencyCode != "GBP")
|
||||
{
|
||||
amount = new Data.Database.Account.Currency().CurrencyConvertToGbp(currencyCode, amount, entryDate);
|
||||
amount = new Logic.Account.Currency().CurrencyConvertToGbp(currencyCode, amount, entryDate);
|
||||
}
|
||||
|
||||
// ensure decimal is rounded
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
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
|
||||
{
|
||||
public decimal CurrencyConvertToGbp(string currencyCode, decimal amount, DateTime conversionDate)
|
||||
/// <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)
|
||||
{
|
||||
if (currencyCode == "GBP" || amount == 0M)
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
if (currencyCode.Length != 3)
|
||||
{
|
||||
throw new Exception("Invalid currency code '" + currencyCode + "'");
|
||||
}
|
||||
|
||||
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
@@ -32,145 +31,209 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
|
||||
cmd.Parameters.AddWithValue("@conversionDate", conversionDate);
|
||||
cmd.Parameters.AddWithValue("@conversionDate", date);
|
||||
|
||||
object result = cmd.ExecuteScalar();
|
||||
if (result != null)
|
||||
{
|
||||
return amount / Convert.ToDecimal(result);
|
||||
}
|
||||
}
|
||||
|
||||
// return reason for no record found
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT CurrencyUnitsPerGBP
|
||||
FROM tblAccountExchangeRate
|
||||
WHERE CurrencyCode=@currencyCode
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
|
||||
|
||||
object result = cmd.ExecuteScalar();
|
||||
if (result == null)
|
||||
{
|
||||
throw new Exception("Currency code '" + currencyCode + "' does not exist in Exchange Rate table");
|
||||
return Convert.ToDecimal(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Date range for " + currencyCode + " " + conversionDate.ToShortDateString() + " " +
|
||||
conversionDate.ToLongTimeString() + "' does not exist in Exchange Rate table");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int CurrencyExchangeRateInsert(int exchangeRateSource, string currencyCode,
|
||||
decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
|
||||
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);
|
||||
periodStart = DateTime.SpecifyKind(periodStart, DateTimeKind.Utc);
|
||||
periodEnd = DateTime.SpecifyKind(periodEnd, DateTimeKind.Utc);
|
||||
|
||||
// CHECKS
|
||||
// HMRC source only
|
||||
if (exchangeRateSource != 1)
|
||||
{
|
||||
throw new Exception("Function does not currently accept exchange rates from sources other than HMRC");
|
||||
}
|
||||
// currency code upper case only
|
||||
currencyCode = currencyCode.ToUpper();
|
||||
if (currencyCode.Length != 3)
|
||||
{
|
||||
throw new Exception("Invalid currency code '" + currencyCode + "'");
|
||||
}
|
||||
|
||||
if (periodEnd <= periodStart)
|
||||
if (periodEnd <= periodStartUtc)
|
||||
{
|
||||
throw new Exception("Invalid date period.");
|
||||
}
|
||||
|
||||
if (checkOverride == false && (periodEnd - periodStart).Days > 31)
|
||||
if (checkOverride == false && (periodEnd - periodStartUtc).Days > 31)
|
||||
{
|
||||
throw new Exception("Date period is greater than 31 days.");
|
||||
}
|
||||
|
||||
// retirve previous data
|
||||
// make the insert
|
||||
DateTime? periodEndLast = null;
|
||||
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT Max(tblAccountExchangeRate.EndDate) AS MaxOfEndDate
|
||||
FROM tblAccountExchangeRate
|
||||
WHERE (((tblAccountExchangeRate.CurrencyCode) = @currencyCode))
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
// currency code not existing
|
||||
if (obj == DBNull.Value && checkOverride == false)
|
||||
{
|
||||
throw new Exception("Currency code '" + currencyCode + "' does not exist in table");
|
||||
}
|
||||
// currency code exists
|
||||
else
|
||||
{
|
||||
periodEndLast = DateTime.SpecifyKind(Convert.ToDateTime(obj), DateTimeKind.Utc);
|
||||
|
||||
if (periodStart != periodEndLast)
|
||||
{
|
||||
throw new Exception("Invalid period start date -- must equal previous period end-date.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// retrive previous exchange rate and check
|
||||
decimal currencyUnitsPerGbpLast = 0;
|
||||
if (periodEndLast != null)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT tblAccountExchangeRate.AccountExchangeRateID, tblAccountExchangeRate.CurrencyUnitsPerGBP
|
||||
FROM tblAccountExchangeRate
|
||||
WHERE (tblAccountExchangeRate.EndDate = @periodEndLast)
|
||||
AND (CurrencyCode = @currencyCode);
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@periodEndLast", periodEndLast);
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
currencyUnitsPerGbpLast = reader.GetDecimal(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Error that shouldn't happen! Check code @ 5129f3e6-2f7e-4883-bc73-b317d8fa4050");
|
||||
}
|
||||
// error if >1 line
|
||||
if (reader.Read())
|
||||
{
|
||||
string errText = "Multiple lines in currency exchange table for '" + currencyCode + "' where [EndDate]=" + periodEndLast.ToString();
|
||||
new Logic.Log.LogEvent().LogError(errText);
|
||||
throw new Exception(errText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check difference between current and previous exchange rates isn't too great
|
||||
if (checkOverride == false &&
|
||||
(currencyUnitsPerGbpLast > (currencyUnitsPerGbp * 1.05m) || currencyUnitsPerGbpLast < (currencyUnitsPerGbp * 0.95m))
|
||||
)
|
||||
{
|
||||
throw new Exception("Difference between supplied and previous exchange rates is greater than 5%");
|
||||
}
|
||||
|
||||
// MAKE THE INSERT
|
||||
int recordId = 0;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAccountExchangeRate (ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate)
|
||||
@@ -179,9 +242,9 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@exchangeRateSource", exchangeRateSource);
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
|
||||
cmd.Parameters.AddWithValue("@currencyUnitsPerGbp", currencyUnitsPerGbp);
|
||||
cmd.Parameters.AddWithValue("@periodStart", periodStart);
|
||||
cmd.Parameters.AddWithValue("@periodStart", periodStartUtc);
|
||||
cmd.Parameters.AddWithValue("@periodEnd", periodEnd);
|
||||
|
||||
recordId = (int)cmd.ExecuteScalar();
|
||||
|
||||
@@ -8,14 +8,22 @@ namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the date bnhtrade started trading, UK time (datetime kind unspecified).
|
||||
/// </summary>
|
||||
/// <returns>The UK date and time the business started (datetime kind unspecified)</returns>
|
||||
public static DateTime GetBusinessStartUk()
|
||||
{
|
||||
return new Logic.Utilities.DateTime().ConvertUtcToUk(GetBusinessStartUtc());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date bnhtrade started trading.
|
||||
/// Gets the date bnhtrade started trading, as UTC time
|
||||
/// </summary>
|
||||
/// <returns>Date and time</returns>
|
||||
/// <returns>The UTC date and time the business started (datetime kind UTC)</returns>
|
||||
public static DateTime GetBusinessStartUtc()
|
||||
{
|
||||
DateTime businessStart = new DateTime(2014, 09, 01);
|
||||
DateTime businessStart = new DateTime(2014, 08, 31, 23, 00, 00); // 2014-09-01 uk date time
|
||||
return DateTime.SpecifyKind(businessStart, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
|
||||
@@ -146,16 +146,16 @@ namespace bnhtrade.Core.Data.Database.Import
|
||||
sqlCommand.Parameters.AddWithValue("@settlementId", settlementRef);
|
||||
}
|
||||
|
||||
var parseDateTime = new Core.Logic.Utilities.DateTimeParse();
|
||||
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.ParseMwsReportDateTime(items[indexSettlementStartDate])); }
|
||||
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.ParseMwsReportDateTime(items[indexSettlementEndDate])); }
|
||||
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.ParseMwsReportDateTime(items[indexDepositDate])); }
|
||||
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); }
|
||||
@@ -245,7 +245,7 @@ namespace bnhtrade.Core.Data.Database.Import
|
||||
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.DateTimeParse().ParseMwsReportDateTime(items[indexPostedDateTime])); }
|
||||
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])); }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -53,7 +54,19 @@ namespace bnhtrade.Core.Data.Database
|
||||
ParameterList = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public void AddParametersToSqlCommand(SqlCommand cmd)
|
||||
// delete this once all references use the new Microsoft.Data.SqlClient
|
||||
public void AddParametersToSqlCommand(System.Data.SqlClient.SqlCommand cmd)
|
||||
{
|
||||
if (ParameterList != null)
|
||||
{
|
||||
foreach (var item in ParameterList)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddParametersToSqlCommand(Microsoft.Data.SqlClient.SqlCommand cmd)
|
||||
{
|
||||
if (ParameterList != null)
|
||||
{
|
||||
|
||||
@@ -1,23 +1,200 @@
|
||||
using System;
|
||||
using FikaAmazonAPI.ConstructFeed.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class Currency
|
||||
{
|
||||
Log.LogEvent log = new Log.LogEvent();
|
||||
|
||||
public decimal CurrencyConvertToGbp(string currencyCode, decimal amount, DateTime conversionDate)
|
||||
{
|
||||
return new Data.Database.Account.Currency().CurrencyConvertToGbp(currencyCode, amount, conversionDate);
|
||||
if (currencyCode == "GBP" || amount == 0M)
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int CurrencyExchangeRateInsert(int exchangeRateSource, string currencyCode,
|
||||
decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
|
||||
if (currencyCode.Length != 3)
|
||||
{
|
||||
return new Data.Database.Account.Currency().CurrencyExchangeRateInsert(exchangeRateSource, currencyCode,
|
||||
currencyUnitsPerGbp, periodStart, periodEnd, checkOverride);
|
||||
throw new Exception("Invalid currency code '" + currencyCode + "'");
|
||||
}
|
||||
|
||||
var db = new Data.Database.Account.Currency();
|
||||
var exchageRate = db.ReadExchangeRate(currencyCode, conversionDate);
|
||||
|
||||
if (exchageRate != null)
|
||||
{
|
||||
return amount / Convert.ToDecimal(exchageRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Currency code '" + currencyCode + "' or date " + conversionDate.ToShortDateString() + " " + conversionDate.ToLongTimeString() + "' does not exist in the Exchange Rate table");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DateTime GetHmrcMaxPeriodAvaible()
|
||||
{
|
||||
// HMRC monthly sxchange rates are published on the penultimate Thursday of the month before
|
||||
// For some leeway we'll use the penultimate Friday
|
||||
|
||||
// find penultimate Friday for current month
|
||||
var ukTimeNow = new Logic.Utilities.DateTime().ConvertUtcToUk(DateTime.UtcNow);
|
||||
var monthDayCount = DateTime.DaysInMonth(ukTimeNow.Year, ukTimeNow.Month);
|
||||
var thisMonthPenultimateFriday = DateTime.SpecifyKind(new DateTime(ukTimeNow.Year, ukTimeNow.Month, monthDayCount), DateTimeKind.Unspecified);
|
||||
int count = 0;
|
||||
int fridayCount = 0;
|
||||
while (count != 15)
|
||||
{
|
||||
if (thisMonthPenultimateFriday.DayOfWeek == DayOfWeek.Friday)
|
||||
{
|
||||
fridayCount++;
|
||||
if (fridayCount == 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
thisMonthPenultimateFriday = thisMonthPenultimateFriday.AddDays(-1);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 15)
|
||||
{
|
||||
throw new Exception("Something went wrong here ErrorID:ef7f5d8f-0f7b-4014-aa65-421ecd5d7367");
|
||||
}
|
||||
|
||||
var mostRecentPeriodAvaible = DateTime.SpecifyKind(new DateTime(ukTimeNow.Year, ukTimeNow.Month, 1), DateTimeKind.Unspecified); ;
|
||||
if (ukTimeNow >= thisMonthPenultimateFriday)
|
||||
{
|
||||
mostRecentPeriodAvaible = mostRecentPeriodAvaible.AddMonths(1);
|
||||
}
|
||||
|
||||
return mostRecentPeriodAvaible;
|
||||
}
|
||||
|
||||
public void UpdateHmrcExchageRates()
|
||||
{
|
||||
log.LogInformation("Starting update database HMRC exchange rates");
|
||||
|
||||
int exchangeRateSourceId = 1; // id for hmrc
|
||||
|
||||
// retrive most recent data from db
|
||||
var db = new Data.Database.Account.Currency();
|
||||
var dbLatestRates = db.ReadExchangeRateLatest();
|
||||
|
||||
// sanity check, make sure there are no duplicates
|
||||
int count = 0;
|
||||
foreach (var exchageRate in dbLatestRates)
|
||||
{
|
||||
count = 0;
|
||||
var currency = exchageRate.CurrencyCode;
|
||||
foreach (var subExchageRate in dbLatestRates)
|
||||
{
|
||||
if (exchageRate.CurrencyCode == subExchageRate.CurrencyCode)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
if (count > 1)
|
||||
{
|
||||
throw new FormatException("Datebase returned duplicate information");
|
||||
}
|
||||
}
|
||||
|
||||
// test for no data (first time running)
|
||||
var hmrcMonthToRetrive = new DateTime();
|
||||
if (dbLatestRates.Any() == false)
|
||||
{
|
||||
hmrcMonthToRetrive = Data.Database.Constants.GetBusinessStartUk();
|
||||
}
|
||||
|
||||
// set first/earliest month to retrive from hmrc website
|
||||
foreach (var exchageRate in dbLatestRates)
|
||||
{
|
||||
var dbEndDateTime = exchageRate.DateTimeEndUk;
|
||||
|
||||
if (hmrcMonthToRetrive == default(DateTime))
|
||||
{
|
||||
hmrcMonthToRetrive = dbEndDateTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dbEndDateTime < hmrcMonthToRetrive)
|
||||
{
|
||||
hmrcMonthToRetrive = dbEndDateTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check - more coding required to retrive periods before 2021-01-01
|
||||
if (hmrcMonthToRetrive < DateTime.SpecifyKind(new DateTime(2021, 1, 1), DateTimeKind.Unspecified))
|
||||
{
|
||||
throw new Exception("This function does not currently retirve exchange rates from HMRC for dates before 2021-01-01");
|
||||
}
|
||||
|
||||
// check if retrival from hmrc is required
|
||||
var hmrcMaxMonthAvaible = GetHmrcMaxPeriodAvaible();
|
||||
if (hmrcMonthToRetrive.Year == hmrcMaxMonthAvaible.Year && hmrcMonthToRetrive.Month > hmrcMaxMonthAvaible.Month)
|
||||
{
|
||||
// nothing to retrive
|
||||
log.LogInformation("Exchange rates curretly up to date, exiting.");
|
||||
return;
|
||||
}
|
||||
|
||||
// get info from hmrc and insert data in db
|
||||
while (hmrcMonthToRetrive <= hmrcMaxMonthAvaible)
|
||||
{
|
||||
count = 0;
|
||||
|
||||
var url = new string(
|
||||
"https://www.trade-tariff.service.gov.uk/api/v2/exchange_rates/files/monthly_xml_"
|
||||
+ hmrcMonthToRetrive.Year.ToString()
|
||||
+ "-"
|
||||
+ hmrcMonthToRetrive.Month.ToString()
|
||||
+ ".xml"
|
||||
);
|
||||
var xd = new XDocument();
|
||||
xd = XDocument.Load(url);
|
||||
|
||||
foreach (var exchageRate in dbLatestRates)
|
||||
{
|
||||
if (exchageRate.DateTimeStartUtc < hmrcMonthToRetrive)
|
||||
{
|
||||
//retrive exchange rate from xml
|
||||
XElement node = xd.Root.Elements("exchangeRate").Where(e => e.Element("currencyCode").Value == exchageRate.CurrencyCode.ToString()).FirstOrDefault();
|
||||
decimal rate = decimal.Parse(node.Element("rateNew").Value);
|
||||
rate = decimal.Round(rate, 4);
|
||||
|
||||
// insert into db
|
||||
new Data.Database.Account.Currency().InsertExchangeRate(
|
||||
exchangeRateSourceId
|
||||
, exchageRate.CurrencyCode
|
||||
, rate
|
||||
, new Utilities.DateTime().ConvertUkToUtc(hmrcMonthToRetrive)
|
||||
, new Utilities.DateTime().ConvertUkToUtc(hmrcMonthToRetrive.AddMonths(1))
|
||||
);
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
log.LogInformation(
|
||||
count + " new exchange rate(s) added to database for " + hmrcMonthToRetrive.ToString("MMMM") + " " + hmrcMonthToRetrive.Year.ToString()
|
||||
);
|
||||
|
||||
hmrcMonthToRetrive = hmrcMonthToRetrive.AddMonths(1);
|
||||
}
|
||||
|
||||
log.LogInformation("Updating database currency exchange rates complete.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
51
src/bnhtrade.Core/Logic/Utilities/DateTime.cs
Normal file
51
src/bnhtrade.Core/Logic/Utilities/DateTime.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class DateTime
|
||||
{
|
||||
public System.DateTime ConvertUkToUtc(System.DateTime ukDateTime)
|
||||
{
|
||||
if (ukDateTime.Kind == DateTimeKind.Local && TimeZoneInfo.Local.Id != "GMT Standard Time")
|
||||
{
|
||||
throw new System.ArgumentException("DateTime kind set to local, local is not set to 'GMT Standard Time'");
|
||||
}
|
||||
else if (ukDateTime.Kind == DateTimeKind.Utc)
|
||||
{
|
||||
throw new System.ArgumentException("DateTime kind is UTC");
|
||||
}
|
||||
|
||||
TimeZoneInfo ukZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
|
||||
System.DateTime ukTime = TimeZoneInfo.ConvertTimeToUtc(ukDateTime, ukZone);
|
||||
return ukTime; // is returned as DateTimeKind 'unspecified'
|
||||
}
|
||||
|
||||
public System.DateTime ConvertUtcToUk(System.DateTime utcDateTime)
|
||||
{
|
||||
if (utcDateTime.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new System.ArgumentException("DateTime kind is not UTC");
|
||||
}
|
||||
|
||||
TimeZoneInfo ukZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
|
||||
System.DateTime ukTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, ukZone);
|
||||
return ukTime; // is returned as DateTimeKind 'unspecified'
|
||||
}
|
||||
|
||||
public System.DateTime ParseIsoDateTimeString(string reportDateTime)
|
||||
{
|
||||
string isoDateTime =
|
||||
reportDateTime.Substring(6, 4) + "-" +
|
||||
reportDateTime.Substring(3, 2) + "-" +
|
||||
reportDateTime.Substring(0, 2) + "T" +
|
||||
reportDateTime.Substring(11, 2) + ":" +
|
||||
reportDateTime.Substring(14, 2) + ":" +
|
||||
reportDateTime.Substring(17, 2) + "Z";
|
||||
return System.DateTime.Parse(isoDateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,9 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class DateTimeCheck : Validate.Validate
|
||||
{
|
||||
public bool IsUtc(DateTime dateTimeToCheck)
|
||||
public bool IsUtc(System.DateTime dateTimeToCheck)
|
||||
{
|
||||
if (dateTimeToCheck == default(DateTime))
|
||||
if (dateTimeToCheck == default(System.DateTime))
|
||||
{
|
||||
ValidationResultAdd( "DateTime value set to default.");
|
||||
return false;
|
||||
@@ -22,9 +22,9 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public bool IsLocal(DateTime dateTimeToCheck)
|
||||
public bool IsLocal(System.DateTime dateTimeToCheck)
|
||||
{
|
||||
if (dateTimeToCheck == default(DateTime))
|
||||
if (dateTimeToCheck == default(System.DateTime))
|
||||
{
|
||||
ValidationResultAdd("DateTime value set to default.");
|
||||
return false;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class DateTimeParse
|
||||
{
|
||||
public DateTime ParseMwsReportDateTime(string reportDateTime)
|
||||
{
|
||||
string isoDateTime =
|
||||
reportDateTime.Substring(6, 4) + "-" +
|
||||
reportDateTime.Substring(3, 2) + "-" +
|
||||
reportDateTime.Substring(0, 2) + "T" +
|
||||
reportDateTime.Substring(11, 2) + ":" +
|
||||
reportDateTime.Substring(14, 2) + ":" +
|
||||
reportDateTime.Substring(17, 2) + "Z";
|
||||
return DateTime.Parse(isoDateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/bnhtrade.Core/Logic/Utilities/ListFunction.cs
Normal file
59
src/bnhtrade.Core/Logic/Utilities/ListFunction.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class ListFunction
|
||||
{
|
||||
public ListFunction() { }
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a unique list from an input list
|
||||
/// </summary>
|
||||
/// <param name="inputList"></param>
|
||||
/// <param name="includeWhiteSpace"></param>
|
||||
/// <returns>Unique list</returns>
|
||||
public List<string> UniqueList(List<string> inputList, bool removeNullorWhitespace = true)
|
||||
{
|
||||
List<string> outputList = new List<string>();
|
||||
|
||||
foreach (string input in inputList)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input) && removeNullorWhitespace)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
bool stringExists = false;
|
||||
foreach (string output in outputList)
|
||||
{
|
||||
if (output == input)
|
||||
{
|
||||
stringExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stringExists == false)
|
||||
{
|
||||
outputList.Add(input);
|
||||
}
|
||||
}
|
||||
|
||||
return outputList;
|
||||
}
|
||||
|
||||
public List<string> UniqueList(List<Enum> inputList, bool removeNullorWhitespace = true)
|
||||
{
|
||||
List<string> stringList = new List<string>();
|
||||
foreach (Enum input in inputList)
|
||||
{
|
||||
stringList.Add(input.ToString());
|
||||
}
|
||||
return UniqueList(stringList, removeNullorWhitespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
var export = new bnhtrade.Core.Logic.Export.AmazonSettlement();
|
||||
|
||||
bool stockUpdate = false;
|
||||
bool exchangeRate = false;
|
||||
bool accountProcess = false;
|
||||
|
||||
while (true)
|
||||
@@ -28,6 +29,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
try
|
||||
{
|
||||
if (stockUpdate == false) { stockUpdate = true; new bnhtrade.Core.Logic.Import.Amazon().SyncAllWithDatabase(); ; }
|
||||
if (exchangeRate == false) { exchangeRate = true; new Logic.Account.Currency().UpdateHmrcExchageRates(); }
|
||||
if (accountProcess == false) { accountProcess = true; export.ToInvoice(); }
|
||||
|
||||
// if (stockProcess == false) { stockProcess = true; stock.ProcessFbaStockImportData(); }
|
||||
|
||||
191
src/bnhtrade.Core/Model/Account/CurrencyCode.cs
Normal file
191
src/bnhtrade.Core/Model/Account/CurrencyCode.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public enum CurrencyCode
|
||||
{
|
||||
AED,
|
||||
AFN,
|
||||
ALL,
|
||||
AMD,
|
||||
ANG,
|
||||
AOA,
|
||||
ARS,
|
||||
AUD,
|
||||
AWG,
|
||||
AZN,
|
||||
BAM,
|
||||
BBD,
|
||||
BDT,
|
||||
BGN,
|
||||
BHD,
|
||||
BIF,
|
||||
BMD,
|
||||
BND,
|
||||
BOB,
|
||||
BOV,
|
||||
BRL,
|
||||
BSD,
|
||||
BTN,
|
||||
BWP,
|
||||
BYN,
|
||||
BYR,
|
||||
BZD,
|
||||
CAD,
|
||||
CDF,
|
||||
CHE,
|
||||
CHF,
|
||||
CHW,
|
||||
CLF,
|
||||
CLP,
|
||||
CNY,
|
||||
COP,
|
||||
COU,
|
||||
CRC,
|
||||
CUC,
|
||||
CUP,
|
||||
CVE,
|
||||
CZK,
|
||||
DJF,
|
||||
DKK,
|
||||
DOP,
|
||||
DZD,
|
||||
EGP,
|
||||
ERN,
|
||||
ETB,
|
||||
EUR,
|
||||
FJD,
|
||||
FKP,
|
||||
GBP,
|
||||
GEL,
|
||||
GHS,
|
||||
GIP,
|
||||
GMD,
|
||||
GNF,
|
||||
GTQ,
|
||||
GYD,
|
||||
HKD,
|
||||
HNL,
|
||||
HRK,
|
||||
HTG,
|
||||
HUF,
|
||||
IDR,
|
||||
ILS,
|
||||
INR,
|
||||
IQD,
|
||||
IRR,
|
||||
ISK,
|
||||
JMD,
|
||||
JOD,
|
||||
JPY,
|
||||
KES,
|
||||
KGS,
|
||||
KHR,
|
||||
KMF,
|
||||
KPW,
|
||||
KRW,
|
||||
KWD,
|
||||
KYD,
|
||||
KZT,
|
||||
LAK,
|
||||
LBP,
|
||||
LKR,
|
||||
LRD,
|
||||
LSL,
|
||||
LYD,
|
||||
MAD,
|
||||
MDL,
|
||||
MGA,
|
||||
MKD,
|
||||
MMK,
|
||||
MNT,
|
||||
MOP,
|
||||
MRO,
|
||||
MUR,
|
||||
MVR,
|
||||
MWK,
|
||||
MXN,
|
||||
MXV,
|
||||
MYR,
|
||||
MZN,
|
||||
NAD,
|
||||
NGN,
|
||||
NIO,
|
||||
NOK,
|
||||
NPR,
|
||||
NZD,
|
||||
OMR,
|
||||
PAB,
|
||||
PEN,
|
||||
PGK,
|
||||
PHP,
|
||||
PKR,
|
||||
PLN,
|
||||
PYG,
|
||||
QAR,
|
||||
RON,
|
||||
RSD,
|
||||
RUB,
|
||||
RWF,
|
||||
SAR,
|
||||
SBD,
|
||||
SCR,
|
||||
SDG,
|
||||
SEK,
|
||||
SGD,
|
||||
SHP,
|
||||
SLL,
|
||||
SOS,
|
||||
SRD,
|
||||
SSP,
|
||||
STD,
|
||||
SVC,
|
||||
SYP,
|
||||
SZL,
|
||||
THB,
|
||||
TJS,
|
||||
TMT,
|
||||
TND,
|
||||
TOP,
|
||||
TRY,
|
||||
TTD,
|
||||
TWD,
|
||||
TZS,
|
||||
UAH,
|
||||
UGX,
|
||||
USD,
|
||||
USN,
|
||||
UYI,
|
||||
UYU,
|
||||
UZS,
|
||||
VEF,
|
||||
VND,
|
||||
VUV,
|
||||
WST,
|
||||
XAF,
|
||||
XAG,
|
||||
XAU,
|
||||
XBA,
|
||||
XBB,
|
||||
XBC,
|
||||
XBD,
|
||||
XCD,
|
||||
XDR,
|
||||
XOF,
|
||||
XPD,
|
||||
XPF,
|
||||
XPT,
|
||||
XSU,
|
||||
XTS,
|
||||
XUA,
|
||||
XXX,
|
||||
YER,
|
||||
ZAR,
|
||||
ZMW,
|
||||
ZWL
|
||||
}
|
||||
}
|
||||
71
src/bnhtrade.Core/Model/Account/CurrencyExchangeRate.cs
Normal file
71
src/bnhtrade.Core/Model/Account/CurrencyExchangeRate.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public class CurrencyExchangeRate
|
||||
{
|
||||
public CurrencyExchangeRate(CurrencyCode currencyCode, int exchangeRateSource, DateTime dateTimeStartUtc, DateTime dateTimeEndUtc)
|
||||
{
|
||||
this.CurrencyCode = currencyCode;
|
||||
this.ExchangeRateSource = exchangeRateSource;
|
||||
|
||||
if (dateTimeEndUtc > dateTimeStartUtc)
|
||||
{
|
||||
this.DateTimeStartUtc = dateTimeStartUtc;
|
||||
this.DateTimeEndUtc = dateTimeEndUtc;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Incorrect start and/or end date value(s)");
|
||||
}
|
||||
}
|
||||
|
||||
public CurrencyCode CurrencyCode { get; private set; }
|
||||
|
||||
public int ExchangeRateSource { get; private set; }
|
||||
|
||||
public decimal CurrencyUnitsPerGbp { get; private set; }
|
||||
|
||||
public DateTime DateTimeStartUk
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Logic.Utilities.DateTime().ConvertUtcToUk(DateTimeStartUtc);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime DateTimeStartUtc { get; private set; }
|
||||
|
||||
public DateTime DateTimeEndUk
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Logic.Utilities.DateTime().ConvertUtcToUk(DateTimeEndUtc);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime DateTimeEndUtc { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a given datetime falls within the the exchange rate period
|
||||
/// </summary>
|
||||
/// <param name="dateTimeToCheck">The date and time to check</param>
|
||||
/// <returns>True or false</returns>
|
||||
public bool DateTimeWithinPeriodCheck(DateTime dateTimeToCheck)
|
||||
{
|
||||
if (dateTimeToCheck >= DateTimeStartUtc && dateTimeToCheck < DateTimeEndUtc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ namespace bnhtrade.Core.Model.Credentials
|
||||
{
|
||||
return "Data Source=" + DataSource + ";Initial Catalog=" + InitialCatalog + ";Persist Security Info=" + PersistSecurityInfo.ToString()
|
||||
+ ";User ID=" + UserId + ";Password=" + UserPassword + ";MultipleActiveResultSets=" + MultipleActiveResultSets.ToString()
|
||||
+ ";Connect Timeout=" + ConnectionTimeout;
|
||||
+ ";Connect Timeout=" + ConnectionTimeout + ";Encrypt=True;TrustServerCertificate=True";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using bnhtrade.Core.Data.Database.Account;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms.Design;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace bnhtrade.Core.Test.Account
|
||||
{
|
||||
@@ -11,7 +14,13 @@ namespace bnhtrade.Core.Test.Account
|
||||
{
|
||||
public Account()
|
||||
{
|
||||
Journal();
|
||||
UpdateHmrcExchageRates();
|
||||
}
|
||||
|
||||
public void UpdateHmrcExchageRates()
|
||||
{
|
||||
var logic = new bnhtrade.Core.Logic.Account.Currency();
|
||||
logic.UpdateHmrcExchageRates();
|
||||
}
|
||||
|
||||
public void PurchaseInvoice()
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<PackageReference Include="CSharpAmazonSpAPI" Version="1.7.17" />
|
||||
<PackageReference Include="CsvHelper" Version="33.0.1" />
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="112.1.0" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace bnhtradeScheduledTasks
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("<1> Amazon reports");
|
||||
Console.WriteLine("<2> Stock functions");
|
||||
Console.WriteLine("<3> Account functions");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("<8> Start scheduled nightly tasks");
|
||||
Console.WriteLine("<9> Dev functions");
|
||||
@@ -242,6 +243,34 @@ namespace bnhtradeScheduledTasks
|
||||
|
||||
} while (true);
|
||||
}
|
||||
else if (input == "3")
|
||||
{
|
||||
do
|
||||
{
|
||||
Console.Clear();
|
||||
Console.WriteLine(consoleHeader);
|
||||
Console.WriteLine("Main Menu > Account");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("<1> Update HMRC Exchange Rates");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("<0> Back");
|
||||
Console.WriteLine("");
|
||||
Console.Write("Enter an option >");
|
||||
input = Console.ReadLine();
|
||||
|
||||
if (input == "0")
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (input == "1")
|
||||
{
|
||||
Console.Clear();
|
||||
new bnhtrade.Core.Logic.Account.Currency().UpdateHmrcExchageRates();
|
||||
Console.WriteLine("Complete, press any key to continue...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
else if (input == "8")
|
||||
{
|
||||
Console.Clear();
|
||||
|
||||
72
src/bnhtrade.gui/FormConsole.Designer.cs
generated
Normal file
72
src/bnhtrade.gui/FormConsole.Designer.cs
generated
Normal file
@@ -0,0 +1,72 @@
|
||||
namespace bnhtrade.gui
|
||||
{
|
||||
partial class FormConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
button1 = new Button();
|
||||
txtConsole = new TextBox();
|
||||
SuspendLayout();
|
||||
//
|
||||
// button1
|
||||
//
|
||||
button1.Location = new Point(610, 389);
|
||||
button1.Name = "button1";
|
||||
button1.Size = new Size(152, 49);
|
||||
button1.TabIndex = 2;
|
||||
button1.Text = "Close";
|
||||
button1.UseVisualStyleBackColor = true;
|
||||
button1.Click += button1_Click;
|
||||
//
|
||||
// txtConsole
|
||||
//
|
||||
txtConsole.Location = new Point(53, 41);
|
||||
txtConsole.Multiline = true;
|
||||
txtConsole.Name = "txtConsole";
|
||||
txtConsole.Size = new Size(709, 337);
|
||||
txtConsole.TabIndex = 3;
|
||||
//
|
||||
// FormConsole
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(8F, 20F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(800, 450);
|
||||
Controls.Add(txtConsole);
|
||||
Controls.Add(button1);
|
||||
Name = "FormConsole";
|
||||
Text = "Form1";
|
||||
Load += FormConsole_Load;
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Button button1;
|
||||
private TextBox txtConsole;
|
||||
}
|
||||
}
|
||||
44
src/bnhtrade.gui/FormConsole.cs
Normal file
44
src/bnhtrade.gui/FormConsole.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using ConsoleRedirection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace bnhtrade.gui
|
||||
{
|
||||
public partial class FormConsole : Form
|
||||
{
|
||||
// That's our custom TextWriter class
|
||||
TextWriter _writer = null;
|
||||
|
||||
public FormConsole()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void FormConsole_Load(object sender, EventArgs e)
|
||||
{
|
||||
// Instantiate the writer
|
||||
_writer = new TextBoxStreamWriter(txtConsole);
|
||||
// Redirect the out Console stream
|
||||
Console.SetOut(_writer);
|
||||
}
|
||||
|
||||
// This is called when the "Say Hello" button is clicked
|
||||
private void txtSayHello_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Writing to the Console now causes the text to be displayed in the text box.
|
||||
Console.WriteLine("Hello world");
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
src/bnhtrade.gui/FormConsole.resx
Normal file
120
src/bnhtrade.gui/FormConsole.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
3
src/bnhtrade.gui/Home.Designer.cs
generated
3
src/bnhtrade.gui/Home.Designer.cs
generated
@@ -269,8 +269,9 @@
|
||||
btnExchangeRate.Name = "btnExchangeRate";
|
||||
btnExchangeRate.Size = new Size(237, 50);
|
||||
btnExchangeRate.TabIndex = 0;
|
||||
btnExchangeRate.Text = "Exchange rate input";
|
||||
btnExchangeRate.Text = "Update exchange rates";
|
||||
btnExchangeRate.UseVisualStyleBackColor = true;
|
||||
btnExchangeRate.Click += btnExchangeRate_Click;
|
||||
//
|
||||
// Home
|
||||
//
|
||||
|
||||
@@ -110,5 +110,12 @@ namespace bnhtrade.gui
|
||||
var form = new PurchaseInvoice(purchaseInvoice);
|
||||
form.Show();
|
||||
}
|
||||
|
||||
private void btnExchangeRate_Click(object sender, EventArgs e)
|
||||
{
|
||||
var myForm = new FormConsole();
|
||||
myForm.Show();
|
||||
new bnhtrade.Core.Logic.Account.Currency().UpdateHmrcExchageRates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,12 +120,6 @@
|
||||
<metadata name="bsReceivingLines.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>250, 17</value>
|
||||
</metadata>
|
||||
<metadata name="bsReceivingLines.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>250, 17</value>
|
||||
</metadata>
|
||||
<metadata name="purchaseLineStatusBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="purchaseLineStatusBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
|
||||
28
src/bnhtrade.gui/TextBoxStreamWriter.cs
Normal file
28
src/bnhtrade.gui/TextBoxStreamWriter.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ConsoleRedirection
|
||||
{
|
||||
public class TextBoxStreamWriter : TextWriter
|
||||
{
|
||||
TextBox _output = null;
|
||||
|
||||
public TextBoxStreamWriter(TextBox output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
public override void Write(char value)
|
||||
{
|
||||
base.Write(value);
|
||||
_output.AppendText(value.ToString()); // When character data is written, append it to the text box.
|
||||
}
|
||||
|
||||
public override Encoding Encoding
|
||||
{
|
||||
get { return System.Text.Encoding.UTF8; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user