using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using PartSource.Automation.Jobs.Interfaces; using PartSource.Automation.Models; using PartSource.Automation.Services; using PartSource.Data; using PartSource.Data.Models; using PartSource.Data.Nexpart; using PartSource.Services; using PartSource.Services.Integrations; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Ratermania.Shopify.Entities; namespace PartSource.Automation.Jobs { public class UpdateFitment : IAutomationJob { private readonly IServiceProvider _serviceProvider; private readonly ShopifyClient _shopifyClient; private readonly PartSourceContext _partSourceContext; private readonly NexpartService _nexpartService; private readonly VehicleService _vehicleService; public UpdateFitment(IServiceProvider serviceProvider, PartSourceContext partSourceContext, ShopifyClient shopifyClient, NexpartService nexpartService, VehicleService vehicleService) { _partSourceContext = partSourceContext; _shopifyClient = shopifyClient; _vehicleService = vehicleService; } public async Task Run() { IList parts = _partSourceContext.ImportData.Where(i => new[] { "Raybestos Brakes", "MotoMaster", "Pro Series OE Plus Brake Pads" }.Contains(i.Vendor)).ToList(); foreach (ImportData importData in parts) { try { Product product = await _shopifyClient.Products.GetById((long)importData.ShopifyId); if (product == null) { continue; } bool isFitment = false; IList vehicles = _vehicleService.GetVehiclesForPart(importData.PartNumber, importData.LineCode); IList vehicleIdFitment = _vehicleService.GetVehicleIdFitment(vehicles); if (vehicleIdFitment.Count > 0) { isFitment = true; string json = JsonConvert.SerializeObject(vehicleIdFitment); if (json.Length >= 100000) { continue; } Metafield vehicleMetafield = new Metafield { Namespace = "fitment", Key = "ids", Value = json, ValueType = "json_string", OwnerResource = "product", OwnerId = product.Id }; await _shopifyClient.Metafields.Add(vehicleMetafield); } IList ymmFitment = _vehicleService.GetYmmFitment(vehicles); if (ymmFitment.Count > 0) { isFitment = true; string json = JsonConvert.SerializeObject(ymmFitment); if (json.Length >= 100000) { continue; } Metafield ymmMetafield = new Metafield { Namespace = "fitment", Key = "seo", Value = json, ValueType = "json_string", OwnerResource = "product", OwnerId = product.Id }; await _shopifyClient.Metafields.Add(ymmMetafield); } Metafield isFitmentMetafield = new Metafield { Namespace = "Flags", Key = "IsFitment", Value = isFitment.ToString(), ValueType = "string", OwnerResource = "product", OwnerId = product.Id }; await _shopifyClient.Metafields.Add(isFitmentMetafield); List tags = new List { importData.LineCode, importData.PartNumber }; for (int i = 0; i < vehicleIdFitment.Count; i += 25) { tags.Add(string.Join('-', vehicleIdFitment.Skip(i).Take(25).Select(i => $"v{i}"))); } tags.AddRange(ymmFitment); if (tags.Count > 250) { tags = tags.Take(250).ToList(); } product.Tags = string.Join(',', tags); await _shopifyClient.Products.Update(product); } catch (Exception ex) { Console.WriteLine($"{importData.VariantSku}: {ex.Message}"); } } return new AutomationJobResult { IsSuccess = true }; } private async Task DeleteFitmentMetafields(long shopifyId) { IDictionary parameters = new Dictionary { { "metafield[owner_id]", shopifyId}, { "metafield[owner_resource]", "product" }, { "namespace", "fitment" }, }; IEnumerable metafields = await _shopifyClient.Metafields.Get(parameters); foreach (Metafield metafield in metafields) { await _shopifyClient.Metafields.Delete(metafield); } } public IList GetVehicles(string partNumber, string lineCode) { partNumber = Regex.Replace(partNumber, "[^a-zA-Z0-9]", string.Empty); //string sql = $"select distinct BaseVehicleId, EngineConfigId from dbo.Fitment where ManufacturerCode in (select WhiCode from DcfMapping where PartSourceCode='{lineCode}') and (partNumber = '{partNumber}' or partNumber = '{partNumber.Replace("-", string.Empty)}')"; string sql = $"with FitmentIds (BaseVehicleId, EngineConfigId) as (select distinct BaseVehicleId, EngineConfigId from dbo.Fitment where LineCode in (select WhiCode from DcfMapping where LineCode='{lineCode}') and PartNumber = '{partNumber}') select v.* from VehicleData v join FitmentIds f on v.BaseVehicleId = f.BaseVehicleId and v.EngineConfigId = f.EngineConfigId;"; #pragma warning disable EF1000 // Possible SQL injection vulnerability. IList vehicles = _partSourceContext.Vehicles.FromSql(sql).ToList(); #pragma warning restore EF1000 // Possible SQL injection vulnerability. return vehicles; } private void Update() { } } }