using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using PartSource.Automation.Models.Jobs; using PartSource.Automation.Services; using PartSource.Data.Contexts; using PartSource.Data.Models; using Ratermania.Automation.Interfaces; using Ratermania.Shopify; using Ratermania.Shopify.Resources; using Ratermania.Shopify.Resources.Enums; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Mail; 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 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; try { products = await _shopifyClient.Products.Get(new Dictionary { { "limit", 250 } }); prices = await _partSourceContext.PartPrices.AsNoTracking().ToListAsync(); } catch (Exception ex) { _logger.LogError(ex, "Failed to get the initial set of products from Shopify."); throw; } while (products != null && products.Any()) { foreach (Product product in products) { List productPricingUpdate = new List(); if (product.Variants.Length > 0) { bool hasUpdate = false; 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 (partPrice == null || !partPrice.Your_Price.HasValue || !partPrice.Compare_Price.HasValue) { continue; } 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 }); product.Variants[i].Price = partPrice.Your_Price.Value; product.Variants[i].CompareAtPrice = partPrice.Compare_Price.Value; product.PublishedAt = partPrice.Active.Trim().ToUpperInvariant() == "Y" ? DateTime.Now : null; product.PublishedScope = PublishedScope.Global; //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 //}; hasUpdate = true; } } if (hasUpdate) { try { //await _shopifyClient.Metafields.Add(metafield); await _shopifyClient.Products.Update(product); pricingReport.AddRange(productPricingUpdate); } catch (Exception ex) { _logger.LogWarning(ex, $"Failed to update pricing for product ID {product.Id}"); } } } } 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); } } }