From d6b198777f60ebc1d775d75491e821ae986a8dac Mon Sep 17 00:00:00 2001 From: Bobbie Hodgetts Date: Fri, 29 May 2020 16:28:16 +0100 Subject: [PATCH 1/4] wip --- .../Logic/Sku/Price/FbaPricing.cs | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs b/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs index 3dc41ce..f3de5e1 100644 --- a/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs +++ b/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs @@ -21,7 +21,7 @@ namespace bnhtrade.Core.Logic.Sku.Price private int newConditionId = Data.Database.Constants.GetProductConditionIdNew(); private List skuInfo; private Dictionary competitivePrices; - DateTime crTimeStamp = DateTime.UtcNow; + DateTime newTimeStamp = DateTime.UtcNow; private int repriceIncrementDivisor = 60; private Dictionary saleCountInPeriod = new Dictionary(); private Logic.Account.TaxCalculation taxCalc; @@ -31,28 +31,25 @@ namespace bnhtrade.Core.Logic.Sku.Price { this.sqlConnectionString = sqlConnectionString; taxCalc = new Account.TaxCalculation(); - crTimeStamp = DateTime.UtcNow; - marginSchemeMargin = taxCalc.GetMarginMultiplier(crTimeStamp); + newTimeStamp = DateTime.UtcNow; + marginSchemeMargin = taxCalc.GetMarginMultiplier(newTimeStamp); } public void Update(bool overrideDayCheck = false) { + UpdatePrecheck(); + using (var scope = new TransactionScope()) { string orderChannel = "Amazon.co.uk"; // may in future enable other order channels - // need to add some cheks up here for last stock reconcilliation - - - - - - // get current sku base pricing details (stock quantity, competative price, VAT info, etc.) skuInfo = new Data.Database.Sku.Price.ReadParameter(sqlConnectionString).Execute(); if (skuInfo == null || !skuInfo.Any()) { - throw new Exception("Querying the database returned no records."); + err += "Querying the database returned no records."; + log.LogError(err); + throw new Exception(err); } // create lists that we'll add to during lopp @@ -85,7 +82,7 @@ namespace bnhtrade.Core.Logic.Sku.Price cr.ReviewRequired = false; cr.OrderChannel = orderChannel; cr.OrderChannelQuantity = skuInfo[i].TotalQuantity; - cr.PriceInfoTimeStamp = crTimeStamp; + cr.PriceInfoTimeStamp = newTimeStamp; cr.SkuNumber = skuInfo[i].SkuNumber; // get inventory age range @@ -258,7 +255,7 @@ namespace bnhtrade.Core.Logic.Sku.Price bool update = false; lastPriceUpdate = new DateTime(lastPriceUpdate.Year, lastPriceUpdate.Month, lastPriceUpdate.Day); - DateTime today = new DateTime(crTimeStamp.Year, crTimeStamp.Month, crTimeStamp.Day); + DateTime today = new DateTime(newTimeStamp.Year, newTimeStamp.Month, newTimeStamp.Day); // will only update once on tue, wed or thurs each week. if (today.DayOfWeek == DayOfWeek.Tuesday || today.DayOfWeek == DayOfWeek.Wednesday || today.DayOfWeek == DayOfWeek.Thursday) @@ -382,5 +379,20 @@ namespace bnhtrade.Core.Logic.Sku.Price return 0; } } + + /// + /// Before running reprice update, this method ensures that the relevant data needed is up to date. + /// + private void UpdatePrecheck() + { + throw new NotImplementedException(); + + // check last FBA sale import + err += "Querying the database returned no records."; + log.LogError(err); + throw new Exception(err); + + // check last amazon sku fees updates + } } } From 738f87f988e24c59cb46f142273d894361398335 Mon Sep 17 00:00:00 2001 From: Bobbie Hodgetts Date: Fri, 5 Jun 2020 12:19:46 +0100 Subject: [PATCH 2/4] wip --- src/bnhtrade.Core/Data/Database/Constants.cs | 10 ++++++++++ src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bnhtrade.Core/Data/Database/Constants.cs b/src/bnhtrade.Core/Data/Database/Constants.cs index 4b989b5..637a0bc 100644 --- a/src/bnhtrade.Core/Data/Database/Constants.cs +++ b/src/bnhtrade.Core/Data/Database/Constants.cs @@ -8,6 +8,16 @@ namespace bnhtrade.Core.Data.Database { public static class Constants { + public static string GetMarginSchemeTaxCode() + { + return "T190"; + } + + public static string GetOrderChannelAmazonUk() + { + return "Amazon.co.uk"; + } + public static int GetProductConditionIdNew() { return 10; diff --git a/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs b/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs index f3de5e1..c8e8ede 100644 --- a/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs +++ b/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs @@ -16,7 +16,7 @@ namespace bnhtrade.Core.Logic.Sku.Price private string sqlConnectionString; private bnhtrade.Core.Logic.Log.LogEvent log = new Log.LogEvent(); string err = "FbaPricing Error: "; - private string marginSchemeTaxCode = "T190"; + private string marginSchemeTaxCode = Data.Database.Constants.GetMarginSchemeTaxCode(); int repriceHoldOnSalePeriod = 14; // days private int newConditionId = Data.Database.Constants.GetProductConditionIdNew(); private List skuInfo; @@ -41,7 +41,7 @@ namespace bnhtrade.Core.Logic.Sku.Price using (var scope = new TransactionScope()) { - string orderChannel = "Amazon.co.uk"; // may in future enable other order channels + string orderChannel = Data.Database.Constants.GetOrderChannelAmazonUk(); ; // may in future enable other order channels // get current sku base pricing details (stock quantity, competative price, VAT info, etc.) skuInfo = new Data.Database.Sku.Price.ReadParameter(sqlConnectionString).Execute(); @@ -70,6 +70,8 @@ namespace bnhtrade.Core.Logic.Sku.Price // loop through skus returnd from stock query for (int i = 0; i < skuInfo.Count(); i++) { + var existing = skuInfo[i]; + string skuNumber = skuInfo[i].SkuNumber; var cr = new Model.Sku.Price.PriceInfo(); From aeef35b57c1ecfb224e9f0e7a7c3cb2b56e6829f Mon Sep 17 00:00:00 2001 From: Bobbie Hodgetts Date: Mon, 8 Jun 2020 15:13:38 +0100 Subject: [PATCH 3/4] wip --- .../Logic/Sku/Price/FbaPricing.cs | 160 ++++++++++-------- 1 file changed, 86 insertions(+), 74 deletions(-) diff --git a/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs b/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs index c8e8ede..3081a92 100644 --- a/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs +++ b/src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs @@ -190,87 +190,18 @@ namespace bnhtrade.Core.Logic.Sku.Price } // finish loop - // validate and save values to database - var validate = new Core.Logic.Validate.SkuPriceInfo(); - if (!validate.IsValidDatabaseCreate(crDictionary.Values.ToList())) - { - err += "Database object create validation failed"; - log.LogError(err, validate.ValidationResultListToString()); - throw new Exception(err); - } + // save values to database + SaveToDatabase(crDictionary); - new Data.Database.Sku.Price.CreatePricingDetail(sqlConnectionString).Executue(crDictionary.Values.ToList()); + // upload to amazon + UploadToAmazon(crDictionary); - // create and upload inventory loader file to amazon - var exportList = new List(); - foreach (var item in crDictionary.Values) - { - var listItem = new Model.Export.AmazonIventoryLoaderFile(); - listItem.Sku = item.SkuNumber; - listItem.MinimumAllowedPrice = item.MinPrice; - listItem.MaximumAllowedPrice = item.MaxPrice; - listItem.Price = item.MaxPrice; - listItem.SetFulfillmentCenterId(true); - exportList.Add(listItem); - } - - // validate - var vaildateInvLoader = new Validate.AmazonIventoryLoaderFile(); - if (!vaildateInvLoader.IsValidFbaPricing(exportList)) - { - err += "Inventory loader object validation failed"; - log.LogError(err, vaildateInvLoader.ValidationResultListToString()); - throw new Exception(err); - } - - // create file stream - var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.CurrentCulture); - config.Delimiter = "\t"; - config.Encoding = Encoding.UTF8; - - var stream = new MemoryStream(); - using (var writer = new StreamWriter(stream, Encoding.UTF8)) - using (var csv = new CsvWriter(writer, config)) - { - csv.WriteRecords(exportList); - } - - // submit file to database and amazon mws - var submit = new Logic.Export.AmazonSubmitFile(sqlConnectionString); - - return; - - submit.SubmitInventoryLoader(stream); + return; // remove after testing scope.Complete(); } } - private bool OkayToReprice(DateTime lastPriceUpdate) - { - if (lastPriceUpdate == default(DateTime)) - { - err += "Invalid, datetime is default."; - log.LogError(err); - throw new Exception(err); - } - - bool update = false; - lastPriceUpdate = new DateTime(lastPriceUpdate.Year, lastPriceUpdate.Month, lastPriceUpdate.Day); - DateTime today = new DateTime(newTimeStamp.Year, newTimeStamp.Month, newTimeStamp.Day); - - // will only update once on tue, wed or thurs each week. - if (today.DayOfWeek == DayOfWeek.Tuesday || today.DayOfWeek == DayOfWeek.Wednesday || today.DayOfWeek == DayOfWeek.Thursday) - { - if (today > lastPriceUpdate.AddDays(3)) - { - update = true; - } - } - - return update; - } - /// /// Get the minimum sale price to break even. /// @@ -382,6 +313,44 @@ namespace bnhtrade.Core.Logic.Sku.Price } } + private bool OkayToReprice(DateTime lastPriceUpdate) + { + if (lastPriceUpdate == default(DateTime)) + { + err += "Invalid, datetime is default."; + log.LogError(err); + throw new Exception(err); + } + + bool update = false; + lastPriceUpdate = new DateTime(lastPriceUpdate.Year, lastPriceUpdate.Month, lastPriceUpdate.Day); + DateTime today = new DateTime(newTimeStamp.Year, newTimeStamp.Month, newTimeStamp.Day); + + // will only update once on tue, wed or thurs each week. + if (today.DayOfWeek == DayOfWeek.Tuesday || today.DayOfWeek == DayOfWeek.Wednesday || today.DayOfWeek == DayOfWeek.Thursday) + { + if (today > lastPriceUpdate.AddDays(3)) + { + update = true; + } + } + + return update; + } + + private void SaveToDatabase(Dictionary crDictionary) + { + var validate = new Core.Logic.Validate.SkuPriceInfo(); + if (!validate.IsValidDatabaseCreate(crDictionary.Values.ToList())) + { + err += "Database object create validation failed"; + log.LogError(err, validate.ValidationResultListToString()); + throw new Exception(err); + } + + new Data.Database.Sku.Price.CreatePricingDetail(sqlConnectionString).Executue(crDictionary.Values.ToList()); + } + /// /// Before running reprice update, this method ensures that the relevant data needed is up to date. /// @@ -396,5 +365,48 @@ namespace bnhtrade.Core.Logic.Sku.Price // check last amazon sku fees updates } + + private void UploadToAmazon(Dictionary crDictionary) + { + var exportList = new List(); + foreach (var item in crDictionary.Values) + { + var listItem = new Model.Export.AmazonIventoryLoaderFile(); + listItem.Sku = item.SkuNumber; + listItem.MinimumAllowedPrice = item.MinPrice; + listItem.MaximumAllowedPrice = item.MaxPrice; + listItem.Price = item.MaxPrice; + listItem.SetFulfillmentCenterId(true); + exportList.Add(listItem); + } + + // validate + var vaildateInvLoader = new Validate.AmazonIventoryLoaderFile(); + if (!vaildateInvLoader.IsValidFbaPricing(exportList)) + { + err += "Inventory loader object validation failed"; + log.LogError(err, vaildateInvLoader.ValidationResultListToString()); + throw new Exception(err); + } + + // create file stream + var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.CurrentCulture); + config.Delimiter = "\t"; + config.Encoding = Encoding.UTF8; + + var stream = new MemoryStream(); + using (var writer = new StreamWriter(stream, Encoding.UTF8)) + using (var csv = new CsvWriter(writer, config)) + { + csv.WriteRecords(exportList); + } + + // submit file to database and amazon mws + var submit = new Logic.Export.AmazonSubmitFile(sqlConnectionString); + + return; // remove after testing + + submit.SubmitInventoryLoader(stream); + } } } From 8cd27646cd0b2d2b9ef1291eed366cf8bfcf6c30 Mon Sep 17 00:00:00 2001 From: Bobbie Hodgetts Date: Wed, 23 Sep 2020 13:15:30 +0100 Subject: [PATCH 4/4] Updating branch with changes from master (#12) * Copy release version to Dropbox on build * Bug fix: Error thrown on list containing null item --- .../Data/Database/Stock/ReadSkuTransactionType.cs | 4 ++++ .../Logic/Stock/SkuTransactionTypePersistance.cs | 2 ++ src/bnhtrade.ScheduledTasks/bnhtrade.ScheduledTasks.csproj | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransactionType.cs b/src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransactionType.cs index c4602f9..40f3de8 100644 --- a/src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransactionType.cs +++ b/src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransactionType.cs @@ -125,6 +125,8 @@ namespace bnhtrade.Core.Data.Database.Stock public List ByTypeCode(List typeCode) { + typeCode.RemoveAll(string.IsNullOrWhiteSpace); + string sqlWhere = @" WHERE TypeCode IN @typeCode "; @@ -136,6 +138,8 @@ namespace bnhtrade.Core.Data.Database.Stock public List ByTypeName(List typeName) { + typeName.RemoveAll(string.IsNullOrWhiteSpace); + string sqlWhere = @" WHERE TypeName IN @typeName "; diff --git a/src/bnhtrade.Core/Logic/Stock/SkuTransactionTypePersistance.cs b/src/bnhtrade.Core/Logic/Stock/SkuTransactionTypePersistance.cs index 5fe313c..02d8abe 100644 --- a/src/bnhtrade.Core/Logic/Stock/SkuTransactionTypePersistance.cs +++ b/src/bnhtrade.Core/Logic/Stock/SkuTransactionTypePersistance.cs @@ -41,6 +41,8 @@ namespace bnhtrade.Core.Logic.Stock { CacheInnit(); + typeCodeList.RemoveAll(string.IsNullOrWhiteSpace); + if (typeCodeList == null || !typeCodeList.Any()) { return; diff --git a/src/bnhtrade.ScheduledTasks/bnhtrade.ScheduledTasks.csproj b/src/bnhtrade.ScheduledTasks/bnhtrade.ScheduledTasks.csproj index 065c7b5..a8e0b7d 100644 --- a/src/bnhtrade.ScheduledTasks/bnhtrade.ScheduledTasks.csproj +++ b/src/bnhtrade.ScheduledTasks/bnhtrade.ScheduledTasks.csproj @@ -106,4 +106,7 @@ + + xcopy /E /Y "$(SolutionDir)artifiacts\Release" "C:\Users\Bobbie\Dropbox\Apps\bnhtrade" + \ No newline at end of file