pull master into branch

* Migrated projects to dotnet8

migrated all projects over to .net8
incomplete feature for gui shipments

* Amazon inventory ledger testing and implementation

Tested what I can until more data for the Amazon Ledger Detail table comes in

* amazon settlement amounts now set to tax inclusive when exporting to invoice

* Some updates to the COM lib to attempt to get it to work on .net 8. Unfinished, porting all Access functions over to vs instead

* 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:
Bobbie Hodgetts
2025-06-09 21:23:42 +01:00
committed by GitHub
parent a0c669f1d4
commit 30174290cf
41 changed files with 1370 additions and 415 deletions

View File

@@ -54,8 +54,7 @@ namespace bnhtrade.ComTypeLib
public int CurrencyExchangeRateInsert(ConnectionCredential sqlConnCred, int exchangeRateSource, string currencyCode, public int CurrencyExchangeRateInsert(ConnectionCredential sqlConnCred, int exchangeRateSource, string currencyCode,
[MarshalAs(UnmanagedType.Currency)] decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false) [MarshalAs(UnmanagedType.Currency)] decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
{ {
return new Core.Logic.Account.Currency().CurrencyExchangeRateInsert(exchangeRateSource, currencyCode, throw new Exception("This function has been retired, now handled by nightly routines");
currencyUnitsPerGbp, periodStart, periodEnd, checkOverride);
} }
} }

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ClearOutputDirectory>True</ClearOutputDirectory>
</PropertyGroup>
</Project>

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- ILRepack -->
<Target Name="ILRepacker" AfterTargets="Build"> <Target Name="ILRepacker" AfterTargets="Build">
<ItemGroup> <ItemGroup>
<InputAssemblies Include="$(OutputPath)\*.dll" /> <InputAssemblies Include="$(OutputPath)*.dll" />
<!--ILRepack started complaining it can't resolve CSVHelper when building the project, hence the line below-->
<!--It's a hack, and will need updating when CSVHelper is updated, but I can't figure it out-->
<!--InputAssemblies Include="C:\Users\Bobbie\.nuget\packages\csvhelper\33.0.1\lib\net8.0\CsvHelper.dll"/-->
</ItemGroup> </ItemGroup>
<ILRepack <ILRepack
@@ -14,6 +18,8 @@
OutputFile="$(TargetPath)" OutputFile="$(TargetPath)"
Parallel="true" Parallel="true"
TargetKind="Dll" TargetKind="Dll"
LibraryPath="$(OutputPath)" /> LibraryPath="$(OutputPath)"
/>
</Target> </Target>
<!-- /ILRepack -->
</Project> </Project>

View File

@@ -0,0 +1,11 @@
To setup on new computer:
1. Add the app.local.config to the users ..\AppData\Local\bnhtrade\ folder (create the bnhtrade folder)
2. CLone bnhtrade solution from the repo
3. Build bnhtradeCOM project
4. Register the COM host for COM. With an elevated prompt, navigate to the build directory and run "regsvr32 bnhtradeCOM.comhost.dll"
5.

View File

@@ -4,7 +4,16 @@
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AssemblyName>bnhtradeCOM</AssemblyName> <AssemblyName>bnhtradeCOM</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<!--Added the line below to copy all dll from .nuget folder to build output folder-->
<!--CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies-->
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<!--https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com#register-the-com-host-for-com-->
<EnableComHosting>true</EnableComHosting>
</PropertyGroup>
<ItemGroup>
<ComHostTypeLibrary Include="bnhtradeCOM.tlb" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup> </PropertyGroup>
@@ -24,15 +33,11 @@
<ProjectReference Include="..\bnhtrade.Core\bnhtrade.Core.csproj" /> <ProjectReference Include="..\bnhtrade.Core\bnhtrade.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.31" /> <PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<PropertyGroup /> <PropertyGroup />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>copy "$(ProjectDir)_RegAsmInstall.bat" "$(TargetDir)"
copy "$(ProjectDir)_RegAsmRefresh.bat" "$(TargetDir)"
copy "$(ProjectDir)_RegAsmUninstall.bat" "$(TargetDir)"</PostBuildEvent>
<AssemblyTitle>bnhtrade COM Type Library</AssemblyTitle> <AssemblyTitle>bnhtrade COM Type Library</AssemblyTitle>
<Company>bnhtrade</Company> <Company>bnhtrade</Company>
<Product>bnhtradeCOMAsm</Product> <Product>bnhtradeCOMAsm</Product>
@@ -40,4 +45,7 @@ copy "$(ProjectDir)_RegAsmUninstall.bat" "$(TargetDir)"</PostBuildEvent>
<AssemblyVersion>1.0.0.0</AssemblyVersion> <AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion> <FileVersion>1.0.0.0</FileVersion>
</PropertyGroup> </PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy &quot;$(ProjectDir)_RegAsmInstall.bat&quot; &quot;$(TargetDir)&quot;&#xD;&#xA;copy &quot;$(ProjectDir)_RegAsmRefresh.bat&quot; &quot;$(TargetDir)&quot;&#xD;&#xA;copy &quot;$(ProjectDir)_RegAsmUninstall.bat&quot; &quot;$(TargetDir)&quot;" />
</Target>
</Project> </Project>

View File

@@ -162,7 +162,7 @@ namespace bnhtrade.Core.Data.Database.Account
// currency conversion // currency conversion
if (currencyCode != "GBP") 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 // ensure decimal is rounded

View File

