using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using bnhtradeDatabaseClient.Product; using bnhtradeDatabaseClient.EbayQuery; using bnhtradeDatabaseClient.Database; using bnhtradeDatabaseClient; using bnhtradeDatabaseClient; using System.Data.SqlClient; using System.IO; using System.Reflection; using static Vba6.StockQuery; namespace Vba6 { [ComVisible(true)] [Guid("033326dd-6edb-4343-8334-4c31acf3565e")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IConnectionCredential { string UserId { get; set; } string Password { get; set; } string ConnectionString { get; } } [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsDual)] [Guid("b670a3fc-feeb-487b-ad25-89a1115e9aa5")] public interface IVbaSqlConnection { SqlConnection GetSqlConnection(ConnectionCredential vbaConnCred); } [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsDual)] [Guid("05860bc9-6a6d-4b8f-a611-3921c4b4755c")] public interface IEbayQuery { int EbayListingItemGet(string itemNumber, DateTime listingEnd, ConnectionCredential sqlConnCred); object[] EbayListingItemInsert(string itemNumber, DateTime listingEnd, string listingTitle, string listingDescription, string ebayUser, bool isAuction, [MarshalAs(UnmanagedType.Currency)] decimal price, DateTime priceTime, [MarshalAs(UnmanagedType.Currency)] decimal shipping, string itemLocation, string category, string imageFilePath, ConnectionCredential sqlConnCred); } [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsDual)] [Guid("0fd536ce-b913-438d-9343-9a1a7a40af71")] public interface IAmazonMws { } [ComVisible(true)] [Guid("90eefc75-11d7-449d-a99f-3e4d1a795ebc")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IPurchaseQuery { void PurchaseLineTransactionNetInsert(ConnectionCredential sqlConnCred, int purchaseLineId, int debitAccountId, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amountNet, DateTime entryDate); void PurchaseLineTransactionNetUpdate(ConnectionCredential sqlConnCred, int accountJouranlId, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amountNet, int debitAccountId); void PurchaseLineTransactionDelete(ConnectionCredential sqlConnCred, int purchaseLineId, int accountJournalId); int PurchaseLineTransactionStockInsert(ConnectionCredential sqlConnCred, int accountJournalId, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, int stockDebitStatusId); void PurchaseLineTransactionStockDelete(ConnectionCredential sqlConnCred, int stockId); } [ComVisible(true)] [Guid("b6215466-7b84-4d1f-807f-6b305a4c05f0")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IAccountQuery { int AccountJournalInsert(ConnectionCredential sqlConnCred, int journalTypeId, DateTime entryDate, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, int debitAccountId = 0, int creditAccountId = 0, bool lockEntry = false); bool AccountJournalDelete(ConnectionCredential sqlConnCred, int accountJournalId); [return: MarshalAs(UnmanagedType.Currency)] decimal CurrencyConvertToGbp(ConnectionCredential sqlConnCred, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, DateTime conversionDate); int CurrencyExchangeRateInsert(ConnectionCredential sqlConnCred, int exchangeRateSource, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false); } [ComVisible(true)] [Guid("ca9ef5b4-f0e6-4b77-9602-0d5f123a1d8d")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IProductQuery { string ReturnStringValue(string stringValue); double ReturnDateValueAsDouble(string stringValue); int ProductGetProductIdByCatId(int catId, ConnectionCredential sqlConnCred); string ProductCompetitivePriceGet(int productId, int conditionId, ConnectionCredential sqlConnCred); int ProductCompetitivePriceSet(int productId, int conditionId, [MarshalAs(UnmanagedType.Currency)] decimal price, bool isBuyBoxPrice, DateTime priceDate, ConnectionCredential sqlConnCred); void ProductUpdateAmazonEstimateFee(ConnectionCredential sqlConnCred, object inputList); } [ComVisible(true)] [Guid("d595d682-8b1e-4aa4-86b7-700e44950e1b")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IStockQuery { int StockInsertPurchase(ConnectionCredential sqlConnCred, int productId, int conditionId, int accountTaxCodeId, int accountJournalId, int quantity, int statusDebitId); int StockInsertOwnerIntroduced(ConnectionCredential sqlConnCred, [MarshalAs(UnmanagedType.Currency)] decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId); void StockDeletePurchase(ConnectionCredential sqlConnCred, int stockId); void StockDeleteOwnerIntroduced(ConnectionCredential sqlConnCred, int stockId); int StockReallocate(ConnectionCredential sqlConnCred, int stockId, int quantity, int debitStatusId, int creditStatusId, DateTime entryDate); void StockJournalDelete(ConnectionCredential sqlConnCred, int stockJournalId); object ReconcileStockTransactions(ConnectionCredential sqlConnCred); bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId); } //[ComVisible(true)] //[Guid("0558e6dc-f5d4-41b6-a51c-856426e77e21")] //[InterfaceType(ComInterfaceType.InterfaceIsDual)] //public interface IReconcileStockTransactionsResult //{ // bool ReconciliationComplete { get; set; } // int StockTransactionId { get; set; } // int StockTransactionTypeId { get; set; } // string ProgressMessage { get; set; } // int ItemsCompleted { get; set; } // int ItemsRemaining { get; set; } // DateTime LastItemDateTime { get; set; } //} [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [Guid("7aa43409-317a-43ad-85f9-2019b5883ab8")] [ProgId("bnhtradeDb.ConnectionCredential")] public class ConnectionCredential : IConnectionCredential { public string UserId { get; set; } public string Password { get; set; } public string ConnectionString { get { return "Data Source=SQL-Server;Initial Catalog=e2A;Persist Security Info=True;User ID=" + UserId + ";Password=" + Password + ";MultipleActiveResultSets=true"; } } } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [Guid("ab7f6468-42db-4f33-8c94-62dc7e1759ea")] [ProgId("bnhtradeDb.Connection")] public class VbaSqlConnection : IVbaSqlConnection { [ComVisible(false)] public SqlConnection GetSqlConnection(ConnectionCredential vbaConnCred) { Connection.DatabaseConnectionDetail connDetail = new Connection.DatabaseConnectionDetail(); connDetail.UserId = vbaConnCred.UserId; connDetail.Password = vbaConnCred.Password; SqlConnection sqlConn = new SqlConnection(connDetail.ConnectionString); return sqlConn; } } [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [Guid("e6743dfa-47d3-4aeb-8f2b-d4e0d5312146")] [ProgId("bnhtradeDb.EbayQuery")] public class EbayQuery : IEbayQuery { public int EbayListingItemGet(string itemNumber, DateTime listingEnd, ConnectionCredential sqlConnCred) { Ebay request = new Ebay(); return request.EbayListingItemGet(sqlConnCred.ConnectionString, itemNumber, listingEnd); } public object[] EbayListingItemInsert(string itemNumber, DateTime listingEnd, string listingTitle, string listingDescription, string ebayUser, bool isAuction, [MarshalAs(UnmanagedType.Currency)] decimal price, DateTime priceTime, [MarshalAs(UnmanagedType.Currency)] decimal shipping, string itemLocation, string category, string imageFilePath, ConnectionCredential sqlConnCred) { // load imagefile FileStream imageFile = null; string imageFileExtension = ""; if (imageFilePath.Length > 0) { imageFileExtension = Path.GetExtension(imageFilePath); if (imageFileExtension == string.Empty) { throw new Exception("Error parsing file extension from file path."); } imageFileExtension = imageFileExtension.Substring(1); imageFile = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read); } // create the return array object Ebay request = new Ebay(); (int ListingItemId, bool IsNewListingItem, bool IsNewListing) result = request.EbayListingItemInsert(sqlConnCred.ConnectionString, itemNumber, listingEnd, listingTitle, listingDescription, ebayUser, isAuction, price, priceTime, shipping, itemLocation, category, imageFile, imageFileExtension); if (imageFile != null) { imageFile.Dispose(); } // create return array object[] returnArray = new object[3]; returnArray[0] = result.ListingItemId; returnArray[1] = result.IsNewListingItem; returnArray[2] = result.IsNewListing; return returnArray; } } [ComVisible(true)] [Guid("23527370-5f3f-47d8-b6a0-35b73890876c")] [ClassInterface(ClassInterfaceType.None)] [ProgId("bnhtradeDb.AmazonMws")] // [ClassInterface(ClassInterfaceType.AutoDual)] public class AmazonMws : IAmazonMws { static void ProductUpdateAmazonEstimateFee() { } } [ComVisible(true)] [Guid("59afd52d-86f4-4863-98e9-7b63a8b3ba51")] [ClassInterface(ClassInterfaceType.None)] [ProgId("bnhtradeDb.ProductQuery")] public class PurchaseQuery : IPurchaseQuery { public void PurchaseLineTransactionNetInsert(ConnectionCredential sqlConnCred, int purchaseLineId, int debitAccountId, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amountNet, DateTime entryDate) { bnhtradeDatabaseClient.Purchase.PurchaseQuery.WIP_PurchaseLineTransactionNetInsert(sqlConnCred.ConnectionString, purchaseLineId, currencyCode, amountNet, entryDate); } public void PurchaseLineTransactionNetUpdate(ConnectionCredential sqlConnCred, int accountJouranlId, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amountNet, int debitAccountId) { bnhtradeDatabaseClient.Purchase.PurchaseQuery.WIP_PurchaseLineTransactionNetUpdate(sqlConnCred.ConnectionString, accountJouranlId, currencyCode, amountNet, debitAccountId); } public void PurchaseLineTransactionDelete(ConnectionCredential sqlConnCred, int purchaseLineId, int accountJournalId) { bnhtradeDatabaseClient.Purchase.PurchaseQuery.WIP_PurchaseLineTransactionDelete(sqlConnCred.ConnectionString, purchaseLineId, accountJournalId); } public int PurchaseLineTransactionStockInsert(ConnectionCredential sqlConnCred, int accountJournalId, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, int stockDebitStatusId) { return bnhtradeDatabaseClient.Stock.StockCreate.WIP_StockInsertPurchase(sqlConnCred.ConnectionString, productId, conditionId, accountTaxCodeId, accountJournalId, quantity, stockDebitStatusId); } public void PurchaseLineTransactionStockDelete(ConnectionCredential sqlConnCred, int stockId) { bnhtradeDatabaseClient.Stock.StockCreate.WIP_StockDeletePurchase(sqlConnCred.ConnectionString, stockId); } } [ComVisible(true)] [Guid("debaee08-a3d5-4f9b-b8cf-ad146c3e0ee9")] [ClassInterface(ClassInterfaceType.None)] [ProgId("bnhtradeDb.AccountQuery")] public class AccountQuery : IAccountQuery { public int AccountJournalInsert(ConnectionCredential sqlConnCred, int journalTypeId, DateTime entryDate, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, int debitAccountId = 0, int creditAccountId = 0, bool lockEntry = false) { return bnhtradeDatabaseClient.Account.AccountQuery.AccountJournalInsert(sqlConnCred.ConnectionString, journalTypeId, entryDate, currencyCode, amount, debitAccountId, creditAccountId, lockEntry); } public bool AccountJournalDelete(ConnectionCredential sqlConnCred, int accountJournalId) { return bnhtradeDatabaseClient.Account.AccountQuery.AccountJournalDelete(sqlConnCred.ConnectionString, accountJournalId); } [return: MarshalAs(UnmanagedType.Currency)] public decimal CurrencyConvertToGbp(ConnectionCredential sqlConnCred, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, DateTime conversionDate) { return bnhtradeDatabaseClient.Account.AccountQuery.CurrencyConvertToGbp(sqlConnCred.ConnectionString, currencyCode, amount, conversionDate); } public int CurrencyExchangeRateInsert(ConnectionCredential sqlConnCred, int exchangeRateSource, string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false) { return bnhtradeDatabaseClient.Account.AccountQuery.CurrencyExchangeRateInsert(sqlConnCred.ConnectionString, exchangeRateSource, currencyCode, currencyUnitsPerGbp, periodStart, periodEnd, checkOverride); } } [ComVisible(true)] [Guid("237ac4be-87f0-4500-bd74-0423d1f72c75")] [ClassInterface(ClassInterfaceType.None)] [ProgId("bnhtradeDb.ProductQuery")] public class ProductQuery : IProductQuery { [ComVisible(false)] [return: MarshalAs(UnmanagedType.BStr)] public string ReturnStringValue(string stringValue) { return "kj;lk1"; } [ComVisible(false)] public double ReturnDateValueAsDouble(string stringValue) { DateTime theTimeNow = DateTime.UtcNow; return theTimeNow.ToOADate(); // back in vba use the CDate(return) function to convert the double // vba Date --> c# DateTime works without marshalling } public int ProductGetProductIdByCatId(int catId, ConnectionCredential sqlConnCred) { var request = new bnhtradeDatabaseClient.Product.ProductQuery(); int? result = request.ProductGetProductIdByCatId(sqlConnCred.ConnectionString, catId); if (result == null) { return 0; } else { return result.Value; } } public string ProductCompetitivePriceGet(int productId, int conditionId, ConnectionCredential sqlConnCred) { var request = new bnhtradeDatabaseClient.Product.ProductQuery(); (decimal? price, DateTime? priceDate) result = request.ProductCompetitivePriceGet(sqlConnCred.ConnectionString, productId, conditionId); if (result.price == null || result.priceDate == null) { return ""; } else { DateTime priceDate2 = result.priceDate.Value; return result.price.ToString() + ";" + priceDate2.ToOADate(); } } public int ProductCompetitivePriceSet(int productId, int conditionId, [MarshalAs(UnmanagedType.Currency)] decimal price, bool isBuyBoxPrice, DateTime priceDate, ConnectionCredential sqlConnCred) { var request = new bnhtradeDatabaseClient.Product.ProductQuery(); return request.ProductCompetitivePriceSet(sqlConnCred.ConnectionString, productId, conditionId, price, isBuyBoxPrice, priceDate); } public void ProductUpdateAmazonEstimateFee(ConnectionCredential sqlConnCred, object inputList) { // get com object in string array var inputTuple = new List<(string asin, decimal priceToEstimate)>(); string[] stringArray = Vba6.Functions.LoadComObjectIntoStringArray(inputList); foreach (var item in stringArray) { string[] split = item.Split(';'); if (split.Length != 2) { throw new Exception("Split function failed on line: " + item); } var tempTuple = (split[0], decimal.Parse(split[1])); inputTuple.Add(tempTuple); } bnhtradeDatabaseClient.Product.ProductQuery.ProductUpdateAmazonEstimateFee(sqlConnCred.ConnectionString, inputTuple); } } [ComVisible(true)] [Guid("10ff112d-a94f-4818-add4-8dddabf1fa9e")] [ClassInterface(ClassInterfaceType.None)] [ProgId("bnhtradeDb.StockQuery")] // [ClassInterface(ClassInterfaceType.AutoDual)] public class StockQuery : IStockQuery { public int StockInsertPurchase(ConnectionCredential sqlConnCred, int productId, int conditionId, int accountTaxCodeId, int accountJournalId, int quantity, int statusDebitId) { return bnhtradeDatabaseClient.Stock.StockCreate.WIP_StockInsertPurchase(sqlConnCred.ConnectionString, productId, conditionId, accountTaxCodeId, accountJournalId, quantity, statusDebitId); } public int StockInsertOwnerIntroduced(ConnectionCredential sqlConnCred, [MarshalAs(UnmanagedType.Currency)] decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId) { return bnhtradeDatabaseClient.Stock.StockCreate.WIP_StockInsertOwnerIntroduced(sqlConnCred.ConnectionString, amount, quantity, productId, conditionId, accountTaxCodeId, entryDate, debitStatusId); } public void StockDeletePurchase(ConnectionCredential sqlConnCred, int stockId) { bnhtradeDatabaseClient.Stock.StockCreate.WIP_StockDeletePurchase(sqlConnCred.ConnectionString, stockId); } public void StockDeleteOwnerIntroduced(ConnectionCredential sqlConnCred, int stockId) { bnhtradeDatabaseClient.Stock.StockCreate.WIP_StockDeleteOwnerIntroduced(sqlConnCred.ConnectionString, stockId); } public int StockReallocate(ConnectionCredential sqlConnCred, int stockId, int quantity, int debitStatusId, int creditStatusId, DateTime entryDate) { entryDate = DateTime.SpecifyKind(entryDate, DateTimeKind.Utc); return bnhtradeDatabaseClient.Stock.StockJournal.StockReallocateByStockId(sqlConnCred.ConnectionString, 4, stockId, quantity, debitStatusId, creditStatusId, entryDate); } public void StockJournalDelete(ConnectionCredential sqlConnCred, int stockJournalId) { bnhtradeDatabaseClient.Stock.StockJournal.StockJournalDelete(sqlConnCred.ConnectionString, stockJournalId); } public object ReconcileStockTransactions(ConnectionCredential sqlConnCred) { var request = new bnhtradeDatabaseClient.Stock.StockReconciliation(); var result = new bnhtradeDatabaseClient.Stock.StockReconciliation.ReconcileStockTransactionsResult(); result = request.ReconcileStockTransactions(sqlConnCred.ConnectionString, false); //ReconcileStockTransactionsResult returnObject = new ReconcileStockTransactionsResult(); // copy values between classes //PropertyInfo[] infos = typeof(ReconcileStockTransactionsResult).GetProperties(); //foreach (PropertyInfo info in infos) //{ // info.SetValue(returnObject, info.GetValue(result, null), null); //} //foreach (PropertyInfo property in typeof(ReconcileStockTransactionsResult).GetProperties()) //{ // if (property.CanWrite) // { // property.SetValue(returnObject, property.GetValue(result, null), null); // } //} //returnObject.ItemsCompleted = result.ItemsCompleted; //returnObject.ItemsRemaining = result.ItemsRemaining; //returnObject.LastItemDateTime = result.LastItemDateTime; //returnObject.ProgressMessage = result.ProgressMessage; //returnObject.ReconciliationComplete = returnObject.ReconciliationComplete; //returnObject.StockTransactionId = result.StockTransactionId; //returnObject.StockTransactionTypeId = result.StockTransactionTypeId; //create the return array object[] returnArray = new object[7]; returnArray[0] = result.ReconciliationComplete; returnArray[1] = result.ProgressMessage; returnArray[2] = result.StockTransactionId; returnArray[3] = result.StockTransactionTypeId; returnArray[4] = result.LastItemDateTime; returnArray[5] = result.ItemsCompleted; returnArray[6] = result.ItemsRemaining; return returnArray; //return returnObject; } public bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId) { return bnhtradeDatabaseClient.Stock.StockJournal.WIP_StockJournalConsistencyCheck(sqlConnCred.ConnectionString, stockId, null); } } //[ComVisible(true)] //[Guid("75a40c36-0b36-4954-8f60-3093f040e54f")] //[ClassInterface(ClassInterfaceType.None)] //[ProgId("bnhtradeDb.StockReconciliationResult")] //// [ClassInterface(ClassInterfaceType.AutoDual)] //public class ReconcileStockTransactionsResult : IReconcileStockTransactionsResult //{ // public bool ReconciliationComplete { get; set; } = false; // public int StockTransactionId { get; set; } // public int StockTransactionTypeId { get; set; } // public string ProgressMessage { get; set; } // public int ItemsCompleted { get; set; } // public int ItemsRemaining { get; set; } // public DateTime LastItemDateTime { get; set; } //} public class Functions { public static string[] LoadComObjectIntoStringArray(object comObject) { Type thisType = comObject.GetType(); Type strType = Type.GetType("System.Object[]"); //Type strType = Type.GetType("System.String[*]"); string[] stringArray = new string[1]; // temporary allocation to keep compiler happy. if (thisType == strType) { object[] args = new object[1]; int numEntries = (int)thisType.InvokeMember("Length", BindingFlags.GetProperty, null, comObject, null); stringArray = new string[numEntries]; for (int i = 0; i < numEntries; i++) { args[0] = i; // since VB arrays index from 1, mine doesn't stringArray[i] = (string)thisType.InvokeMember("GetValue", BindingFlags.InvokeMethod, null, comObject, args); } } // End if(thisType == dblType) else { throw new Exception("something went wrong loading object into c# array. Type is '" + thisType.ToString() + "'"); } return stringArray; } // End LoadComObjectIntoDoubleArray() } }