From b259b779677efa71589b6708cdc4d11912b76b7e Mon Sep 17 00:00:00 2001 From: Tom Raterman Date: Sun, 30 Oct 2022 22:12:25 -0400 Subject: [PATCH] Automation and Shopify library updates --- PartSource.Api/PartSource.Api.csproj | 2 +- .../Jobs/ExecuteSsisPackages.cs | 13 +- .../Jobs/GetNexpartMenuItems.cs | 3 +- .../Jobs/POC/FixMultipleSeoTables.cs | 3 +- .../Jobs/POC/UpdateBulbFitment.cs | 5 +- .../Jobs/POC/UpdateFitmentHtml.cs | 3 +- .../Jobs/POC/UpdateFitmentScratchpad.cs | 3 +- .../Jobs/POC/UpdateWiperFitment.cs | 8 +- .../Jobs/ProcessWhiFitment.cs | 11 +- .../Jobs/ProcessWhiVehicles.cs | 3 +- PartSource.Automation/Jobs/StatusCheck.cs | 3 +- PartSource.Automation/Jobs/TestJob.cs | 3 +- PartSource.Automation/Jobs/UpdateFitment.cs | 13 +- .../Jobs/UpdatePositioning.cs | 7 +- PartSource.Automation/Jobs/UpdatePricing.cs | 225 +++++++----------- .../PartSource.Automation.csproj | 7 +- PartSource.Automation/Program.cs | 38 ++- PartSource.Automation/appsettings.json | 11 +- .../PartSource.Services.csproj | 2 +- PartSource.sln | 4 +- nuget.config | 5 +- 21 files changed, 172 insertions(+), 200 deletions(-) diff --git a/PartSource.Api/PartSource.Api.csproj b/PartSource.Api/PartSource.Api.csproj index 48caee0..280d4b0 100644 --- a/PartSource.Api/PartSource.Api.csproj +++ b/PartSource.Api/PartSource.Api.csproj @@ -35,7 +35,7 @@ - + diff --git a/PartSource.Automation/Jobs/ExecuteSsisPackages.cs b/PartSource.Automation/Jobs/ExecuteSsisPackages.cs index a821245..53d94e5 100644 --- a/PartSource.Automation/Jobs/ExecuteSsisPackages.cs +++ b/PartSource.Automation/Jobs/ExecuteSsisPackages.cs @@ -4,6 +4,7 @@ using PartSource.Automation.Models.Configuration; using PartSource.Automation.Services; using Ratermania.Automation.Interfaces; using System; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -18,15 +19,17 @@ namespace PartSource.Automation.Jobs // TODO: set from config private readonly string[] _ssisPackages = { "Parts Price", "Parts Availability" }; - public ExecuteSsisPackages(EmailService emailService, FtpService ftpService, SsisService ssisService, ILogger logger) + public ExecuteSsisPackages(EmailService emailService, IConfiguration configuration, SsisService ssisService, ILogger logger) { - _ftpService = ftpService; + FtpConfiguration ftpConfiguration = configuration.GetSection("FtpServers:AzureConfiguration").Get(); + _emailService = emailService; + _ftpService = new FtpService(ftpConfiguration); _ssisService = ssisService; _logger = logger; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { await Task.Run(() => { @@ -37,12 +40,12 @@ namespace PartSource.Automation.Jobs _ftpService.Download($"{package}.txt"); _ssisService.Execute($"{package}.dtsx"); - _logger.LogInformation("Execution of SSIS package {package} completed successfully.", package); + _logger.LogInformation($"Execution of SSIS package {package} completed successfully."); } catch (Exception ex) { - _logger.LogError(ex, "Execution of SSIS package {package} failed", package); + _logger.LogError($"Execution of SSIS package {package} failed.", ex); throw; } diff --git a/PartSource.Automation/Jobs/GetNexpartMenuItems.cs b/PartSource.Automation/Jobs/GetNexpartMenuItems.cs index 41b2397..d337a99 100644 --- a/PartSource.Automation/Jobs/GetNexpartMenuItems.cs +++ b/PartSource.Automation/Jobs/GetNexpartMenuItems.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -18,7 +19,7 @@ namespace PartSource.Automation.Jobs _nexpartService = nexpartService; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { IList rows = new List { diff --git a/PartSource.Automation/Jobs/POC/FixMultipleSeoTables.cs b/PartSource.Automation/Jobs/POC/FixMultipleSeoTables.cs index 7771d10..49078d4 100644 --- a/PartSource.Automation/Jobs/POC/FixMultipleSeoTables.cs +++ b/PartSource.Automation/Jobs/POC/FixMultipleSeoTables.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs.POC @@ -19,7 +20,7 @@ namespace PartSource.Automation.Jobs.POC _shopifyClient = shopifyClient; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { IEnumerable products = await _shopifyClient.Products.Get(new Dictionary { { "limit", 250 }, { "product_type", "CA112-SC137-FL13750_Intake Manifolds" } }); diff --git a/PartSource.Automation/Jobs/POC/UpdateBulbFitment.cs b/PartSource.Automation/Jobs/POC/UpdateBulbFitment.cs index eacd838..6c0fddf 100644 --- a/PartSource.Automation/Jobs/POC/UpdateBulbFitment.cs +++ b/PartSource.Automation/Jobs/POC/UpdateBulbFitment.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -29,7 +30,7 @@ namespace PartSource.Automation.Jobs.POC _shopifyClient = shopifyClient; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { await BuildDatabase(); await UpdateShopify(); @@ -177,7 +178,7 @@ namespace PartSource.Automation.Jobs.POC Namespace = "position", Key = key, Value = json, - ValueType = "json_string", + Type = "json", OwnerResource = "product", OwnerId = product.Id }; diff --git a/PartSource.Automation/Jobs/POC/UpdateFitmentHtml.cs b/PartSource.Automation/Jobs/POC/UpdateFitmentHtml.cs index 67ff0a5..36019af 100644 --- a/PartSource.Automation/Jobs/POC/UpdateFitmentHtml.cs +++ b/PartSource.Automation/Jobs/POC/UpdateFitmentHtml.cs @@ -16,6 +16,7 @@ using System.Data; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -37,7 +38,7 @@ namespace PartSource.Automation.Jobs _vehicleService = vehicleService; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { IEnumerable products = null; diff --git a/PartSource.Automation/Jobs/POC/UpdateFitmentScratchpad.cs b/PartSource.Automation/Jobs/POC/UpdateFitmentScratchpad.cs index a1ea5e4..2190ff5 100644 --- a/PartSource.Automation/Jobs/POC/UpdateFitmentScratchpad.cs +++ b/PartSource.Automation/Jobs/POC/UpdateFitmentScratchpad.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs.POC @@ -39,7 +40,7 @@ namespace PartSource.Automation.Jobs.POC _vehicleService = vehicleService; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { IList productTypes = new List { diff --git a/PartSource.Automation/Jobs/POC/UpdateWiperFitment.cs b/PartSource.Automation/Jobs/POC/UpdateWiperFitment.cs index a6f36fc..ff38bc4 100644 --- a/PartSource.Automation/Jobs/POC/UpdateWiperFitment.cs +++ b/PartSource.Automation/Jobs/POC/UpdateWiperFitment.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; @@ -29,9 +30,9 @@ namespace PartSource.Automation.Jobs.POC _shopifyClient = shopifyClient; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { - // await BuildDatabase(); + await BuildDatabase(); await UpdateShopify(); } @@ -143,7 +144,6 @@ namespace PartSource.Automation.Jobs.POC } } - //[SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "It's a Shopify metafield key")] private async Task SavePositionMetafield(Product product, IList vehicleIds, string position) { if (vehicleIds.Count == 0) @@ -169,7 +169,7 @@ namespace PartSource.Automation.Jobs.POC Namespace = "position", Key = key, Value = json, - ValueType = "json_string", + Type = "json", OwnerResource = "product", OwnerId = product.Id }; diff --git a/PartSource.Automation/Jobs/ProcessWhiFitment.cs b/PartSource.Automation/Jobs/ProcessWhiFitment.cs index 1203c35..78a2122 100644 --- a/PartSource.Automation/Jobs/ProcessWhiFitment.cs +++ b/PartSource.Automation/Jobs/ProcessWhiFitment.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -39,11 +40,11 @@ namespace PartSource.Automation.Jobs _noteDictionary = new ConcurrentDictionary(); } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2008:Do not create tasks without passing a TaskScheduler", Justification = "")] - public async Task Run() + [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2008:Do not create tasks without passing a TaskScheduler", Justification = "Not library code")] + public async Task Run(CancellationToken token, params string[] arguments) { _whiSeoService.TruncateFitmentTables(); - // _whiSeoService.GetFiles(_seoDataType); + _whiSeoService.GetFiles(_seoDataType); string directory = Path.Combine(_ftpConfiguration.Destination, _seoDataType.ToString().ToLowerInvariant()); DirectoryInfo directoryInfo = new DirectoryInfo(directory); @@ -55,7 +56,7 @@ namespace PartSource.Automation.Jobs fileGroups.Enqueue(fileGroup); } - Task[] taskArray = new Task[8]; + Task[] taskArray = new Task[Environment.ProcessorCount / 2]; for (int i = 0; i < taskArray.Length; i++) { @@ -90,7 +91,7 @@ namespace PartSource.Automation.Jobs _logger.LogInformation($"Created fitment table for part group {fitmentTable}."); } - }); + }, token); } Task.WaitAll(taskArray); diff --git a/PartSource.Automation/Jobs/ProcessWhiVehicles.cs b/PartSource.Automation/Jobs/ProcessWhiVehicles.cs index dc64557..0db132f 100644 --- a/PartSource.Automation/Jobs/ProcessWhiVehicles.cs +++ b/PartSource.Automation/Jobs/ProcessWhiVehicles.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -36,7 +37,7 @@ namespace PartSource.Automation.Jobs } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { _whiSeoService.TruncateVehicleTables(); _whiSeoService.GetFiles(_seoDataType); diff --git a/PartSource.Automation/Jobs/StatusCheck.cs b/PartSource.Automation/Jobs/StatusCheck.cs index 00a257d..b02e123 100644 --- a/PartSource.Automation/Jobs/StatusCheck.cs +++ b/PartSource.Automation/Jobs/StatusCheck.cs @@ -1,6 +1,7 @@ using PartSource.Automation.Models; using PartSource.Automation.Services; using Ratermania.Automation.Interfaces; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -15,7 +16,7 @@ namespace PartSource.Automation.Jobs _emailService = emailService; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { foreach (string phoneNumber in phoneNumbers) { diff --git a/PartSource.Automation/Jobs/TestJob.cs b/PartSource.Automation/Jobs/TestJob.cs index 3c25313..891f20e 100644 --- a/PartSource.Automation/Jobs/TestJob.cs +++ b/PartSource.Automation/Jobs/TestJob.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using PartSource.Automation.Services; +using System.Threading; namespace PartSource.Automation.Jobs { @@ -21,7 +22,7 @@ namespace PartSource.Automation.Jobs } #pragma warning disable CS1998, CA1303 - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { // _emailService.Send("Automation Test Message", "This is a test email from the automation server. If this message was in your spam folder, whitelist the address that sent this email."); diff --git a/PartSource.Automation/Jobs/UpdateFitment.cs b/PartSource.Automation/Jobs/UpdateFitment.cs index 11ba060..adb8972 100644 --- a/PartSource.Automation/Jobs/UpdateFitment.cs +++ b/PartSource.Automation/Jobs/UpdateFitment.cs @@ -16,6 +16,7 @@ using System.Data; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -37,7 +38,7 @@ namespace PartSource.Automation.Jobs _vehicleService = vehicleService; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { IEnumerable products = null; @@ -104,7 +105,7 @@ namespace PartSource.Automation.Jobs Namespace = "fitment", Key = "ids", Value = json, - ValueType = "json_string", + Type = "json", OwnerResource = "product", OwnerId = product.Id }; @@ -145,7 +146,7 @@ namespace PartSource.Automation.Jobs Namespace = "fitment", Key = "seo", Value = json, - ValueType = "json_string", + Type = "single_line_text_field", OwnerResource = "product", OwnerId = product.Id }; @@ -158,7 +159,7 @@ namespace PartSource.Automation.Jobs Namespace = "Flags", Key = "IsFitment", Value = isFitment.ToString(), - ValueType = "string", + Type = "single_line_text_field", OwnerResource = "product", OwnerId = product.Id }; @@ -170,7 +171,7 @@ namespace PartSource.Automation.Jobs Namespace = "google", Key = "custom_label_0", Value = importData.LineCode, - ValueType = "string", + Type = "single_line_text_field", OwnerResource = "product", OwnerId = product.Id }; @@ -182,7 +183,7 @@ namespace PartSource.Automation.Jobs Namespace = "google", Key = "custom_label_1", Value = importData.PartNumber, - ValueType = "string", + Type = "single_line_text_field", OwnerResource = "product", OwnerId = product.Id }; diff --git a/PartSource.Automation/Jobs/UpdatePositioning.cs b/PartSource.Automation/Jobs/UpdatePositioning.cs index 59b271b..2099f99 100644 --- a/PartSource.Automation/Jobs/UpdatePositioning.cs +++ b/PartSource.Automation/Jobs/UpdatePositioning.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs @@ -32,7 +33,7 @@ namespace PartSource.Automation.Jobs _vehicleService = vehicleService; } - public async Task Run() + public async Task Run(CancellationToken token, params string[] arguments) { IDictionary parameters = new Dictionary { @@ -131,7 +132,7 @@ namespace PartSource.Automation.Jobs Namespace = "fitment", Key = "note_text", Value = json, - ValueType = "json_string", + Type = "json", OwnerResource = "product", OwnerId = product.Id }; @@ -204,7 +205,7 @@ namespace PartSource.Automation.Jobs Namespace = "position", Key = key, Value = json, - ValueType = "json_string", + Type = "json", OwnerResource = "product", OwnerId = product.Id }; diff --git a/PartSource.Automation/Jobs/UpdatePricing.cs b/PartSource.Automation/Jobs/UpdatePricing.cs index adbd547..38a1db9 100644 --- a/PartSource.Automation/Jobs/UpdatePricing.cs +++ b/PartSource.Automation/Jobs/UpdatePricing.cs @@ -13,161 +13,114 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Mail; +using System.Threading; using System.Threading.Tasks; namespace PartSource.Automation.Jobs { - public class UpdatePricing : IAutomationJob - { - private readonly ILogger _logger; - private readonly PartSourceContext _partSourceContext; - private readonly ShopifyClient _shopifyClient; - private readonly EmailService _emailService; + public class UpdatePricing : IAutomationJob + { + private readonly ILogger _logger; + private readonly PartSourceContext _partSourceContext; + private readonly ShopifyClient _shopifyClient; + private readonly EmailService _emailService; - public UpdatePricing(ILogger logger, PartSourceContext partSourceContext, ShopifyClient shopifyClient, EmailService emailService) - { - _logger = logger; - _partSourceContext = partSourceContext; - _shopifyClient = shopifyClient; - _emailService = emailService; - } + public UpdatePricing(ILogger logger, PartSourceContext partSourceContext, ShopifyClient shopifyClient, EmailService emailService) + { + _logger = logger; + _partSourceContext = partSourceContext; + _shopifyClient = shopifyClient; + _emailService = emailService; + } - public async Task Run() - { - List pricingReport = new List(); - IEnumerable products = null; - IEnumerable prices = null; + public async Task Run(CancellationToken token, params string[] arguments) + { + List pricingReport = new List(); + IEnumerable products = null; + IEnumerable prices = null; - try - { - products = await _shopifyClient.Products.Get(new Dictionary { { "limit", 250 } }); - prices = await _partSourceContext.PartPrices.AsNoTracking().ToListAsync(); - } + try + { + products = await _shopifyClient.Products.Get(new Dictionary { { "limit", 250 } }); + prices = await _partSourceContext.PartPrices.AsNoTracking().ToListAsync(token); + } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to get the initial set of products from Shopify."); + catch (Exception ex) + { + _logger.LogError(ex, "Failed to get the initial set of products from Shopify."); - throw; - } + throw; + } - while (products != null && products.Any()) - { - foreach (Product product in products) - { - List productPricingUpdate = new List(); + while (products != null && products.Any()) + { + foreach (Product product in products) + { + if (product.Variants.Length > 0) + { + for (int i = 0; i < product.Variants.Length; i++) + { + Variant variant = product.Variants[i]; + PartPrice partPrice = prices.Where(p => p.SKU == variant.Sku).FirstOrDefault(); - if (product.Variants.Length > 0) - { - bool hasUpdate = false; + if (partPrice == null || !partPrice.Your_Price.HasValue || !partPrice.Compare_Price.HasValue) + { + continue; + } - for (int i = 0; i < product.Variants.Length; i++) - { - Variant variant = product.Variants[i]; - PartPrice partPrice = prices.Where(p => p.SKU == variant.Sku).FirstOrDefault(); + product.Variants[i].Price = partPrice.Your_Price.Value; + product.Variants[i].CompareAtPrice = partPrice.Compare_Price.Value; - if (partPrice == null || !partPrice.Your_Price.HasValue || !partPrice.Compare_Price.HasValue) - { - continue; - } + product.PublishedAt = partPrice.Active.Trim().ToUpperInvariant() == "Y" ? (DateTime?)DateTime.Now : null; + product.PublishedScope = PublishedScope.Global; - if (product.Variants[i].Price.ToString("G29") != partPrice.Your_Price.Value.ToString("G29") || product.Variants[i].CompareAtPrice.ToString("G29") != partPrice.Compare_Price.Value.ToString("G29")) - { - productPricingUpdate.Add(new UpdatePricingResult - { - Sku = variant.Sku, - OldPrice = product.Variants[i].Price, - NewPrice = partPrice.Your_Price.Value, - OldCompareAt = product.Variants[i].CompareAtPrice, - NewCompareAt = partPrice.Compare_Price.Value - }); + try + { + await _shopifyClient.Metafields.Add(new Metafield + { + Namespace = "Pricing", + Key = "CorePrice", + Value = partPrice.Core_Price.HasValue ? partPrice.Core_Price.Value.ToString() : "0.00", + Type = "single_line_text_field", + OwnerResource = "product", + OwnerId = product.Id + }); + } - product.Variants[i].Price = partPrice.Your_Price.Value; - product.Variants[i].CompareAtPrice = partPrice.Compare_Price.Value; + catch (Exception ex) + { + _logger.LogWarning(ex, $"Failed to update core price metafield for product ID {product.Id}"); + } + } - product.PublishedAt = partPrice.Active.Trim().ToUpperInvariant() == "Y" ? DateTime.Now : null; - product.PublishedScope = PublishedScope.Global; + try + { + await _shopifyClient.Products.Update(product); + } - //Metafield metafield = new Metafield - //{ - // Namespace = "Pricing", - // Key = "CorePrice", - // Value = partPrice.Core_Price.HasValue ? partPrice.Core_Price.Value.ToString() : "0.00", - // ValueType = "string", - // OwnerResource = "product", - // OwnerId = product.Id - //}; + catch (Exception ex) + { + _logger.LogWarning(ex, $"Failed to update pricing for product ID {product.Id}"); + } + } + } - hasUpdate = true; - } - } - if (hasUpdate) - { - try - { - //await _shopifyClient.Metafields.Add(metafield); - await _shopifyClient.Products.Update(product); - - pricingReport.AddRange(productPricingUpdate); - } + try + { + products = await _shopifyClient.Products.GetNext(); - catch (Exception ex) - { - _logger.LogWarning(ex, $"Failed to update pricing for product ID {product.Id}"); - } - } - } - } + _logger.LogInformation($"Total updated: {pricingReport.Count}"); + } - try - { - products = await _shopifyClient.Products.GetNext(); - - _logger.LogInformation($"Total updated: {pricingReport.Count}"); - } - - catch (Exception ex) - { - _logger.LogWarning(ex, "Failed to get the next set of products. Retrying"); - products = await _shopifyClient.Products.GetPrevious(); - } - } - - Attachment attachment = GetPricingReportAttachment(pricingReport); - - _emailService.Send("Pricing Update Completed", $"The pricing update has completed. Total updated: {pricingReport.Count}", attachment); - } - - private Attachment GetPricingReportAttachment(IList pricingReport) - { - string directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Pricing Reports"); - string filename = Path.Combine(directory, $"Pricing Update {DateTime.Now.ToString("yyyy-MM-dd")}.csv"); - - if (!Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } - - if (File.Exists(filename)) - { - File.Delete(filename); - } - - using FileStream fileStream = File.OpenWrite(filename); - using StreamWriter streamWriter = new StreamWriter(fileStream, System.Text.Encoding.UTF8); - - streamWriter.WriteLine("SKU, Old Price, New Price, Old Compare At, New Compare At"); - - foreach (UpdatePricingResult pricingResult in pricingReport) - { - streamWriter.WriteLine($"{pricingResult.Sku},{pricingResult.OldPrice},{pricingResult.NewPrice},{pricingResult.OldCompareAt},{pricingResult.NewCompareAt}"); - } - - streamWriter.Close(); - fileStream.Close(); - - return new Attachment(filename); - } - } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to get the next set of products. Retrying"); + products = await _shopifyClient.Products.GetPrevious(); + } + } + + _emailService.Send("Pricing Update Completed", $"The pricing update has completed."); + } + } } \ No newline at end of file diff --git a/PartSource.Automation/PartSource.Automation.csproj b/PartSource.Automation/PartSource.Automation.csproj index 2fd53a8..10a58e3 100644 --- a/PartSource.Automation/PartSource.Automation.csproj +++ b/PartSource.Automation/PartSource.Automation.csproj @@ -18,9 +18,10 @@ - - - + + + + diff --git a/PartSource.Automation/Program.cs b/PartSource.Automation/Program.cs index 6925c45..86198df 100644 --- a/PartSource.Automation/Program.cs +++ b/PartSource.Automation/Program.cs @@ -15,6 +15,7 @@ using PartSource.Services; using Ratermania.Automation.DependencyInjection; using Ratermania.Automation.Logging; using Ratermania.Shopify.DependencyInjection; +using Ratermania.JwtSpot.Configuration; using System; using System.IO; using System.Threading.Tasks; @@ -68,36 +69,33 @@ namespace PartSource.Automation { options.ApiKey = builder.Configuration["Shopify:ApiKey"]; options.ApiSecret = builder.Configuration["Shopify:ApiSecret"]; - options.ApiVersion = "2021-01"; + options.ApiVersion = "2022-10"; options.ShopDomain = builder.Configuration["Shopify:ShopDomain"]; //options.ApiKey = "9a533dad460321c6ce8f30bf5b8691ed"; //options.ApiSecret = "dc9e28365d9858e544d57ac7af43fee7"; - //options.ApiVersion = "2021-01"; + //options.ApiVersion = "2022-10"; //options.ShopDomain = "dev-partsource.myshopify.com"; }) .AddAutomation(options => - { - //options.HasBaseInterval(new TimeSpan(0, 15, 0)) - // .HasMaxFailures(3) - // .HasJob(options => - // options.HasInterval(new TimeSpan(24, 0, 0)) - // .StartsAt(DateTime.Today.AddHours(26)) - // ) - // .HasJob(options => - // options.HasInterval(new TimeSpan(24, 0, 0)) - // .StartsAt(DateTime.Today.AddHours(27)) - // .HasDependency() - // ); - options.HasBaseInterval(new TimeSpan(0, 15, 0)) .HasMaxFailures(3) - .HasJob(options => + .HasJob(options => options.HasInterval(new TimeSpan(24, 0, 0)) - ); - //.AddApiServer(); - }) + .StartsAt(DateTime.Today.AddHours(26))) + .HasJob(options => + options.HasInterval(new TimeSpan(24, 0, 0)) + .StartsAt(DateTime.Today.AddHours(27)) + .HasDependency()) + .UseApiServer(opts => + opts.HasApiKey("PartsourceAPIKey") + .UseJwtSpot(jwt => + jwt.HasAudience(builder.Configuration["JwtSpot:Audience"]) + .HasIssuer(builder.Configuration["JwtSpot:Issuer"]) + .UseX509Certificate(builder.Configuration["JwtSpot:CertPath"]) + .UseJwksUrl(builder.Configuration["JwtSpot:JwksUrl"]))) + .UseSqlServer(builder.Configuration.GetConnectionString("AutomationDatabase"))) .AddSingleton(builder.Configuration.GetSection("FtpServers:AzureConfiguration").Get()) .AddSingleton() @@ -114,7 +112,7 @@ namespace PartSource.Automation logging.AddEventLog(); logging.AddConsole(); - // logging.AddProvider(new AutomationLoggerProvider()); + //logging.AddProvider(new AutomationLoggerProvider()); }); } } diff --git a/PartSource.Automation/appsettings.json b/PartSource.Automation/appsettings.json index 47ad194..c0f06be 100644 --- a/PartSource.Automation/appsettings.json +++ b/PartSource.Automation/appsettings.json @@ -1,5 +1,6 @@ { "ConnectionStrings": { + "AutomationDatabase": "Data Source=localhost;Initial Catalog=Automation;Integrated Security=true;Trust Server Certificate=true;", "FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true", "PartSourceDatabase": "Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, @@ -31,12 +32,18 @@ "ApiSecret": "527a3b4213c2c7ecb214728a899052df", "ShopDomain": "partsource.myshopify.com" }, + "JwtSpot": { + "Audience": "Ratermania.Automation", + "Issuer": "https://tomraterman.com", + "JwksUrl": "http://localhost:5103/jwks", + "CertPath": "C:\\Users\\tom\\Desktop\\PartsourceAutomation.pfx" + }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information", - // "Microsoft.EntityFrameworkCore.Database.Command": "Information" + "Microsoft.Hosting.Lifetime": "Information" + // "Microsoft.EntityFrameworkCore.Database.Command": "Information" }, "EventLog": { "LogLevel": { diff --git a/PartSource.Services/PartSource.Services.csproj b/PartSource.Services/PartSource.Services.csproj index 483842b..661b722 100644 --- a/PartSource.Services/PartSource.Services.csproj +++ b/PartSource.Services/PartSource.Services.csproj @@ -14,7 +14,7 @@ - + diff --git a/PartSource.sln b/PartSource.sln index 7f24697..198692f 100644 --- a/PartSource.sln +++ b/PartSource.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29613.14 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32519.379 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PartSource.Api", "PartSource.Api\PartSource.Api.csproj", "{126B8961-1D86-4F73-9BB9-79ECE78E9257}" EndProject diff --git a/nuget.config b/nuget.config index 75be74a..7c02f79 100644 --- a/nuget.config +++ b/nuget.config @@ -1,10 +1,9 @@ - + - - +