@@ -1,26 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SqlClient; using Microsoft.Data.SqlClient;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections;
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentOutbound;
using System.Data;
namespace bnhtrade.Core.Data.Database.Account namespace bnhtrade.Core.Data.Database.Account
{ {
internal class Currency : Connection 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)) using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{ {
sqlConn.Open(); sqlConn.Open();
@@ -32,145 +31,210 @@ namespace bnhtrade.Core.Data.Database.Account
", sqlConn)) ", sqlConn))
{ {
cmd.Parameters.AddWithValue("@currencyCode", currencyCode); cmd.Parameters.AddWithValue("@currencyCode", currencyCode);
cmd.Parameters.AddWithValue("@conversionDate", conversionDate); cmd.Parameters.AddWithValue("@conversionDate", date);
object result = cmd.ExecuteScalar(); object result = cmd.ExecuteScalar();
if (result != null) if (result != null)
{ {
return amount / Convert.ToDecimal(result); return 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");
} }
else else
{ {
throw new Exception("Date range for " + currencyCode + " " + conversionDate.ToShortDateString() + " " + return null;
conversionDate.ToLongTimeString() + "' does not exist in Exchange Rate table");
} }
} }
} }
} }
public int CurrencyExchangeRateInsert(int exchangeRateSource, string currencyCode, public List<Model.Account.CurrencyExchangeRate> ReadExchangeRate(List<Model.Account.CurrencyCode> currencyCodeList = null, DateTime date = default(DateTime))
decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
{ {
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); currencyUnitsPerGbp = decimal.Round(currencyUnitsPerGbp, 4);
periodStart = DateTime.SpecifyKind(periodStart, DateTimeKind.Utc);
periodEnd = DateTime.SpecifyKind(periodEnd, DateTimeKind.Utc);
// CHECKS // CHECKS
// HMRC source only if (periodEnd <= periodStartUtc)
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)
{ {
throw new Exception("Invalid date period."); 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."); throw new Exception("Date period is greater than 31 days.");
} }
// retirve previous data // make the insert
DateTime? periodEndLast = null; DateTime? periodEndLast = null;
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString)) using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{ {
sqlConn.Open(); 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; int recordId = 0;
using (SqlCommand cmd = new SqlCommand(@" using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblAccountExchangeRate (ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate) INSERT INTO tblAccountExchangeRate (ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate)
@@ -179,9 +243,9 @@ namespace bnhtrade.Core.Data.Database.Account
", sqlConn)) ", sqlConn))
{ {
cmd.Parameters.AddWithValue("@exchangeRateSource", exchangeRateSource); cmd.Parameters.AddWithValue("@exchangeRateSource", exchangeRateSource);
cmd.Parameters.AddWithValue("@currencyCode", currencyCode); cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
cmd.Parameters.AddWithValue("@currencyUnitsPerGbp", currencyUnitsPerGbp); cmd.Parameters.AddWithValue("@currencyUnitsPerGbp", currencyUnitsPerGbp);
cmd.Parameters.AddWithValue("@periodStart", periodStart); cmd.Parameters.AddWithValue("@periodStart", periodStartUtc);
cmd.Parameters.AddWithValue("@periodEnd", periodEnd); cmd.Parameters.AddWithValue("@periodEnd", periodEnd);
recordId = (int)cmd.ExecuteScalar(); recordId = (int)cmd.ExecuteScalar();

View File

@@ -8,14 +8,22 @@ namespace bnhtrade.Core.Data.Database
{ {
public static class Constants 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> /// <summary>
/// Gets the date bnhtrade started trading. /// Gets the date bnhtrade started trading, as UTC time
/// </summary> /// </summary>
/// <returns>Date and time</returns> /// <returns>The UTC date and time the business started (datetime kind UTC)</returns>
public static DateTime GetBusinessStartUtc() 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); return DateTime.SpecifyKind(businessStart, DateTimeKind.Utc);
} }

View File

@@ -354,8 +354,8 @@ namespace bnhtrade.Core.Data.Database.Import
item.Asin = reader.GetString(8); item.Asin = reader.GetString(8);
item.Condition = reader.GetString(9); item.Condition = reader.GetString(9);
item.CurrencyUnit = reader.GetString(10); item.CurrencyUnit = reader.GetString(10);
item.AmountPerUnit = reader.GetInt32(11); item.AmountPerUnit = reader.GetDecimal(11);
item.AmountTotal = reader.GetInt32(12); item.AmountTotal = reader.GetDecimal(12);
item.QuantityReimbursedCash = reader.GetInt32(13); item.QuantityReimbursedCash = reader.GetInt32(13);
item.QuantityReimbursedInventory = reader.GetInt32(14); item.QuantityReimbursedInventory = reader.GetInt32(14);
item.QuantityReimbursedTotal = reader.GetInt32(15); item.QuantityReimbursedTotal = reader.GetInt32(15);

View File

@@ -146,16 +146,16 @@ namespace bnhtrade.Core.Data.Database.Import
sqlCommand.Parameters.AddWithValue("@settlementId", settlementRef); 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); } 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); } 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); } 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); } if (indexTotalAmount == -1 || items[indexTotalAmount].Length == 0) { sqlCommand.Parameters.AddWithValue("@totalAmount", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@settlementotalAmounttId", settlementAmount); } else { sqlCommand.Parameters.AddWithValue("@settlementotalAmounttId", settlementAmount); }
@@ -245,7 +245,7 @@ namespace bnhtrade.Core.Data.Database.Import
else { sqlCommand.Parameters.AddWithValue("@FulfillmentRef", items[indexFulfillmentId]); } else { sqlCommand.Parameters.AddWithValue("@FulfillmentRef", items[indexFulfillmentId]); }
if (indexPostedDateTime == -1 || items[indexPostedDateTime].Length == 0) { sqlCommand.Parameters.AddWithValue("@PostedDateTimeUTC", DBNull.Value); } 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); } if (indexOrderItemCode == -1 || items[indexOrderItemCode].Length == 0) { sqlCommand.Parameters.AddWithValue("@OrderItemCode", DBNull.Value); }
else { sqlCommand.Parameters.AddWithValue("@OrderItemCode", long.Parse(items[indexOrderItemCode])); } else { sqlCommand.Parameters.AddWithValue("@OrderItemCode", long.Parse(items[indexOrderItemCode])); }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SqlClient; using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -53,7 +54,19 @@ namespace bnhtrade.Core.Data.Database
ParameterList = new Dictionary<string, object>(); 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) if (ParameterList != null)
{ {

View File

@@ -6,23 +6,19 @@ namespace bnhtrade.Core.Data.Database.Stock
{ {
public class InsertSkuTransactionType : Connection public class InsertSkuTransactionType : Connection
{ {
/// <summary>
/// The insert command will not participate in any amibent transaction scope. Default is true.
/// </summary>
public bool SuppressTransactionScope { get; set; } = true;
/// <summary> /// <summary>
/// Creates a new SKU Transaction Type /// Creates a new SKU Transaction Type
/// </summary> /// </summary>
/// <param name="stockJournalTypeId"></param> /// <param name="stockJournalTypeId"></param>
/// <param name="skuTransactionCode"></param> /// <param name="skuTransactionCode"></param>
/// <param name="transactionScopeSuppress">The insert command will not participate in any amibent transaction scope</param>
/// <returns>ID of the created record</returns> /// <returns>ID of the created record</returns>
/// <exception cref="Exception"></exception> /// <exception cref="Exception"></exception>
public int Create(string skuTransactionCode, int stockJournalTypeId) public int Create(string skuTransactionCode, int stockJournalTypeId, bool transactionScopeSuppress = false)
{ {
int id; int id;
var scopeOption = new TransactionScopeOption(); var scopeOption = new TransactionScopeOption();
if (SuppressTransactionScope) if (transactionScopeSuppress)
{ {
scopeOption = TransactionScopeOption.Suppress; scopeOption = TransactionScopeOption.Suppress;
} }
@@ -32,6 +28,7 @@ namespace bnhtrade.Core.Data.Database.Stock
} }
using (TransactionScope scope = new TransactionScope(scopeOption)) using (TransactionScope scope = new TransactionScope(scopeOption))
{
using (SqlConnection conn = new SqlConnection(SqlConnectionString)) using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{ {
conn.Open(); conn.Open();
@@ -47,8 +44,8 @@ namespace bnhtrade.Core.Data.Database.Stock
", conn)) ", conn))
{ {
cmd.Parameters.AddWithValue("@typeName", skuTransactionCode); cmd.Parameters.AddWithValue("@typeName", skuTransactionCode);
cmd.Parameters.AddWithValue("@typeCode", skuTransactionCode);
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId); cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
cmd.Parameters.AddWithValue("@typeCode", skuTransactionCode);
object obj = cmd.ExecuteScalar(); object obj = cmd.ExecuteScalar();
@@ -59,6 +56,7 @@ namespace bnhtrade.Core.Data.Database.Stock
} }
scope.Complete(); scope.Complete();
} }
}
return id; return id;
} }
} }

View File

