From ea0a52b2a0b0e88410b943ab9717500872bcc6fd Mon Sep 17 00:00:00 2001 From: Bobbie Hodgetts Date: Mon, 9 Jun 2025 20:56:26 +0100 Subject: [PATCH] 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. --- src/bnhtrade.ComTypeLib/Account/Account.cs | 3 +- .../Data/Database/Account/CreateJournal.cs | 2 +- .../Data/Database/Account/Currency.cs | 311 +++++++++++------- src/bnhtrade.Core/Data/Database/Constants.cs | 14 +- .../Database/Import/AmazonSettlementInsert.cs | 10 +- .../Data/Database/SqlWhereBuilder.cs | 15 +- src/bnhtrade.Core/Logic/Account/Currency.cs | 189 ++++++++++- src/bnhtrade.Core/Logic/Utilities/DateTime.cs | 51 +++ .../Logic/Utilities/DateTimeCheck.cs | 8 +- .../Logic/Utilities/DateTimeParse.cs | 23 -- .../Logic/Utilities/ListFunction.cs | 59 ++++ .../Logic/Utilities/NightlyRoutine.cs | 2 + .../Model/Account/CurrencyCode.cs | 191 +++++++++++ .../Model/Account/CurrencyExchangeRate.cs | 71 ++++ .../Model/Credentials/bnhtradeDB.cs | 2 +- src/bnhtrade.Core/Test/Account/Account.cs | 13 +- src/bnhtrade.Core/bnhtrade.Core.csproj | 1 + src/bnhtrade.ScheduledTasks/Program.cs | 29 ++ src/bnhtrade.gui/FormConsole.Designer.cs | 72 ++++ src/bnhtrade.gui/FormConsole.cs | 44 +++ src/bnhtrade.gui/FormConsole.resx | 120 +++++++ src/bnhtrade.gui/Home.Designer.cs | 3 +- src/bnhtrade.gui/Home.cs | 7 + src/bnhtrade.gui/Home.resx | 6 - src/bnhtrade.gui/TextBoxStreamWriter.cs | 28 ++ 25 files changed, 1095 insertions(+), 179 deletions(-) create mode 100644 src/bnhtrade.Core/Logic/Utilities/DateTime.cs delete mode 100644 src/bnhtrade.Core/Logic/Utilities/DateTimeParse.cs create mode 100644 src/bnhtrade.Core/Logic/Utilities/ListFunction.cs create mode 100644 src/bnhtrade.Core/Model/Account/CurrencyCode.cs create mode 100644 src/bnhtrade.Core/Model/Account/CurrencyExchangeRate.cs create mode 100644 src/bnhtrade.gui/FormConsole.Designer.cs create mode 100644 src/bnhtrade.gui/FormConsole.cs create mode 100644 src/bnhtrade.gui/FormConsole.resx create mode 100644 src/bnhtrade.gui/TextBoxStreamWriter.cs diff --git a/src/bnhtrade.ComTypeLib/Account/Account.cs b/src/bnhtrade.ComTypeLib/Account/Account.cs index 7d42ea3..491ac29 100644 --- a/src/bnhtrade.ComTypeLib/Account/Account.cs +++ b/src/bnhtrade.ComTypeLib/Account/Account.cs @@ -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"); } } diff --git a/src/bnhtrade.Core/Data/Database/Account/CreateJournal.cs b/src/bnhtrade.Core/Data/Database/Account/CreateJournal.cs index 01a4f04..a149dbf 100644 --- a/src/bnhtrade.Core/Data/Database/Account/CreateJournal.cs +++ b/src/bnhtrade.Core/Data/Database/Account/CreateJournal.cs @@ -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 diff --git a/src/bnhtrade.Core/Data/Database/Account/Currency.cs b/src/bnhtrade.Core/Data/Database/Account/Currency.cs index da36093..f2ed460 100644 --- a/src/bnhtrade.Core/Data/Database/Account/Currency.cs +++ b/src/bnhtrade.Core/Data/Database/Account/Currency.cs @@ -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) + /// + /// Returns excahnge rate, in decimal format, for a given currency and datetime + /// + /// currency code + /// dat and time + /// + 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 ReadExchangeRate(List currencyCodeList = null, DateTime date = default(DateTime)) { + throw new NotImplementedException("Complete, but untested"); + + var returnList = new List(); + + 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 stringList = new List(); + 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 ReadExchangeRateLatest(List currencyCodeList = null) + { + var returnList = new List(); + + 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(); + 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(); diff --git a/src/bnhtrade.Core/Data/Database/Constants.cs b/src/bnhtrade.Core/Data/Database/Constants.cs index 8fae4df..6795e36 100644 --- a/src/bnhtrade.Core/Data/Database/Constants.cs +++ b/src/bnhtrade.Core/Data/Database/Constants.cs @@ -8,14 +8,22 @@ namespace bnhtrade.Core.Data.Database { public static class Constants { + /// + /// Gets the date bnhtrade started trading, UK time (datetime kind unspecified). + /// + /// The UK date and time the business started (datetime kind unspecified) + public static DateTime GetBusinessStartUk() + { + return new Logic.Utilities.DateTime().ConvertUtcToUk(GetBusinessStartUtc()); + } /// - /// Gets the date bnhtrade started trading. + /// Gets the date bnhtrade started trading, as UTC time /// - /// Date and time + /// The UTC date and time the business started (datetime kind UTC) 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); } diff --git a/src/bnhtrade.Core/Data/Database/Import/AmazonSettlementInsert.cs b/src/bnhtrade.Core/Data/Database/Import/AmazonSettlementInsert.cs index 4719cb9..778368b 100644 --- a/src/bnhtrade.Core/Data/Database/Import/AmazonSettlementInsert.cs +++ b/src/bnhtrade.Core/Data/Database/Import/AmazonSettlementInsert.cs @@ -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])); } diff --git a/src/bnhtrade.Core/Data/Database/SqlWhereBuilder.cs b/src/bnhtrade.Core/Data/Database/SqlWhereBuilder.cs index 812e4a7..73687f1 100644 --- a/src/bnhtrade.Core/Data/Database/SqlWhereBuilder.cs +++ b/src/bnhtrade.Core/Data/Database/SqlWhereBuilder.cs @@ -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(); } - 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) { diff --git a/src/bnhtrade.Core/Logic/Account/Currency.cs b/src/bnhtrade.Core/Logic/Account/Currency.cs index 0aa682d..49ced0b 100644 --- a/src/bnhtrade.Core/Logic/Account/Currency.cs +++ b/src/bnhtrade.Core/Logic/Account/Currency.cs @@ -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; + } + + if (currencyCode.Length != 3) + { + 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"); + } + } - public int CurrencyExchangeRateInsert(int exchangeRateSource, string currencyCode, - decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false) + private DateTime GetHmrcMaxPeriodAvaible() { - return new Data.Database.Account.Currency().CurrencyExchangeRateInsert(exchangeRateSource, currencyCode, - currencyUnitsPerGbp, periodStart, periodEnd, checkOverride); + // 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."); } } } diff --git a/src/bnhtrade.Core/Logic/Utilities/DateTime.cs b/src/bnhtrade.Core/Logic/Utilities/DateTime.cs new file mode 100644 index 0000000..efb1e45 --- /dev/null +++ b/src/bnhtrade.Core/Logic/Utilities/DateTime.cs @@ -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); + } + } +} diff --git a/src/bnhtrade.Core/Logic/Utilities/DateTimeCheck.cs b/src/bnhtrade.Core/Logic/Utilities/DateTimeCheck.cs index dacc3fe..a1a2d2f 100644 --- a/src/bnhtrade.Core/Logic/Utilities/DateTimeCheck.cs +++ b/src/bnhtrade.Core/Logic/Utilities/DateTimeCheck.cs @@ -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; diff --git a/src/bnhtrade.Core/Logic/Utilities/DateTimeParse.cs b/src/bnhtrade.Core/Logic/Utilities/DateTimeParse.cs deleted file mode 100644 index 970a387..0000000 --- a/src/bnhtrade.Core/Logic/Utilities/DateTimeParse.cs +++ /dev/null @@ -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); - } - } -} diff --git a/src/bnhtrade.Core/Logic/Utilities/ListFunction.cs b/src/bnhtrade.Core/Logic/Utilities/ListFunction.cs new file mode 100644 index 0000000..5712e89 --- /dev/null +++ b/src/bnhtrade.Core/Logic/Utilities/ListFunction.cs @@ -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() { } + + /// + /// Outputs a unique list from an input list + /// + /// + /// + /// Unique list + public List UniqueList(List inputList, bool removeNullorWhitespace = true) + { + List outputList = new List(); + + 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 UniqueList(List inputList, bool removeNullorWhitespace = true) + { + List stringList = new List(); + foreach (Enum input in inputList) + { + stringList.Add(input.ToString()); + } + return UniqueList(stringList, removeNullorWhitespace); + } + } +} diff --git a/src/bnhtrade.Core/Logic/Utilities/NightlyRoutine.cs b/src/bnhtrade.Core/Logic/Utilities/NightlyRoutine.cs index 586f2f3..153b206 100644 --- a/src/bnhtrade.Core/Logic/Utilities/NightlyRoutine.cs +++ b/src/bnhtrade.Core/Logic/Utilities/NightlyRoutine.cs @@ -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(); } diff --git a/src/bnhtrade.Core/Model/Account/CurrencyCode.cs b/src/bnhtrade.Core/Model/Account/CurrencyCode.cs new file mode 100644 index 0000000..f6629e2 --- /dev/null +++ b/src/bnhtrade.Core/Model/Account/CurrencyCode.cs @@ -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 + } +} diff --git a/src/bnhtrade.Core/Model/Account/CurrencyExchangeRate.cs b/src/bnhtrade.Core/Model/Account/CurrencyExchangeRate.cs new file mode 100644 index 0000000..5558f78 --- /dev/null +++ b/src/bnhtrade.Core/Model/Account/CurrencyExchangeRate.cs @@ -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; } + + + /// + /// Checks whether a given datetime falls within the the exchange rate period + /// + /// The date and time to check + /// True or false + public bool DateTimeWithinPeriodCheck(DateTime dateTimeToCheck) + { + if (dateTimeToCheck >= DateTimeStartUtc && dateTimeToCheck < DateTimeEndUtc) + { + return true; + } + else + { + return false; + } + } + } +} diff --git a/src/bnhtrade.Core/Model/Credentials/bnhtradeDB.cs b/src/bnhtrade.Core/Model/Credentials/bnhtradeDB.cs index 6071447..c8140ab 100644 --- a/src/bnhtrade.Core/Model/Credentials/bnhtradeDB.cs +++ b/src/bnhtrade.Core/Model/Credentials/bnhtradeDB.cs @@ -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"; } } diff --git a/src/bnhtrade.Core/Test/Account/Account.cs b/src/bnhtrade.Core/Test/Account/Account.cs index cbd55e2..04c9ded 100644 --- a/src/bnhtrade.Core/Test/Account/Account.cs +++ b/src/bnhtrade.Core/Test/Account/Account.cs @@ -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() diff --git a/src/bnhtrade.Core/bnhtrade.Core.csproj b/src/bnhtrade.Core/bnhtrade.Core.csproj index 806982c..924196e 100644 --- a/src/bnhtrade.Core/bnhtrade.Core.csproj +++ b/src/bnhtrade.Core/bnhtrade.Core.csproj @@ -36,6 +36,7 @@ + diff --git a/src/bnhtrade.ScheduledTasks/Program.cs b/src/bnhtrade.ScheduledTasks/Program.cs index e438418..f797450 100644 --- a/src/bnhtrade.ScheduledTasks/Program.cs +++ b/src/bnhtrade.ScheduledTasks/Program.cs @@ -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(); diff --git a/src/bnhtrade.gui/FormConsole.Designer.cs b/src/bnhtrade.gui/FormConsole.Designer.cs new file mode 100644 index 0000000..1f77957 --- /dev/null +++ b/src/bnhtrade.gui/FormConsole.Designer.cs @@ -0,0 +1,72 @@ +namespace bnhtrade.gui +{ + partial class FormConsole + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + 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; + } +} \ No newline at end of file diff --git a/src/bnhtrade.gui/FormConsole.cs b/src/bnhtrade.gui/FormConsole.cs new file mode 100644 index 0000000..a5314c4 --- /dev/null +++ b/src/bnhtrade.gui/FormConsole.cs @@ -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(); + } + } +} diff --git a/src/bnhtrade.gui/FormConsole.resx b/src/bnhtrade.gui/FormConsole.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/src/bnhtrade.gui/FormConsole.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/bnhtrade.gui/Home.Designer.cs b/src/bnhtrade.gui/Home.Designer.cs index 45c1b74..43c956d 100644 --- a/src/bnhtrade.gui/Home.Designer.cs +++ b/src/bnhtrade.gui/Home.Designer.cs @@ -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 // diff --git a/src/bnhtrade.gui/Home.cs b/src/bnhtrade.gui/Home.cs index 39117f8..b4ce227 100644 --- a/src/bnhtrade.gui/Home.cs +++ b/src/bnhtrade.gui/Home.cs @@ -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(); + } } } diff --git a/src/bnhtrade.gui/Home.resx b/src/bnhtrade.gui/Home.resx index 80aeb14..a298a7f 100644 --- a/src/bnhtrade.gui/Home.resx +++ b/src/bnhtrade.gui/Home.resx @@ -120,12 +120,6 @@ 250, 17 - - 250, 17 - - - 17, 17 - 17, 17 diff --git a/src/bnhtrade.gui/TextBoxStreamWriter.cs b/src/bnhtrade.gui/TextBoxStreamWriter.cs new file mode 100644 index 0000000..333312a --- /dev/null +++ b/src/bnhtrade.gui/TextBoxStreamWriter.cs @@ -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; } + } + } +}