@@ -4,7 +4,9 @@ using System.Data.SqlClient;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Transactions;
using Dapper; using Dapper;
using static System.Formats.Asn1.AsnWriter;
namespace bnhtrade.Core.Data.Database.Stock namespace bnhtrade.Core.Data.Database.Stock
{ {
@@ -14,81 +16,10 @@ namespace bnhtrade.Core.Data.Database.Stock
{ {
} }
/// <summary> private List<Model.Stock.SkuTransactionType> Execute(string sqlWhere, DynamicParameters param, bool transactionScopeSuppress = false)
/// Depriciated, delete when not required by other code
/// </summary>
/// <param name="sqlConnectionString"></param>
/// <param name="typeCode"></param>
/// <returns></returns>
public int GetTypeId(string typeCode)
{ {
/* GetStockTransactionTypeId return meanings var returnList = new List<Model.Stock.SkuTransactionType>();
* >0 use as the TypeId when inserting transaction
* 0 Skip transpose, type doesn't exist or is new (not reviewed yet)
* -1 Type import/transpose is disabled, IsProcessed=TRUE StockTransactionID=NULL */
// old optional parameters
// , bool onNewReturnId = false, bool onNewDisableInsert = false
if (typeCode.Length == 0)
{
throw new Exception("Empty match string passed to method");
}
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
{
sqlConn.Open();
using (SqlCommand cmd = new SqlCommand(@"
SELECT
StockSkuTransactionTypeID,
IsNewReviewRequired,
TransactionImportEnabled
FROM
tblStockSkuTransactionType
WHERE
TypeCode=@typeCode;
", sqlConn))
{
cmd.Parameters.AddWithValue("@typeCode", typeCode);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
int transactionTypeId = reader.GetInt32(0);
bool isNew = reader.GetBoolean(1);
bool importEnabled = reader.GetBoolean(2);
if (isNew == true)
{
// return 0 and 'skip' item
return 0;
}
else if (importEnabled == false)
{
// mark IsProcessed=true and leave transactionId=null
return -1;
}
else if (transactionTypeId > 0)
{
return transactionTypeId;
}
else
{
throw new Exception("Sku TransactionTypeId lookup method failed, is one of the 'enabled' boolean on table set to null?");
}
}
else
{
return 0;
}
}
}
}
}
private List<Model.Stock.SkuTransactionType> Execute(string sqlWhere, DynamicParameters param)
{
string sql = @" string sql = @"
SELECT tblStockSkuTransactionType.StockSkuTransactionTypeID AS TypeId SELECT tblStockSkuTransactionType.StockSkuTransactionTypeID AS TypeId
,tblStockSkuTransactionType.TypeName ,tblStockSkuTransactionType.TypeName
@@ -116,14 +47,26 @@ namespace bnhtrade.Core.Data.Database.Stock
sql += sqlWhere; sql += sqlWhere;
using (SqlConnection conn = new SqlConnection(SqlConnectionString)) using (SqlConnection conn = new SqlConnection(SqlConnectionString))
{
if (transactionScopeSuppress)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{ {
conn.Open(); conn.Open();
returnList = conn.Query<Model.Stock.SkuTransactionType>(sql, param).ToList();
return conn.Query<Model.Stock.SkuTransactionType>(sql, param).ToList(); }
}
else
{
conn.Open();
returnList = conn.Query<Model.Stock.SkuTransactionType>(sql, param).ToList();
} }
} }
public List<Model.Stock.SkuTransactionType> ByTypeCode(List<string> typeCodeList) return returnList;
}
public List<Model.Stock.SkuTransactionType> ByTypeCode(List<string> typeCodeList, bool transactionScopeSuppress = false)
{ {
typeCodeList.RemoveAll(string.IsNullOrWhiteSpace); typeCodeList.RemoveAll(string.IsNullOrWhiteSpace);
@@ -138,7 +81,7 @@ namespace bnhtrade.Core.Data.Database.Stock
return Execute(sqlWhere, param); return Execute(sqlWhere, param);
} }
public List<Model.Stock.SkuTransactionType> ByTypeName(List<string> typeName) public List<Model.Stock.SkuTransactionType> ByTypeName(List<string> typeName, bool transactionScopeSuppress = false)
{ {
typeName.RemoveAll(string.IsNullOrWhiteSpace); typeName.RemoveAll(string.IsNullOrWhiteSpace);

View File

@@ -1,23 +1,200 @@
using System; using FikaAmazonAPI.ConstructFeed.Messages;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
namespace bnhtrade.Core.Logic.Account namespace bnhtrade.Core.Logic.Account
{ {
public class Currency public class Currency
{ {
Log.LogEvent log = new Log.LogEvent();
public decimal CurrencyConvertToGbp(string currencyCode, decimal amount, DateTime conversionDate) 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, if (currencyCode.Length != 3)
decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
{ {
return new Data.Database.Account.Currency().CurrencyExchangeRateInsert(exchangeRateSource, currencyCode, throw new Exception("Invalid currency code '" + currencyCode + "'");
currencyUnitsPerGbp, periodStart, periodEnd, checkOverride); }
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.");
} }
} }
} }

View File

@@ -45,7 +45,7 @@ namespace bnhtrade.Core.Logic.Import
dateLog.SetDateTimeUtc(reportName, utcEndDate); dateLog.SetDateTimeUtc(reportName, utcEndDate);
scope.Complete(); scope.Complete();
} }
log.LogInformation("Amazon report '" + reportName + "' sync with database comlpete."); log.LogInformation("Amazon report '" + reportName + "' sync with database complete.");
} }
} }
} }

View File

@@ -126,9 +126,6 @@ namespace bnhtrade.Core.Logic.Stock
/// <exception cref="Exception"></exception> /// <exception cref="Exception"></exception>
public int Create(Model.Stock.SkuTransactionCreate skuTransaction) public int Create(Model.Stock.SkuTransactionCreate skuTransaction)
{ {
// need to add function to check if transaction type exists, if not, create a new one.
throw new NotImplementedException();
if (skuTransaction == null) if (skuTransaction == null)
{ {
throw new Exception(err + "Object was null"); throw new Exception(err + "Object was null");

View File

@@ -39,10 +39,10 @@ namespace bnhtrade.Core.Logic.Stock
private string ConstructTransactionTypeCode(Model.Import.AmazonFbaInventoryLedgerDetail record) private string ConstructTransactionTypeCode(Model.Import.AmazonFbaInventoryLedgerDetail record)
{ {
if (string.IsNullOrEmpty(record.Reason)) //if (string.IsNullOrEmpty(record.Reason))
{ //{
return null; // return null;
} //}
string transactionCode = "<AmazonReport><GET_LEDGER_DETAIL_VIEW_DATA><" + record.EventType + ">"; string transactionCode = "<AmazonReport><GET_LEDGER_DETAIL_VIEW_DATA><" + record.EventType + ">";
@@ -66,33 +66,26 @@ namespace bnhtrade.Core.Logic.Stock
} }
/// <summary> /// <summary>
/// Imports/Transaposes all data required for reconcilation, into the sku transaction table. /// Imports/Transaposes all required data into sku transaction table for reconcilation.
/// </summary> /// </summary>
public void ImportAll() public void ImportAll()
{ {
bool inventoryLedgerDetail = false; string methodName = "'Import all' data to 'Stock SKU Transactions'";
bool reimbursement = false;
log.LogInformation(methodName + " started...");
while (true)
{
try try
{ {
if (true) ImportAmazonFbaLedgerDetail();
ImportAmazonFbaReimbursement();
}
catch
{ {
if (inventoryLedgerDetail == false) { inventoryLedgerDetail = true; ImportAmazonFbaLedgerDetail(); } log.LogError(methodName + " did not complete.");
if (reimbursement == false) { reimbursement = true; ImportAmazonFbaReimbursement(); } throw;
} }
break; log.LogInformation(methodName + " complete.");
}
catch (Exception ex)
{
log.LogError(
"Exception caught running Importing amazon reports in the SKU transaction table, see for further details",
ex.ToString()
);
}
}
} }
/// <summary> /// <summary>
@@ -101,7 +94,9 @@ namespace bnhtrade.Core.Logic.Stock
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public void ImportAmazonFbaReimbursement() public void ImportAmazonFbaReimbursement()
{ {
throw new NotImplementedException("Needs testing"); string methodName = "Import 'Amazon FBA Reimbursement' into 'Stock SKU Transactions'";
//throw new NotImplementedException("Needs testing");
/* /*
* Not to be used for stock reconciliation! A single stock item can have multiple reimburesements aginst it. * Not to be used for stock reconciliation! A single stock item can have multiple reimburesements aginst it.
@@ -112,9 +107,9 @@ namespace bnhtrade.Core.Logic.Stock
* and also the 'Cost of goods' amounts moved to the appropreate account id * and also the 'Cost of goods' amounts moved to the appropreate account id
*/ */
log.LogInformation("Starting TransposeFbaRemovalOrderReport()"); log.LogInformation(methodName + " started...");
int transposeCount = 0; int importedCount = 0;
int transposeSkip = 0; int processedCount = 0;
var dbAmznReport = new Data.Database.Import.AmazonFbaReimbursement(); var dbAmznReport = new Data.Database.Import.AmazonFbaReimbursement();
var dbTransType = new Logic.Stock.SkuTransactionTypeCrud(); var dbTransType = new Logic.Stock.SkuTransactionTypeCrud();
@@ -128,6 +123,8 @@ namespace bnhtrade.Core.Logic.Stock
var transTypeCodeList = new List<string>(); var transTypeCodeList = new List<string>();
foreach (var item in importList) foreach (var item in importList)
{ {
processedCount++;
transTypeCodeList.Add(ConstructTransactionTypeCode(item, false)); transTypeCodeList.Add(ConstructTransactionTypeCode(item, false));
// any that reimburse inventory, will have two entries // any that reimburse inventory, will have two entries
if(item.QuantityReimbursedInventory > 0) if(item.QuantityReimbursedInventory > 0)
@@ -170,7 +167,7 @@ namespace bnhtrade.Core.Logic.Stock
// don't go any further until the transaction-type has been reviewed/setup // don't go any further until the transaction-type has been reviewed/setup
if (foundNewType) if (foundNewType)
{ {
log.LogWarning("Cannot complete ImportAmazonFbaReimbursement, new 'Stock Trnasaction Type' found. Review required/"); log.LogWarning(methodName + " unable to complete. New 'Stock Trnasaction Type' found. Review required/");
return; return;
} }
@@ -189,7 +186,7 @@ namespace bnhtrade.Core.Logic.Stock
if (transType.IsNewReviewRequired) if (transType.IsNewReviewRequired)
{ {
throw new Exception("Fail safe: Buggy code, should not get here!"); throw new Exception(methodName + " fail safe: Buggy code, should not get here!");
} }
else if (transType.TransactionImportEnabled) else if (transType.TransactionImportEnabled)
{ {
@@ -214,7 +211,7 @@ namespace bnhtrade.Core.Logic.Stock
if (transType.IsNewReviewRequired) if (transType.IsNewReviewRequired)
{ {
throw new Exception("Fail safe: Buggy code, should not get here!"); throw new Exception(methodName + " fail safe: Buggy code, should not get here!");
} }
else if (transType.TransactionImportEnabled) else if (transType.TransactionImportEnabled)
{ {
@@ -233,20 +230,26 @@ namespace bnhtrade.Core.Logic.Stock
} }
// update the amazon report table // update the amazon report table
dbAmznReport.UpdateIsProcessed(item.FbaReimbursementReportID, true, transId); dbAmznReport.UpdateIsProcessed(item.FbaReimbursementReportID, true, transId);
transposeCount = transposeCount + 1; importedCount++;
} }
// drop out of loop // drop out of loop
scope.Complete(); scope.Complete();
} }
Console.Write("\r"); Console.Write("\r");
log.LogInformation("ProcessFbaReimbursementData() complete, " + transposeCount + " total records transposed, " + transposeSkip + " records skipped.");
log.LogInformation(
methodName + " complete. Records transferred/processed " + importedCount + "/" + processedCount
);
} }
catch (Exception ex) catch (Exception ex)
{ {
log.LogError("Exception catch, aborting ProcessFbaReimbursementData(), see detailed info. " log.LogError(
+ transposeCount + " total records completed, " + transposeSkip + " records skipped.", ex.ToString()); methodName + " aborted due an exception, no records where modified."
} , ex.ToString()
);
throw;
}
} }
/// <summary> /// <summary>
@@ -255,12 +258,11 @@ namespace bnhtrade.Core.Logic.Stock
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public void ImportAmazonFbaLedgerDetail() public void ImportAmazonFbaLedgerDetail()
{ {
// Done but needs testing!! string methodName = "Import 'Amazon FBA Ledger Detail' into 'Stock SKU Transactions'";
throw new NotImplementedException("Done but needs testing!!");
log.LogInformation("Starting TransposeFbaAdustmentReport()"); log.LogInformation(methodName + " started");
int transposeCount = 0; int transferredCount = 0;
int transposeSkip = 0; int processedCount = 0;
using (var scope = new TransactionScope()) using (var scope = new TransactionScope())
{ {
@@ -275,6 +277,8 @@ namespace bnhtrade.Core.Logic.Stock
var transCodeToJournalTypeId = new Dictionary<string, int>(); var transCodeToJournalTypeId = new Dictionary<string, int>();
foreach (var item in reportDict) foreach (var item in reportDict)
{ {
processedCount++;
// test for internal Amazon stuff that we don't care about and mark as processed // test for internal Amazon stuff that we don't care about and mark as processed
if (item.Value.EventType == "WhseTransfers") if (item.Value.EventType == "WhseTransfers")
{ {
@@ -340,8 +344,11 @@ namespace bnhtrade.Core.Logic.Stock
} }
} }
// check for any new types codes, and add them if ther are // check for any new types codes, remove existing from list and add remaing to db
using (TransactionScope scope2 = new TransactionScope(TransactionScopeOption.Suppress))
{
var dbTransType = new Logic.Stock.SkuTransactionTypeCrud(); var dbTransType = new Logic.Stock.SkuTransactionTypeCrud();
var transTypeList = dbTransType.GetByTypeCode(transCodeToJournalTypeId.Keys.ToList()); var transTypeList = dbTransType.GetByTypeCode(transCodeToJournalTypeId.Keys.ToList());
foreach (var transType in transTypeList) foreach (var transType in transTypeList)
@@ -356,6 +363,7 @@ namespace bnhtrade.Core.Logic.Stock
{ {
dbTransType.Create(newItem.Key, newItem.Value); dbTransType.Create(newItem.Key, newItem.Value);
} }
}
// finally, add the transction list to the table // finally, add the transction list to the table
var dbTransaction = new Logic.Stock.SkuTransactionCrud(); var dbTransaction = new Logic.Stock.SkuTransactionCrud();
@@ -363,33 +371,28 @@ namespace bnhtrade.Core.Logic.Stock
{ {
int id = dbTransaction.Create(item); int id = dbTransaction.Create(item);
dbImport.UpdateIsProcessed((int)item.ForeignKey, id); dbImport.UpdateIsProcessed((int)item.ForeignKey, id);
transferredCount++;
} }
scope.Complete(); scope.Complete();
log.LogInformation( log.LogInformation(
"TransposeFbaAdustmentReport() complete, " + transposeCount + " total records transposed, " + transposeSkip + " records skipped." methodName + " complete. Records transferred/processed " + transferredCount + "/" + processedCount
); );
if (transposeSkip > 0)
{
log.LogInformation(
transposeSkip + " number records skipped during TransposeFbaAdustmentReport() operation."
);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
scope.Dispose(); scope.Dispose();
log.LogError( log.LogError(
"Exception catch, aborting TransposeFbaAdustmentReport(), see detailed info. " methodName + " aborted, no records modified. See additional info exception details."
+ transposeCount + " total records completed, " + transposeSkip + " records skipped."
, ex.ToString() , ex.ToString()
); );
}
} throw;
return; }
}
} }
} }
} }

View File

@@ -25,15 +25,15 @@ namespace bnhtrade.Core.Logic.Stock
/// <param name="stockJournalTypeId"></param> /// <param name="stockJournalTypeId"></param>
/// <returns>Id for new record entry</returns> /// <returns>Id for new record entry</returns>
/// <exception cref="InvalidOperationException">Transaction type code already exists</exception> /// <exception cref="InvalidOperationException">Transaction type code already exists</exception>
public int Create(string skuTransactionTypeCode, int stockJournalTypeId) public int Create(string skuTransactionTypeCode, int stockJournalTypeId, bool transactionScopeSuppress = false)
{ {
//check to see if type already exists //check to see if type already exists
var result = dbRead.ByTypeCode(new List<string> { skuTransactionTypeCode }); var result = dbRead.ByTypeCode(new List<string> { skuTransactionTypeCode }, transactionScopeSuppress);
if (result.Any()) if (result.Any())
throw new InvalidOperationException("Create SKU Transaction Type failed, typecode already exists failed"); throw new InvalidOperationException("Create SKU Transaction Type failed, typecode already exists failed");
// okay to proceed // okay to proceed
int id = new Data.Database.Stock.InsertSkuTransactionType().Create(skuTransactionTypeCode, stockJournalTypeId); int id = new Data.Database.Stock.InsertSkuTransactionType().Create(skuTransactionTypeCode, stockJournalTypeId, transactionScopeSuppress);
return id; return id;
} }
@@ -42,14 +42,14 @@ namespace bnhtrade.Core.Logic.Stock
/// </summary> /// </summary>
/// <param name="typeCode"></param> /// <param name="typeCode"></param>
/// <returns>The object, or null</returns> /// <returns>The object, or null</returns>
public Model.Stock.SkuTransactionType GetByTypeCode(string typeCode) public Model.Stock.SkuTransactionType GetByTypeCode(string typeCode, bool transactionScopeSuppress = false)
{ {
if (string.IsNullOrWhiteSpace(typeCode)) if (string.IsNullOrWhiteSpace(typeCode))
{ {
return null; return null;
} }
var result = dbRead.ByTypeCode(new List<string> { typeCode }); var result = dbRead.ByTypeCode(new List<string> { typeCode }, transactionScopeSuppress);
if (result.Any()) if (result.Any())
{ {
@@ -66,7 +66,7 @@ namespace bnhtrade.Core.Logic.Stock
/// </summary> /// </summary>
/// <param name="typeCodeList">list of transaction type codes</param> /// <param name="typeCodeList">list of transaction type codes</param>
/// <returns>DIctionary key=transactionTypeCode, value=transactionType object</returns> /// <returns>DIctionary key=transactionTypeCode, value=transactionType object</returns>
public Dictionary<string, Model.Stock.SkuTransactionType> GetByTypeCode(List<string> typeCodeList) public Dictionary<string, Model.Stock.SkuTransactionType> GetByTypeCode(List<string> typeCodeList, bool transactionScopeSuppress = false)
{ {
var returnDict = new Dictionary<string, Model.Stock.SkuTransactionType>(); var returnDict = new Dictionary<string, Model.Stock.SkuTransactionType>();
if (!typeCodeList.Any()) if (!typeCodeList.Any())
@@ -74,7 +74,7 @@ namespace bnhtrade.Core.Logic.Stock
return returnDict; return returnDict;
} }
var dbResult = dbRead.ByTypeCode(typeCodeList); var dbResult = dbRead.ByTypeCode(typeCodeList, transactionScopeSuppress);
foreach(var item in dbResult) foreach(var item in dbResult)
{ {

View 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);
}
}
}

View File

@@ -8,9 +8,9 @@ namespace bnhtrade.Core.Logic.Utilities
{ {
public class DateTimeCheck : Validate.Validate 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."); ValidationResultAdd( "DateTime value set to default.");
return false; return false;
@@ -22,9 +22,9 @@ namespace bnhtrade.Core.Logic.Utilities
} }
return true; 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."); ValidationResultAdd("DateTime value set to default.");
return false; return false;

View File

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

View 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);
}
}
}

View File

@@ -21,6 +21,7 @@ namespace bnhtrade.Core.Logic.Utilities
var export = new bnhtrade.Core.Logic.Export.AmazonSettlement(); var export = new bnhtrade.Core.Logic.Export.AmazonSettlement();
bool stockUpdate = false; bool stockUpdate = false;
bool exchangeRate = false;
bool accountProcess = false; bool accountProcess = false;
while (true) while (true)
@@ -28,6 +29,7 @@ namespace bnhtrade.Core.Logic.Utilities
try try
{ {
if (stockUpdate == false) { stockUpdate = true; new bnhtrade.Core.Logic.Import.Amazon().SyncAllWithDatabase(); ; } 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 (accountProcess == false) { accountProcess = true; export.ToInvoice(); }
// if (stockProcess == false) { stockProcess = true; stock.ProcessFbaStockImportData(); } // if (stockProcess == false) { stockProcess = true; stock.ProcessFbaStockImportData(); }

View File

@@ -15,7 +15,10 @@ namespace bnhtrade.Core.Logic.Validate
/// <returns></returns> /// <returns></returns>
public static bool SkuNumber(string skuNumber) public static bool SkuNumber(string skuNumber)
{ {
if (string.IsNullOrEmpty(skuNumber)) { return false;} if (string.IsNullOrEmpty(skuNumber))
{
return false;
}
int count = 0; int count = 0;
foreach (char c in skuNumber) foreach (char c in skuNumber)
@@ -50,11 +53,17 @@ namespace bnhtrade.Core.Logic.Validate
public static bool DateTime(DateTime dateTime) public static bool DateTime(DateTime dateTime)
{ {
if (dateTime == default(DateTime)) if (dateTime == default(DateTime))
{ return false; } {
return false;
}
else if (dateTime.Kind != DateTimeKind.Utc) else if (dateTime.Kind != DateTimeKind.Utc)
{ return false; } {
return false;
}
else else
{ return true; } {
return true;
}
} }
} }
} }

View 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
}
}

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

View File

@@ -42,7 +42,7 @@ namespace bnhtrade.Core.Model.Account
public abstract class Invoice : InvoiceHeader, IInvoice public abstract class Invoice : InvoiceHeader, IInvoice
{ {
private bool unitAmountIsTaxExclusive = true; private bool unitAmountIsTaxExclusive = false;
public decimal InvoiceNetAmount { get; } public decimal InvoiceNetAmount { get; }

View File

@@ -28,7 +28,7 @@ namespace bnhtrade.Core.Model.Credentials
{ {
return "Data Source=" + DataSource + ";Initial Catalog=" + InitialCatalog + ";Persist Security Info=" + PersistSecurityInfo.ToString() return "Data Source=" + DataSource + ";Initial Catalog=" + InitialCatalog + ";Persist Security Info=" + PersistSecurityInfo.ToString()
+ ";User ID=" + UserId + ";Password=" + UserPassword + ";MultipleActiveResultSets=" + MultipleActiveResultSets.ToString() + ";User ID=" + UserId + ";Password=" + UserPassword + ";MultipleActiveResultSets=" + MultipleActiveResultSets.ToString()
+ ";Connect Timeout=" + ConnectionTimeout; + ";Connect Timeout=" + ConnectionTimeout + ";Encrypt=True;TrustServerCertificate=True";
} }
} }

View File

@@ -54,7 +54,7 @@ namespace bnhtrade.Core.Model.Stock
{ {
var result = new List<ValidationResult>(); var result = new List<ValidationResult>();
if (Logic.Validate.Format.DateTime(TransactionDate)) if (Logic.Validate.Format.DateTime(TransactionDate) == false)
{ {
result.Add(new ValidationResult("Invalid transaction date")); result.Add(new ValidationResult("Invalid transaction date"));
} }
@@ -62,7 +62,7 @@ namespace bnhtrade.Core.Model.Stock
{ {
result.Add(new ValidationResult("Invalid transaction type code")); result.Add(new ValidationResult("Invalid transaction type code"));
} }
if (Logic.Validate.Format.SkuNumber(SkuNumber)) if (Logic.Validate.Format.SkuNumber(SkuNumber) == false)
{ {
result.Add(new ValidationResult("Invalid SKU number")); result.Add(new ValidationResult("Invalid SKU number"));
} }

View File

@@ -12,7 +12,7 @@ namespace bnhtrade.Core.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

View File

@@ -1,9 +1,12 @@
using System; using bnhtrade.Core.Data.Database.Account;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms.Design; using System.Windows.Forms.Design;
using System.Xml;
using System.Xml.Linq;
namespace bnhtrade.Core.Test.Account namespace bnhtrade.Core.Test.Account
{ {
@@ -11,7 +14,13 @@ namespace bnhtrade.Core.Test.Account
{ {
public Account() public Account()
{ {
Journal(); UpdateHmrcExchageRates();
}
public void UpdateHmrcExchageRates()
{
var logic = new bnhtrade.Core.Logic.Account.Currency();
logic.UpdateHmrcExchageRates();
} }
public void PurchaseInvoice() public void PurchaseInvoice()

View File

@@ -5,6 +5,8 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets> <ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<!--Added the line below to copy all dll from .nuget folder to build output folder-->
<!--CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies-->
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
@@ -30,28 +32,30 @@
<Folder Include="Test\Product\" /> <Folder Include="Test\Product\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Analyzer Include="..\..\packages\AWSSDK.SecurityToken.3.7.300.76\analyzers\dotnet\cs\AWSSDK.SecurityToken.CodeAnalysis.dll" /> <PackageReference Include="AWSSDK.Core" Version="3.7.402.47" />
<Analyzer Include="..\..\packages\AWSSDK.SecurityToken.3.7.300.76\analyzers\dotnet\cs\SharedAnalysisCode.dll" />
<Analyzer Include="..\..\packages\AWSSDK.SQS.3.7.300.75\analyzers\dotnet\cs\AWSSDK.SQS.CodeAnalysis.dll" />
<Analyzer Include="..\..\packages\AWSSDK.SQS.3.7.300.75\analyzers\dotnet\cs\SharedAnalysisCode.dll" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.7.303.15" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.300.76">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="CSharpAmazonSpAPI" Version="1.7.17" /> <PackageReference Include="CSharpAmazonSpAPI" Version="1.7.17" />
<PackageReference Include="CsvHelper" Version="31.0.4" /> <PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="Dapper" Version="2.1.35" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Dapper.Contrib" Version="2.0.78"> <PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
<TreatAsUsed>true</TreatAsUsed> <PackageReference Include="RestSharp" Version="112.1.0" />
</PackageReference> <PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="112.1.0" />
<PackageReference Include="RestSharp" Version="110.2.0" /> <PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="110.2.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Data\Database\Product\UpdateAmazonFeeEstimate.cs" /> <Compile Remove="Data\Database\Product\UpdateAmazonFeeEstimate.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project> </Project>

View File

@@ -25,6 +25,7 @@ namespace bnhtradeScheduledTasks
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("<1> Amazon reports"); Console.WriteLine("<1> Amazon reports");
Console.WriteLine("<2> Stock functions"); Console.WriteLine("<2> Stock functions");
Console.WriteLine("<3> Account functions");
Console.WriteLine(""); Console.WriteLine("");
Console.WriteLine("<8> Start scheduled nightly tasks"); Console.WriteLine("<8> Start scheduled nightly tasks");
Console.WriteLine("<9> Dev functions"); Console.WriteLine("<9> Dev functions");
@@ -50,12 +51,12 @@ namespace bnhtradeScheduledTasks
Console.WriteLine("<1> Start nightly tasks"); Console.WriteLine("<1> Start nightly tasks");
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("<2> Update FBA Inventory Data"); Console.WriteLine("<2> Update FBA Inventory Data");
Console.WriteLine("<3> Update FBA Inventory Age Data"); Console.WriteLine("<3> Update FBA Inventory Ledger Data (new)");
Console.WriteLine("<4> Update Amazon Settlement Data"); Console.WriteLine("<4> Update Amazon Settlement Data");
Console.WriteLine("<5> Update Fba Inventory Receipt Data"); Console.WriteLine("<5> (depreciated) Update Fba Inventory Receipt Data");
Console.WriteLine("<6> Update Fba Sale Shipment Data"); Console.WriteLine("<6> Update Fba Sale Shipment Data");
Console.WriteLine("<7> Update Fba Return Data"); Console.WriteLine("<7> Update Fba Return Data");
Console.WriteLine("<8> Update Fba Adustment Data"); Console.WriteLine("<8> (depreciated) Update Fba Adustment Data");
Console.WriteLine("<9> Update Fba Removal Order Data"); Console.WriteLine("<9> Update Fba Removal Order Data");
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("<0> Back"); Console.WriteLine("<0> Back");
@@ -84,7 +85,7 @@ namespace bnhtradeScheduledTasks
else if (input == "3") else if (input == "3")
{ {
Console.Clear(); Console.Clear();
new bnhtrade.Core.Logic.Import.AmazonFbaInventoryAge().SyncDatabaseWithAmazon(); new bnhtrade.Core.Logic.Import.AmazonFbaInventoryLedgerDetail().SyncDatabaseWithAmazon();
Console.WriteLine("Complete, press any key to continue..."); Console.WriteLine("Complete, press any key to continue...");
Console.ReadKey(); Console.ReadKey();
} }
@@ -242,6 +243,34 @@ namespace bnhtradeScheduledTasks
} while (true); } 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") else if (input == "8")
{ {
Console.Clear(); Console.Clear();

View File

@@ -64,8 +64,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.4" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<AssemblyTitle>bnhtrade Scheduled Tasks</AssemblyTitle> <AssemblyTitle>bnhtrade Scheduled Tasks</AssemblyTitle>

72
src/bnhtrade.gui/FormConsole.Designer.cs generated Normal file
View 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;
}
}

View 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();
}
}
}

View 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>

View File

@@ -48,11 +48,14 @@
dateTimeOrderSearch = new DateTimePicker(); dateTimeOrderSearch = new DateTimePicker();
label1 = new Label(); label1 = new Label();
textboxOrderSearch = new TextBox(); textboxOrderSearch = new TextBox();
tabAccounts = new TabPage();
btnExchangeRate = new Button();
tabControl1.SuspendLayout(); tabControl1.SuspendLayout();
Receiving.SuspendLayout(); Receiving.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
((System.ComponentModel.ISupportInitialize)bsReceivingLines).BeginInit(); ((System.ComponentModel.ISupportInitialize)bsReceivingLines).BeginInit();
((System.ComponentModel.ISupportInitialize)purchaseLineStatusBindingSource).BeginInit(); ((System.ComponentModel.ISupportInitialize)purchaseLineStatusBindingSource).BeginInit();
tabAccounts.SuspendLayout();
SuspendLayout(); SuspendLayout();
// //
// tabControl1 // tabControl1
@@ -61,19 +64,22 @@
tabControl1.Controls.Add(tabPage1); tabControl1.Controls.Add(tabPage1);
tabControl1.Controls.Add(tabPage2); tabControl1.Controls.Add(tabPage2);
tabControl1.Controls.Add(Receiving); tabControl1.Controls.Add(Receiving);
tabControl1.Location = new Point(12, 12); tabControl1.Controls.Add(tabAccounts);
tabControl1.Location = new Point(14, 16);
tabControl1.Margin = new Padding(3, 4, 3, 4);
tabControl1.Name = "tabControl1"; tabControl1.Name = "tabControl1";
tabControl1.SelectedIndex = 0; tabControl1.SelectedIndex = 0;
tabControl1.Size = new Size(1022, 533); tabControl1.Size = new Size(1168, 711);
tabControl1.TabIndex = 0; tabControl1.TabIndex = 0;
tabControl1.SelectedIndexChanged += tabControl1_SelectedIndexChanged; tabControl1.SelectedIndexChanged += tabControl1_SelectedIndexChanged;
// //
// tabPage1 // tabPage1
// //
tabPage1.Location = new Point(4, 24); tabPage1.Location = new Point(4, 29);
tabPage1.Margin = new Padding(3, 4, 3, 4);
tabPage1.Name = "tabPage1"; tabPage1.Name = "tabPage1";
tabPage1.Padding = new Padding(3); tabPage1.Padding = new Padding(3, 4, 3, 4);
tabPage1.Size = new Size(1014, 505); tabPage1.Size = new Size(1160, 678);
tabPage1.TabIndex = 0; tabPage1.TabIndex = 0;
tabPage1.Text = "Home"; tabPage1.Text = "Home";
tabPage1.UseVisualStyleBackColor = true; tabPage1.UseVisualStyleBackColor = true;
@@ -81,10 +87,11 @@
// tabPage2 // tabPage2
// //
tabPage2.AccessibleName = ""; tabPage2.AccessibleName = "";
tabPage2.Location = new Point(4, 24); tabPage2.Location = new Point(4, 29);
tabPage2.Margin = new Padding(3, 4, 3, 4);
tabPage2.Name = "tabPage2"; tabPage2.Name = "tabPage2";
tabPage2.Padding = new Padding(3); tabPage2.Padding = new Padding(3, 4, 3, 4);
tabPage2.Size = new Size(1014, 505); tabPage2.Size = new Size(1160, 678);
tabPage2.TabIndex = 1; tabPage2.TabIndex = 1;
tabPage2.Text = "FBA Shipments"; tabPage2.Text = "FBA Shipments";
tabPage2.UseVisualStyleBackColor = true; tabPage2.UseVisualStyleBackColor = true;
@@ -98,10 +105,11 @@
Receiving.Controls.Add(dateTimeOrderSearch); Receiving.Controls.Add(dateTimeOrderSearch);
Receiving.Controls.Add(label1); Receiving.Controls.Add(label1);
Receiving.Controls.Add(textboxOrderSearch); Receiving.Controls.Add(textboxOrderSearch);
Receiving.Location = new Point(4, 24); Receiving.Location = new Point(4, 29);
Receiving.Margin = new Padding(3, 4, 3, 4);
Receiving.Name = "Receiving"; Receiving.Name = "Receiving";
Receiving.Padding = new Padding(3); Receiving.Padding = new Padding(3, 4, 3, 4);
Receiving.Size = new Size(1014, 505); Receiving.Size = new Size(1160, 678);
Receiving.TabIndex = 2; Receiving.TabIndex = 2;
Receiving.Text = "Receiving"; Receiving.Text = "Receiving";
Receiving.UseVisualStyleBackColor = true; Receiving.UseVisualStyleBackColor = true;
@@ -111,10 +119,10 @@
// //
labelDataGridCount.Anchor = AnchorStyles.Right; labelDataGridCount.Anchor = AnchorStyles.Right;
labelDataGridCount.ImageAlign = ContentAlignment.MiddleRight; labelDataGridCount.ImageAlign = ContentAlignment.MiddleRight;
labelDataGridCount.Location = new Point(857, 70); labelDataGridCount.Location = new Point(979, 93);
labelDataGridCount.Name = "labelDataGridCount"; labelDataGridCount.Name = "labelDataGridCount";
labelDataGridCount.RightToLeft = RightToLeft.Yes; labelDataGridCount.RightToLeft = RightToLeft.Yes;
labelDataGridCount.Size = new Size(129, 21); labelDataGridCount.Size = new Size(147, 28);
labelDataGridCount.TabIndex = 6; labelDataGridCount.TabIndex = 6;
labelDataGridCount.Text = "labelListCount"; labelDataGridCount.Text = "labelListCount";
labelDataGridCount.TextAlign = ContentAlignment.MiddleLeft; labelDataGridCount.TextAlign = ContentAlignment.MiddleLeft;
@@ -126,11 +134,13 @@
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView1.Columns.AddRange(new DataGridViewColumn[] { purchaseNumberDataGridViewTextBoxColumn, purchaseDateDataGridViewTextBoxColumn, itemDescriptionDataGridViewTextBoxColumn, purchaseLineIdDataGridViewTextBoxColumn, lineStatusDataGridViewTextBoxColumn, purchaseIdDataGridViewTextBoxColumn }); dataGridView1.Columns.AddRange(new DataGridViewColumn[] { purchaseNumberDataGridViewTextBoxColumn, purchaseDateDataGridViewTextBoxColumn, itemDescriptionDataGridViewTextBoxColumn, purchaseLineIdDataGridViewTextBoxColumn, lineStatusDataGridViewTextBoxColumn, purchaseIdDataGridViewTextBoxColumn });
dataGridView1.DataSource = bsReceivingLines; dataGridView1.DataSource = bsReceivingLines;
dataGridView1.Location = new Point(31, 94); dataGridView1.Location = new Point(35, 125);
dataGridView1.Margin = new Padding(3, 4, 3, 4);
dataGridView1.MultiSelect = false; dataGridView1.MultiSelect = false;
dataGridView1.Name = "dataGridView1"; dataGridView1.Name = "dataGridView1";
dataGridView1.RowHeadersWidth = 51;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView1.Size = new Size(955, 396); dataGridView1.Size = new Size(1091, 528);
dataGridView1.TabIndex = 5; dataGridView1.TabIndex = 5;
dataGridView1.DoubleClick += dataGridView1_DoubleClick; dataGridView1.DoubleClick += dataGridView1_DoubleClick;
// //
@@ -138,18 +148,23 @@
// //
purchaseNumberDataGridViewTextBoxColumn.DataPropertyName = "PurchaseNumber"; purchaseNumberDataGridViewTextBoxColumn.DataPropertyName = "PurchaseNumber";
purchaseNumberDataGridViewTextBoxColumn.HeaderText = "PurchaseNumber"; purchaseNumberDataGridViewTextBoxColumn.HeaderText = "PurchaseNumber";
purchaseNumberDataGridViewTextBoxColumn.MinimumWidth = 6;
purchaseNumberDataGridViewTextBoxColumn.Name = "purchaseNumberDataGridViewTextBoxColumn"; purchaseNumberDataGridViewTextBoxColumn.Name = "purchaseNumberDataGridViewTextBoxColumn";
purchaseNumberDataGridViewTextBoxColumn.Width = 125;
// //
// purchaseDateDataGridViewTextBoxColumn // purchaseDateDataGridViewTextBoxColumn
// //
purchaseDateDataGridViewTextBoxColumn.DataPropertyName = "PurchaseDate"; purchaseDateDataGridViewTextBoxColumn.DataPropertyName = "PurchaseDate";
purchaseDateDataGridViewTextBoxColumn.HeaderText = "PurchaseDate"; purchaseDateDataGridViewTextBoxColumn.HeaderText = "PurchaseDate";
purchaseDateDataGridViewTextBoxColumn.MinimumWidth = 6;
purchaseDateDataGridViewTextBoxColumn.Name = "purchaseDateDataGridViewTextBoxColumn"; purchaseDateDataGridViewTextBoxColumn.Name = "purchaseDateDataGridViewTextBoxColumn";
purchaseDateDataGridViewTextBoxColumn.Width = 125;
// //
// itemDescriptionDataGridViewTextBoxColumn // itemDescriptionDataGridViewTextBoxColumn
// //
itemDescriptionDataGridViewTextBoxColumn.DataPropertyName = "ItemDescription"; itemDescriptionDataGridViewTextBoxColumn.DataPropertyName = "ItemDescription";
itemDescriptionDataGridViewTextBoxColumn.HeaderText = "ItemDescription"; itemDescriptionDataGridViewTextBoxColumn.HeaderText = "ItemDescription";
itemDescriptionDataGridViewTextBoxColumn.MinimumWidth = 6;
itemDescriptionDataGridViewTextBoxColumn.Name = "itemDescriptionDataGridViewTextBoxColumn"; itemDescriptionDataGridViewTextBoxColumn.Name = "itemDescriptionDataGridViewTextBoxColumn";
itemDescriptionDataGridViewTextBoxColumn.Width = 500; itemDescriptionDataGridViewTextBoxColumn.Width = 500;
// //
@@ -157,19 +172,25 @@
// //
purchaseLineIdDataGridViewTextBoxColumn.DataPropertyName = "PurchaseLineId"; purchaseLineIdDataGridViewTextBoxColumn.DataPropertyName = "PurchaseLineId";
purchaseLineIdDataGridViewTextBoxColumn.HeaderText = "PurchaseLineId"; purchaseLineIdDataGridViewTextBoxColumn.HeaderText = "PurchaseLineId";
purchaseLineIdDataGridViewTextBoxColumn.MinimumWidth = 6;
purchaseLineIdDataGridViewTextBoxColumn.Name = "purchaseLineIdDataGridViewTextBoxColumn"; purchaseLineIdDataGridViewTextBoxColumn.Name = "purchaseLineIdDataGridViewTextBoxColumn";
purchaseLineIdDataGridViewTextBoxColumn.Width = 125;
// //
// lineStatusDataGridViewTextBoxColumn // lineStatusDataGridViewTextBoxColumn
// //
lineStatusDataGridViewTextBoxColumn.DataPropertyName = "LineStatus"; lineStatusDataGridViewTextBoxColumn.DataPropertyName = "LineStatus";
lineStatusDataGridViewTextBoxColumn.HeaderText = "LineStatus"; lineStatusDataGridViewTextBoxColumn.HeaderText = "LineStatus";
lineStatusDataGridViewTextBoxColumn.MinimumWidth = 6;
lineStatusDataGridViewTextBoxColumn.Name = "lineStatusDataGridViewTextBoxColumn"; lineStatusDataGridViewTextBoxColumn.Name = "lineStatusDataGridViewTextBoxColumn";
lineStatusDataGridViewTextBoxColumn.Width = 125;
// //
// purchaseIdDataGridViewTextBoxColumn // purchaseIdDataGridViewTextBoxColumn
// //
purchaseIdDataGridViewTextBoxColumn.DataPropertyName = "PurchaseId"; purchaseIdDataGridViewTextBoxColumn.DataPropertyName = "PurchaseId";
purchaseIdDataGridViewTextBoxColumn.HeaderText = "PurchaseId"; purchaseIdDataGridViewTextBoxColumn.HeaderText = "PurchaseId";
purchaseIdDataGridViewTextBoxColumn.MinimumWidth = 6;
purchaseIdDataGridViewTextBoxColumn.Name = "purchaseIdDataGridViewTextBoxColumn"; purchaseIdDataGridViewTextBoxColumn.Name = "purchaseIdDataGridViewTextBoxColumn";
purchaseIdDataGridViewTextBoxColumn.Width = 125;
// //
// bsReceivingLines // bsReceivingLines
// //
@@ -177,9 +198,10 @@
// //
// buttonSearch // buttonSearch
// //
buttonSearch.Location = new Point(865, 37); buttonSearch.Location = new Point(989, 49);
buttonSearch.Margin = new Padding(3, 4, 3, 4);
buttonSearch.Name = "buttonSearch"; buttonSearch.Name = "buttonSearch";
buttonSearch.Size = new Size(109, 25); buttonSearch.Size = new Size(125, 33);
buttonSearch.TabIndex = 4; buttonSearch.TabIndex = 4;
buttonSearch.Text = "Search"; buttonSearch.Text = "Search";
buttonSearch.UseVisualStyleBackColor = true; buttonSearch.UseVisualStyleBackColor = true;
@@ -190,9 +212,10 @@
comboBox1.DataSource = purchaseLineStatusBindingSource; comboBox1.DataSource = purchaseLineStatusBindingSource;
comboBox1.DisplayMember = "PurchaseLineStatusName"; comboBox1.DisplayMember = "PurchaseLineStatusName";
comboBox1.FormattingEnabled = true; comboBox1.FormattingEnabled = true;
comboBox1.Location = new Point(195, 39); comboBox1.Location = new Point(223, 52);
comboBox1.Margin = new Padding(3, 4, 3, 4);
comboBox1.Name = "comboBox1"; comboBox1.Name = "comboBox1";
comboBox1.Size = new Size(189, 23); comboBox1.Size = new Size(215, 28);
comboBox1.TabIndex = 3; comboBox1.TabIndex = 3;
comboBox1.ValueMember = "PurchaseLineStatusId"; comboBox1.ValueMember = "PurchaseLineStatusId";
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged; comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
@@ -204,35 +227,59 @@
// //
// dateTimeOrderSearch // dateTimeOrderSearch
// //
dateTimeOrderSearch.Location = new Point(31, 39); dateTimeOrderSearch.Location = new Point(35, 52);
dateTimeOrderSearch.Margin = new Padding(3, 4, 3, 4);
dateTimeOrderSearch.Name = "dateTimeOrderSearch"; dateTimeOrderSearch.Name = "dateTimeOrderSearch";
dateTimeOrderSearch.Size = new Size(131, 23); dateTimeOrderSearch.Size = new Size(149, 27);
dateTimeOrderSearch.TabIndex = 2; dateTimeOrderSearch.TabIndex = 2;
dateTimeOrderSearch.ValueChanged += dateTimeOrderSearch_ValueChanged; dateTimeOrderSearch.ValueChanged += dateTimeOrderSearch_ValueChanged;
// //
// label1 // label1
// //
label1.AutoSize = true; label1.AutoSize = true;
label1.Location = new Point(31, 21); label1.Location = new Point(35, 28);
label1.Name = "label1"; label1.Name = "label1";
label1.Size = new Size(75, 15); label1.Size = new Size(95, 20);
label1.TabIndex = 1; label1.TabIndex = 1;
label1.Text = "Order Search"; label1.Text = "Order Search";
// //
// textboxOrderSearch // textboxOrderSearch
// //
textboxOrderSearch.Location = new Point(417, 39); textboxOrderSearch.Location = new Point(477, 52);
textboxOrderSearch.Margin = new Padding(3, 4, 3, 4);
textboxOrderSearch.Name = "textboxOrderSearch"; textboxOrderSearch.Name = "textboxOrderSearch";
textboxOrderSearch.Size = new Size(415, 23); textboxOrderSearch.Size = new Size(474, 27);
textboxOrderSearch.TabIndex = 0; textboxOrderSearch.TabIndex = 0;
textboxOrderSearch.KeyPress += textboxOrderSearch_KeyPress; textboxOrderSearch.KeyPress += textboxOrderSearch_KeyPress;
// //
// tabAccounts
//
tabAccounts.Controls.Add(btnExchangeRate);
tabAccounts.Location = new Point(4, 29);
tabAccounts.Name = "tabAccounts";
tabAccounts.Padding = new Padding(3);
tabAccounts.Size = new Size(1160, 678);
tabAccounts.TabIndex = 3;
tabAccounts.Text = "Accounts";
tabAccounts.UseVisualStyleBackColor = true;
//
// btnExchangeRate
//
btnExchangeRate.Location = new Point(48, 50);
btnExchangeRate.Name = "btnExchangeRate";
btnExchangeRate.Size = new Size(237, 50);
btnExchangeRate.TabIndex = 0;
btnExchangeRate.Text = "Update exchange rates";
btnExchangeRate.UseVisualStyleBackColor = true;
btnExchangeRate.Click += btnExchangeRate_Click;
//
// Home // Home
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1046, 557); ClientSize = new Size(1195, 743);
Controls.Add(tabControl1); Controls.Add(tabControl1);
Margin = new Padding(3, 4, 3, 4);
Name = "Home"; Name = "Home";
Text = "Form1"; Text = "Form1";
Load += Form1_Load; Load += Form1_Load;
@@ -242,6 +289,7 @@
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit(); ((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
((System.ComponentModel.ISupportInitialize)bsReceivingLines).EndInit(); ((System.ComponentModel.ISupportInitialize)bsReceivingLines).EndInit();
((System.ComponentModel.ISupportInitialize)purchaseLineStatusBindingSource).EndInit(); ((System.ComponentModel.ISupportInitialize)purchaseLineStatusBindingSource).EndInit();
tabAccounts.ResumeLayout(false);
ResumeLayout(false); ResumeLayout(false);
} }
@@ -266,5 +314,7 @@
private DataGridViewTextBoxColumn lineStatusDataGridViewTextBoxColumn; private DataGridViewTextBoxColumn lineStatusDataGridViewTextBoxColumn;
private DataGridViewTextBoxColumn purchaseIdDataGridViewTextBoxColumn; private DataGridViewTextBoxColumn purchaseIdDataGridViewTextBoxColumn;
private Label labelDataGridCount; private Label labelDataGridCount;
private TabPage tabAccounts;
private Button btnExchangeRate;
} }
} }

View File

@@ -110,5 +110,12 @@ namespace bnhtrade.gui
var form = new PurchaseInvoice(purchaseInvoice); var form = new PurchaseInvoice(purchaseInvoice);
form.Show(); form.Show();
} }
private void btnExchangeRate_Click(object sender, EventArgs e)
{
var myForm = new FormConsole();
myForm.Show();
new bnhtrade.Core.Logic.Account.Currency().UpdateHmrcExchageRates();
}
} }
} }

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