Initial commit
This commit is contained in:
145
PartSource.Automation/Jobs/AddProducts.cs
Normal file
145
PartSource.Automation/Jobs/AddProducts.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using PartSource.Automation.Jobs.Interfaces;
|
||||
using PartSource.Automation.Models;
|
||||
using PartSource.Automation.Services;
|
||||
using PartSource.Data;
|
||||
using PartSource.Data.Models;
|
||||
using PartSource.Data.Shopify;
|
||||
using PartSource.Services;
|
||||
using PartSource.Services.Integrations;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PartSource.Automation.Jobs
|
||||
{
|
||||
public class AddProducts : IAutomationJob
|
||||
{
|
||||
private readonly PartSourceContext _partSourceContext;
|
||||
private readonly ShopifyClient _shopifyClient;
|
||||
|
||||
public AddProducts(PartSourceContext partSourceContext, ShopifyClient shopifyClient)
|
||||
{
|
||||
_partSourceContext = partSourceContext;
|
||||
_shopifyClient = shopifyClient;
|
||||
}
|
||||
|
||||
|
||||
public async Task<AutomationJobResult> Run()
|
||||
{
|
||||
await AddSkus();
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
IsSuccess = true
|
||||
};
|
||||
}
|
||||
|
||||
public async Task AddSkus()
|
||||
{
|
||||
ImportData importData = _partSourceContext.ImportData.FirstOrDefault(p => !p.ShopifyId.HasValue);
|
||||
|
||||
while (importData != null)
|
||||
{
|
||||
if (importData == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Images
|
||||
List<ProductImage> productImages = new List<ProductImage>();
|
||||
string[] imageUrls = importData.ImageSrc?.Split(',');
|
||||
|
||||
if (imageUrls?.Length > 0)
|
||||
{
|
||||
foreach (string url in imageUrls)
|
||||
{
|
||||
productImages.Add(new ProductImage
|
||||
{
|
||||
Src = url,
|
||||
Alt = importData.ImageAltText
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
productImages.Add(new ProductImage
|
||||
{
|
||||
Src = "https://cdn.shopify.com/s/files/1/2239/4255/files/No_Image_Found.jpg",
|
||||
Alt = "No Image Found"
|
||||
});
|
||||
}
|
||||
|
||||
// Product Tags
|
||||
List<string> productTags = new List<string>
|
||||
{
|
||||
importData.LineCode,
|
||||
importData.PartNumber,
|
||||
};
|
||||
|
||||
List<ProductVariant> productVariants = new List<ProductVariant>();
|
||||
productVariants.Add(new ProductVariant
|
||||
{
|
||||
InventoryPolicy = "Deny",
|
||||
CompareAtPrice = importData.CompareAt,
|
||||
Price = importData.Price,
|
||||
Sku = importData.VariantSku,
|
||||
Title = importData.VariantTitle,
|
||||
Option1 = importData.IsVariant.ToString(),
|
||||
RequiresShipping = false
|
||||
});
|
||||
|
||||
Product requestData = new Product
|
||||
{
|
||||
BodyHtml = importData.BodyHtml,
|
||||
Title = importData.Title,
|
||||
Vendor = importData.Vendor,
|
||||
Tags = string.Join(",", productTags),
|
||||
Published = true,
|
||||
//ProductType = importData.FINELINE_NM,
|
||||
Images = productImages.ToArray(),
|
||||
Variants = productVariants.ToArray(),
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
|
||||
requestData = await _shopifyClient.Products.Add(requestData);
|
||||
|
||||
if (requestData.Id > 0)
|
||||
{
|
||||
importData.ShopifyId = requestData.Id;
|
||||
|
||||
_partSourceContext.SaveChanges();
|
||||
|
||||
Console.WriteLine($"{importData.VariantSku}");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"SHOPIFY ID WAS 0 - {importData.VariantSku}");
|
||||
}
|
||||
|
||||
importData = _partSourceContext.ImportData.FirstOrDefault(p => !p.ShopifyId.HasValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//private void Log(string message)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// using (FileStream fileStream = File.OpenWrite(@"C:\users\tommy\desktop\log.txt"))
|
||||
// {
|
||||
// fileStream.Write(Encoding.UTF8.GetBytes(message + "\n"));
|
||||
// }
|
||||
// }
|
||||
|
||||
// catch
|
||||
// {
|
||||
// // LOL Fix this
|
||||
// Log(message);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
320
PartSource.Automation/Jobs/BuildVehicleCache.cs
Normal file
320
PartSource.Automation/Jobs/BuildVehicleCache.cs
Normal file
@@ -0,0 +1,320 @@
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using PartSource.Automation.Jobs.Interfaces;
|
||||
//using PartSource.Automation.Services;
|
||||
//using PartSource.Data;
|
||||
//using PartSource.Data.Models;
|
||||
//using PartSource.Data.Nexpart;
|
||||
//using PartSource.Services;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
|
||||
//using BaseVehicle = PartSource.Data.Models.BaseVehicle;
|
||||
|
||||
//namespace PartSource.Automation.Jobs
|
||||
//{
|
||||
// public class BuildVehicleCache : IAutomationJob
|
||||
// {
|
||||
// private readonly NexpartService _nexpartService;
|
||||
// private readonly PartSourceContext _partSourceContext;
|
||||
|
||||
// private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
// public BuildVehicleCache(IServiceProvider serviceProvider, PartSourceContext partSourceContext, NexpartService nexpartService)
|
||||
// {
|
||||
// _nexpartService = nexpartService;
|
||||
// _partSourceContext = partSourceContext;
|
||||
// _serviceProvider = serviceProvider;
|
||||
// }
|
||||
|
||||
// public void Run()
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// //AddMakes();
|
||||
// //AddModels();
|
||||
|
||||
// // AddEngines();
|
||||
|
||||
// //AddYearMakeModels();
|
||||
|
||||
// AddSubmodels();
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// ;
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void AddEngines()
|
||||
// {
|
||||
// IList<BaseVehicle> baseVehicles = _partSourceContext.BaseVehicles.ToList();
|
||||
|
||||
// foreach (BaseVehicle baseVehicle in baseVehicles)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// WHIEngineSearch whiEngineSearch = new WHIEngineSearch
|
||||
// {
|
||||
// VehicleIdentifier = new VehicleIdentifier
|
||||
// {
|
||||
// BaseVehicleId = baseVehicle.Id
|
||||
// }
|
||||
// };
|
||||
|
||||
// WHIEngineSearchResponse response = _nexpartService.SendRequest<WHIEngineSearch, WHIEngineSearchResponse>(whiEngineSearch).Result;
|
||||
|
||||
// foreach (WHIEngine engine in response.ResponseBody.WHIEngine)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
|
||||
// if (!_partSourceContext.Engines.Any(e => e.Id == engine.Id))
|
||||
// {
|
||||
// _partSourceContext.Engines.Add(new Data.Models.Engine
|
||||
// {
|
||||
// Id = engine.Id,
|
||||
// Description = engine.Description
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// _partSourceContext.SaveChanges();
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Failed to add engine { engine.Id } - { ex.Message }");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Failed to add engines for base vehicle { baseVehicle.Id } - { ex.Message }");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void AddSubmodels()
|
||||
// {
|
||||
// int maxBaseVehicleId = _partSourceContext.Submodels.Any()
|
||||
// ? _partSourceContext.Submodels.Max(s => s.BaseVehicleId)
|
||||
// : 0;
|
||||
|
||||
// IList<BaseVehicle> baseVehicles = _partSourceContext.BaseVehicles.AsNoTracking().Where(b => b.Id > maxBaseVehicleId).ToList();
|
||||
|
||||
// foreach (BaseVehicle baseVehicle in baseVehicles)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// SubModelSearch smSearch = new SubModelSearch()
|
||||
// {
|
||||
// MakeId = baseVehicle.VehicleMakeId,
|
||||
// ModelId = baseVehicle.VehicleModelId,
|
||||
// Year = baseVehicle.Year,
|
||||
// RegionId = 2
|
||||
// };
|
||||
// SubModelSearchResponse smResponse = _nexpartService.SendRequest<SubModelSearch, SubModelSearchResponse>(smSearch).Result;
|
||||
|
||||
// SubModel[] subModels = smResponse.ResponseBody?.SubModel;
|
||||
// if (subModels == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// foreach (SubModel submodel in subModels)
|
||||
// {
|
||||
// EngineSearch requestContent = new EngineSearch()
|
||||
// {
|
||||
// VehicleIdentifier = new VehicleIdentifier()
|
||||
// {
|
||||
// BaseVehicleId = baseVehicle.Id
|
||||
// },
|
||||
// SubModelId = int.Parse(submodel.Id)
|
||||
// };
|
||||
// EngineSearchResponse response = _nexpartService.SendRequest<EngineSearch, EngineSearchResponse>(requestContent).Result;
|
||||
|
||||
// if (response.ResponseBody == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// foreach (Data.Nexpart.Engine engine in response.ResponseBody.Engine)
|
||||
// {
|
||||
// VehicleIdSearch vidSearch = new VehicleIdSearch
|
||||
// {
|
||||
// VehicleIdentifier = new VehicleIdentifier()
|
||||
// {
|
||||
// BaseVehicleId = baseVehicle.Id,
|
||||
// EngineConfigId = engine.Id
|
||||
// },
|
||||
// Criterion = new Criterion[]
|
||||
// {
|
||||
// new Criterion
|
||||
// {
|
||||
// Attribute = "SUB_MODEL",
|
||||
// Id = int.Parse(submodel.Id)
|
||||
// }
|
||||
// },
|
||||
// RegionId = new RegionId
|
||||
// {
|
||||
// Value = 2
|
||||
// },
|
||||
// ResultOption = new ResultOption[]
|
||||
// {
|
||||
// new ResultOption
|
||||
// {
|
||||
// Value = "WHI_ENGINE"
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// VehicleIdSearchResponse vidResponse = _nexpartService.SendRequest<VehicleIdSearch, VehicleIdSearchResponse>(vidSearch).Result;
|
||||
|
||||
// if (vidResponse != null && vidResponse.ResponseBody.VehicleToEngineConfigId > 0)
|
||||
// {
|
||||
// _partSourceContext.Submodels.Add(new Submodel
|
||||
// {
|
||||
// VehicleToEngineConfigId = vidResponse.ResponseBody.VehicleToEngineConfigId,
|
||||
// SubmodelId = int.Parse(submodel.Id),
|
||||
// BaseVehicleId = baseVehicle.Id,
|
||||
// EngineId = vidResponse.ResponseBody.WHIEngineId
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// _partSourceContext.SaveChanges();
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Failed to add BaseVehicleId {baseVehicle.Id}: {ex.Message}");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void AddYearMakeModels()
|
||||
// {
|
||||
// BaseVehicleSearch request = new BaseVehicleSearch
|
||||
// {
|
||||
// Years = new Years
|
||||
// {
|
||||
// From = 1950,
|
||||
// To = 2020
|
||||
// },
|
||||
// Region = new[]
|
||||
// {
|
||||
// new Region
|
||||
// {
|
||||
// Id = 2
|
||||
// }
|
||||
// },
|
||||
// VehicleType = new[]
|
||||
// {
|
||||
// new VehicleType
|
||||
// {
|
||||
// Id = 5
|
||||
// },
|
||||
// new VehicleType
|
||||
// {
|
||||
// Id = 6
|
||||
// },
|
||||
// new VehicleType
|
||||
// {
|
||||
// Id = 7
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// BaseVehicleSearchResponse response = _nexpartService.SendRequest<BaseVehicleSearch, BaseVehicleSearchResponse>(request).Result;
|
||||
|
||||
// foreach (Data.Nexpart.BaseVehicle vehicle in response.ResponseBody.BaseVehicle)
|
||||
// {
|
||||
// _partSourceContext.BaseVehicles.Add(new Data.Models.BaseVehicle
|
||||
// {
|
||||
// Id = (int)vehicle.BaseVehicleId,
|
||||
// VehicleMakeId = (int)vehicle.MakeId,
|
||||
// VehicleModelId = (int)vehicle.ModelId,
|
||||
// Year = (int)vehicle.Year
|
||||
// });
|
||||
// }
|
||||
|
||||
// _partSourceContext.SaveChanges();
|
||||
// }
|
||||
|
||||
// private void AddMakes()
|
||||
// {
|
||||
// MakeSearch requestContent = new MakeSearch()
|
||||
// {
|
||||
// VehicleTypeId = new int[] { 5, 6, 7 },
|
||||
// RegionId = new int[] { 2 }
|
||||
// };
|
||||
|
||||
// MakeSearchResponse response = _nexpartService.SendRequest<MakeSearch, MakeSearchResponse>(requestContent).Result;
|
||||
|
||||
// foreach (Make make in response.ResponseBody.Make)
|
||||
// {
|
||||
// _partSourceContext.VehicleMakes.Add(new VehicleMake
|
||||
// {
|
||||
// Id = make.Id,
|
||||
// Name = make.Value
|
||||
// });
|
||||
// }
|
||||
|
||||
// _partSourceContext.SaveChanges();
|
||||
// }
|
||||
|
||||
// private void AddModels()
|
||||
// {
|
||||
// IList<VehicleMake> vehicleMakes = _partSourceContext.VehicleMakes.ToList();
|
||||
// IDictionary<int, VehicleModel> vehicleModels = new Dictionary<int, VehicleModel>();
|
||||
|
||||
// foreach (VehicleMake vehicleMake in vehicleMakes)
|
||||
// {
|
||||
// for (int year = 1950; year <= 2020; year++)
|
||||
// {
|
||||
// ModelSearch requestContent = new ModelSearch()
|
||||
// {
|
||||
// MakeId = vehicleMake.Id,
|
||||
// Year = year,
|
||||
// VehicleTypeId = new int[] { 5, 6, 7 },
|
||||
// RegionId = new int[] { 2 }
|
||||
// };
|
||||
|
||||
// ModelSearchResponse response = _nexpartService.SendRequest<ModelSearch, ModelSearchResponse>(requestContent).Result;
|
||||
|
||||
// if (response.ResponseBody == null || response.ResponseBody.Length == 0)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// foreach (Model model in response.ResponseBody[0].Model)
|
||||
// {
|
||||
// bool result = vehicleModels.TryGetValue(model.Id, out VehicleModel throwaway);
|
||||
|
||||
// if (!result)
|
||||
// {
|
||||
// VehicleModel vehicleModel = new VehicleModel
|
||||
// {
|
||||
// Id = model.Id,
|
||||
// Name = model.Value,
|
||||
// VehicleMakeId = vehicleMake.Id
|
||||
// };
|
||||
|
||||
// vehicleModels.Add(model.Id, vehicleModel);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// _partSourceContext.VehicleModels.AddRange(vehicleModels.Values);
|
||||
// _partSourceContext.SaveChanges();
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
//}
|
||||
62
PartSource.Automation/Jobs/DeleteProducts.cs
Normal file
62
PartSource.Automation/Jobs/DeleteProducts.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using PartSource.Data.Shopify;
|
||||
using PartSource.Services;
|
||||
using PartSource.Automation.Jobs.Interfaces;
|
||||
using PartSource.Automation.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using PartSource.Data;
|
||||
using PartSource.Data.Models;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PartSource.Services.Integrations;
|
||||
using PartSource.Automation.Models;
|
||||
|
||||
namespace PartSource.Automation.Jobs
|
||||
{
|
||||
public class DeleteProducts : IAutomationJob
|
||||
{
|
||||
private readonly ShopifyClient _shopifyClient;
|
||||
|
||||
public DeleteProducts(ShopifyClient shopifyClient)
|
||||
{
|
||||
_shopifyClient = shopifyClient;
|
||||
}
|
||||
|
||||
// If this job fails, oh well. Run it again and again until it works, or use the Shopify UI (LOL)
|
||||
public async Task<AutomationJobResult> Run()
|
||||
{
|
||||
Console.WriteLine("This job will delete ALL PRODUCTS from Shopify. If you really want to delete EVERY SINGLE PRODUCT, type 'mechanical keyboard' below.");
|
||||
string input = Console.ReadLine();
|
||||
|
||||
if (input != "mechanical keyboard")
|
||||
{
|
||||
return new AutomationJobResult
|
||||
{
|
||||
IsSuccess = true
|
||||
};
|
||||
}
|
||||
|
||||
IEnumerable<Product> products = await _shopifyClient.Products.Get();
|
||||
|
||||
while (products != null)
|
||||
{
|
||||
foreach (Product product in products)
|
||||
{
|
||||
bool result = await _shopifyClient.Products.Delete(product);
|
||||
}
|
||||
|
||||
products = await _shopifyClient.Products.GetNext();
|
||||
|
||||
Console.Write('.');
|
||||
}
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
Message = "All products deleted. Don't forget to truncate the ImportData table",
|
||||
IsSuccess = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
53
PartSource.Automation/Jobs/ExecuteSsisPackages.cs
Normal file
53
PartSource.Automation/Jobs/ExecuteSsisPackages.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using PartSource.Automation.Jobs.Interfaces;
|
||||
using PartSource.Automation.Models;
|
||||
using PartSource.Automation.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PartSource.Automation.Jobs
|
||||
{
|
||||
public class ExecuteSsisPackages : IAutomationJob
|
||||
{
|
||||
private readonly FtpService _ftpService;
|
||||
private readonly SsisService _ssisService;
|
||||
|
||||
// TODO: set from config
|
||||
private readonly string[] _ssisPackages = { "Parts Availability", "Parts Price" };
|
||||
|
||||
public ExecuteSsisPackages(FtpService ftpService, SsisService ssisService)
|
||||
{
|
||||
_ftpService = ftpService;
|
||||
_ssisService = ssisService;
|
||||
}
|
||||
|
||||
public async Task<AutomationJobResult> Run()
|
||||
{
|
||||
IList<string> updatedPackages = new List<string>();
|
||||
IList<string> failedPackages = new List<string>();
|
||||
|
||||
foreach (string package in _ssisPackages)
|
||||
{
|
||||
try
|
||||
{
|
||||
_ftpService.Download($"{package}.txt");
|
||||
_ssisService.Execute($"{package}.dtsx");
|
||||
|
||||
updatedPackages.Add(package);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
failedPackages.Add(package);
|
||||
// TODO: Log
|
||||
}
|
||||
}
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
Message = $"Updated Packages: {string.Join(',', updatedPackages)} \n Failed Packages: {string.Join(',', failedPackages)}",
|
||||
IsSuccess = failedPackages.Count == 0
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
14
PartSource.Automation/Jobs/Interfaces/IAutomationJob.cs
Normal file
14
PartSource.Automation/Jobs/Interfaces/IAutomationJob.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using PartSource.Automation.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PartSource.Automation.Jobs.Interfaces
|
||||
{
|
||||
public interface IAutomationJob
|
||||
{
|
||||
Task<AutomationJobResult> Run();
|
||||
}
|
||||
}
|
||||
21
PartSource.Automation/Jobs/TestJob.cs
Normal file
21
PartSource.Automation/Jobs/TestJob.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using PartSource.Automation.Jobs.Interfaces;
|
||||
using PartSource.Automation.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PartSource.Automation.Jobs
|
||||
{
|
||||
public class TestJob : IAutomationJob
|
||||
{
|
||||
public async Task<AutomationJobResult> Run()
|
||||
{
|
||||
return new AutomationJobResult
|
||||
{
|
||||
Message = "Test job ran successfully",
|
||||
IsSuccess = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
535
PartSource.Automation/Jobs/UpdateFitment - Copy.cs
Normal file
535
PartSource.Automation/Jobs/UpdateFitment - Copy.cs
Normal file
@@ -0,0 +1,535 @@
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using PartSource.Automation.Jobs.Interfaces;
|
||||
//using PartSource.Automation.Services;
|
||||
//using PartSource.Data;
|
||||
//using PartSource.Data.Models;
|
||||
//using PartSource.Data.Nexpart;
|
||||
//using PartSource.Data.Shopify;
|
||||
//using PartSource.Services;
|
||||
//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;
|
||||
|
||||
//namespace PartSource.Automation.Jobs
|
||||
//{
|
||||
// public class UpdateFitmentCopy : AddProducts, IAutomationJob
|
||||
// {
|
||||
// private readonly IServiceProvider _serviceProvider;
|
||||
// private readonly SuperOldShopifyService _shopifyService;
|
||||
// private readonly PartSourceContext _partSourceContext;
|
||||
// private readonly NexpartService _nexpartService;
|
||||
|
||||
|
||||
// private ConcurrentQueue<long> _shopifyIdQueue;
|
||||
// private string _connectionString = "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=3600;";
|
||||
|
||||
// private readonly int _threadCount = 1;
|
||||
|
||||
// public UpdateFitmentCopy(IServiceProvider serviceProvider, PartSourceContext partSourceContext, SuperOldShopifyService shopifyService, NexpartService nexpartService) : base(serviceProvider, partSourceContext, nexpartService, shopifyService)
|
||||
// {
|
||||
// _serviceProvider = serviceProvider;
|
||||
// _nexpartService = nexpartService;
|
||||
// _shopifyService = shopifyService;
|
||||
// _partSourceContext = partSourceContext;
|
||||
|
||||
// }
|
||||
|
||||
// new public void Run()
|
||||
// {
|
||||
// Console.WriteLine("");
|
||||
|
||||
|
||||
// UpdateMetafields(26);
|
||||
|
||||
|
||||
|
||||
|
||||
// //UpdatePublished();
|
||||
|
||||
|
||||
// //FitmentReport();
|
||||
|
||||
// // List<long> shopifyIds = _partSourceContext.ImportData.Where(s => s.IsFitment.Value && s.ShopifyId != null).Select(s => (long)s.ShopifyId).ToList();
|
||||
// //List<long> shopifyIds = _partSourceContext.ImportData.Where(s => s.ShopifyId != null).Select(s => (long)s.ShopifyId).ToList();
|
||||
|
||||
// //_shopifyIdQueue = new ConcurrentQueue<long>(shopifyIds);
|
||||
|
||||
// //Parallel.For(0, _threadCount, i =>
|
||||
// // {
|
||||
|
||||
|
||||
// // //Categorize();
|
||||
// // });
|
||||
// // });
|
||||
// }
|
||||
|
||||
|
||||
// private IList<string> GetYmmFitmentTags(BuyersGuideSearchResponse response)
|
||||
// {
|
||||
// BuyersGuideMake[] makes = response?.ResponseBody?.Apps?.Make;
|
||||
// if (makes == null)
|
||||
// {
|
||||
// return new List<string>();
|
||||
// }
|
||||
|
||||
// IList<string> fitmentTags = new List<string>();
|
||||
|
||||
// foreach (BuyersGuideMake make in makes)
|
||||
// {
|
||||
// foreach (BuyersGuideModel model in make.Model)
|
||||
// {
|
||||
// IList<int> years = new List<int>();
|
||||
// for (int year = model.FromYear; year <= model.ToYear; year++)
|
||||
// {
|
||||
// years.Add(year);
|
||||
// }
|
||||
|
||||
// string tag = $"{string.Join('-', years)} {make.Name} {model.Name}";
|
||||
|
||||
// fitmentTags.Add(tag);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return fitmentTags;
|
||||
// }
|
||||
|
||||
// //private IList<string> GetVehicleIdFitmentTags(BuyersGuideSearchResponse response)
|
||||
// //{
|
||||
// // BuyersGuideMake[] makes = response?.ResponseBody?.Apps?.Make;
|
||||
// // if (makes == null)
|
||||
// // {
|
||||
// // return new List<string>();
|
||||
// // }
|
||||
|
||||
// // IList<string> fitmentTags = new List<string>();
|
||||
|
||||
// // foreach (BuyersGuideMake make in makes)
|
||||
// // {
|
||||
// // foreach (BuyersGuideModel model in make.Model)
|
||||
// // {
|
||||
// // foreach (BuyersGuideEngine engine in model.Engine)
|
||||
// // {
|
||||
// // IList<int> vehicleIds = _partSourceContext.VehicleData.Where(d =>
|
||||
// // d.EngineDescription == engine.Desc
|
||||
// // && d.Year == engine.Year
|
||||
// // && d.MakeName == make.Name
|
||||
// // && d.ModelName == model.Name
|
||||
// // )
|
||||
// // .Select(d => d.VehicleToEngineConfigId)
|
||||
// // .ToList();
|
||||
|
||||
// // foreach (int id in vehicleIds)
|
||||
// // {
|
||||
// // string tag = $"v{id}";
|
||||
|
||||
// // fitmentTags.Add(tag);
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // return fitmentTags;
|
||||
// //}
|
||||
|
||||
// /* public void UpdateFitmentViaBuyersGuideSearch()
|
||||
// {
|
||||
// int i = 0;
|
||||
// IList<Product> products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
|
||||
// while (products.Count > 0)
|
||||
// {
|
||||
// foreach (Product product in products)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// //if (product.Tags.Contains("-v") || product.Tags.ToLowerInvariant().Contains("zzzisfitment=false"))
|
||||
// //{
|
||||
// // continue;
|
||||
// //}
|
||||
|
||||
// ImportData importData = _partSourceContext.ImportData.FirstOrDefault(p => p.ShopifyId == product.Id);
|
||||
// if (importData == null || !importData.IsFitment.Value)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// importData.DcfMappings = _partSourceContext.DcfMappings.Where(d => d.LineCode == importData.LineCode).ToList();
|
||||
|
||||
// BuyersGuideSearch buyersGuideSearch = new BuyersGuideSearch();
|
||||
// List<string> ymmFitmentTags = new List<string>();
|
||||
// List<string> vehicleIdFitmentTags = new List<string>();
|
||||
|
||||
// foreach (DcfMapping mapping in importData.DcfMappings)
|
||||
// {
|
||||
// buyersGuideSearch = new BuyersGuideSearch
|
||||
// {
|
||||
// Part = new BuyersGuidePart
|
||||
// {
|
||||
// PartNumber = importData.PartNumber,
|
||||
// MfrCode = mapping.WhiCode
|
||||
// }
|
||||
// };
|
||||
|
||||
// BuyersGuideSearchResponse response = _nexpartService.SendRequest<BuyersGuideSearch, BuyersGuideSearchResponse>(buyersGuideSearch).Result;
|
||||
|
||||
// if (response.ResponseBody != null)
|
||||
// {
|
||||
// ymmFitmentTags.AddRange(GetYmmFitmentTags(response));
|
||||
// //vehicleIdFitmentTags.AddRange(GetVehicleIdFitmentTags(response));
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool published = true;
|
||||
// List<string> productTags = new List<string>
|
||||
// {
|
||||
// importData.LineCode,
|
||||
// importData.PartNumber
|
||||
// };
|
||||
|
||||
// published = (ymmFitmentTags.Count > 0 || vehicleIdFitmentTags.Count > 0);
|
||||
|
||||
// productTags.Add($"zzzisFitment={importData.IsFitment}");
|
||||
// productTags.AddRange(vehicleIdFitmentTags);
|
||||
// productTags.AddRange(ymmFitmentTags);
|
||||
|
||||
|
||||
// if (productTags.Count > 249)
|
||||
// {
|
||||
// string message = $"Truncating {importData.VariantSku} - {productTags.Count} product tags";
|
||||
|
||||
// // Console.WriteLine(message);
|
||||
|
||||
// productTags = productTags.Take(249).ToList();
|
||||
// }
|
||||
|
||||
// published = (ymmFitmentTags.Count > 0 || vehicleIdFitmentTags.Count > 0);
|
||||
|
||||
|
||||
// product.Tags = string.Join(",", productTags);
|
||||
// product.PublishedAt = published ? (DateTime?)DateTime.Now : null;
|
||||
|
||||
// bool updateResult = _shopifyService.UpdateProduct(product).Result;
|
||||
|
||||
// if (updateResult)
|
||||
// {
|
||||
// if (published)
|
||||
// {
|
||||
// Console.WriteLine($"{product.Id}");
|
||||
// }
|
||||
// }
|
||||
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine($"Failed to update product {product.Id}");
|
||||
// }
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"{ex.Message}");
|
||||
// }
|
||||
// }
|
||||
|
||||
// i++;
|
||||
// products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
// }
|
||||
|
||||
// } */
|
||||
|
||||
// /* private void UpdatePublished()
|
||||
// {
|
||||
// DbContextOptionsBuilder<PartSourceContext> optionsBuilder = new DbContextOptionsBuilder<PartSourceContext>();
|
||||
// optionsBuilder.UseSqlServer(_connectionString);
|
||||
|
||||
// PartSourceContext threadDbContext = new PartSourceContext(optionsBuilder.Options);
|
||||
|
||||
// int i = 0;
|
||||
// int updated = 0;
|
||||
// IList<Product> products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
|
||||
// while (products.Count > 0)
|
||||
// {
|
||||
// foreach (Product product in products)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// ImportData importData = threadDbContext.ImportData.FirstOrDefault(p => p.ShopifyId == product.Id);
|
||||
|
||||
// if (importData == null || !importData.IsFitment.Value)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (product.PublishedAt == null)
|
||||
// {
|
||||
// if (product.Tags.Contains("-v"))
|
||||
// {
|
||||
// IList<string> tags = product.Tags.Split(',');
|
||||
|
||||
// string fitmentTag = tags.Where(t => t.ToLowerInvariant().Contains("zzzisfitment")).FirstOrDefault();
|
||||
// tags.Remove(fitmentTag);
|
||||
// tags.Add("zzzisFitment=True");
|
||||
|
||||
// product.Tags = string.Join(',', tags);
|
||||
// product.PublishedAt = DateTime.Now;
|
||||
|
||||
// bool result = _shopifyService.UpdateProduct(product).Result;
|
||||
|
||||
// updated++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// i++;
|
||||
// products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
|
||||
// Console.Write($"\ri={i}");
|
||||
// }
|
||||
// } */
|
||||
|
||||
// private void FitmentReport()
|
||||
// {
|
||||
// IList<ImportData> importCache = _partSourceContext.ImportData.Where(s => s.IsFitment.Value && s.ShopifyId != null).ToList();
|
||||
// IList<DcfMapping> mappingCache = _partSourceContext.DcfMappings.ToList();
|
||||
|
||||
// Regex regex = new Regex("v[0-9]{6}");
|
||||
|
||||
// using (StreamWriter writer = File.AppendText("c:\\users\\tommy\\desktop\\fitment report.csv"))
|
||||
// {
|
||||
|
||||
// writer.WriteLine("Line Code,Part Number,WHI Match");
|
||||
|
||||
// int i = 0;
|
||||
// IList<Product> products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
|
||||
|
||||
// while (products.Count > 0)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// foreach (Product product in products)
|
||||
// {
|
||||
// ImportData importData = importCache.Join(
|
||||
// mappingCache,
|
||||
// d => d.LineCode,
|
||||
// m => m.LineCode,
|
||||
// (d, m) => d
|
||||
// )
|
||||
// .FirstOrDefault(p => p.ShopifyId == product.Id);
|
||||
|
||||
// if (importData == null || !importData.IsFitment.Value || product.Variants.Length == 0)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// bool tagged = regex.IsMatch(product.Tags);
|
||||
|
||||
// if (!tagged)
|
||||
// {
|
||||
// // IList<string> whiCodes = mappingCache.Where(d => d.LineCode == importData.LineCode).Select(d => d.WhiCode).ToList();
|
||||
// writer.WriteLine($"{importData.LineCode},{importData.PartNumber},{tagged}");
|
||||
// }
|
||||
// }
|
||||
|
||||
// i++;
|
||||
// products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine("whoops");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// private void UpdateMetafields(int i)
|
||||
// {
|
||||
// DbContextOptionsBuilder<PartSourceContext> optionsBuilder = new DbContextOptionsBuilder<PartSourceContext>();
|
||||
// optionsBuilder.UseSqlServer(_connectionString);
|
||||
|
||||
// ShopifyClient shopifyClient = new ShopifyClient(new Ratermania.Shopify.ShopifyOptionsBuilder
|
||||
// {
|
||||
// ShopDomain = "partsource.myshopify.com",
|
||||
// ApiVersion = "2020-01",
|
||||
// ApiKey = "88f931933b566ade1fc92c6a39f04b34",
|
||||
// ApiSecret = "527a3b4213c2c7ecb214728a899052df"
|
||||
// });
|
||||
|
||||
// PartSourceContext threadDbContext = new PartSourceContext(optionsBuilder.Options);
|
||||
// threadDbContext.Database.SetCommandTimeout(1440);
|
||||
|
||||
// IList<Product> products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
|
||||
// while (products.Count > 0)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// foreach (Product product in products)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if (product.Tags.Contains("-v") || product.Tags.ToLowerInvariant().Contains("zzzisfitment=false"))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// ImportData test = threadDbContext.ImportData.First();
|
||||
|
||||
// ImportData importData = threadDbContext.ImportData.FirstOrDefault(p => p.ShopifyId == product.Id);
|
||||
|
||||
// if (importData == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// bool published = true;
|
||||
// List<string> productTags = new List<string>
|
||||
// {
|
||||
// importData.LineCode,
|
||||
// importData.PartNumber
|
||||
// };
|
||||
|
||||
|
||||
|
||||
// IDictionary<string, IList<string>> positions = new Dictionary<string, IList<string>>();
|
||||
|
||||
// string partNumber = Regex.Replace(importData.PartNumber, "[^a-zA-Z0-9]", string.Empty);
|
||||
|
||||
// string sql = $"select distinct BaseVehicleId, EngineConfigId, LineCode, PartNumber, Position from dbo.Fitment where LineCode in (select WhiCode from DcfMapping where LineCode='{importData.LineCode}') and PartNumber = '{partNumber}'";
|
||||
|
||||
// IList<Fitment> fitments = _partSourceContext.Fitments.FromSql(sql).ToList();
|
||||
|
||||
|
||||
// foreach (Fitment fitment in fitments)
|
||||
// {
|
||||
// fitment.Position = fitment.Position.Replace("\"", string.Empty);
|
||||
|
||||
// if (string.IsNullOrEmpty(fitment.Position))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// VehicleData vehicle = _partSourceContext.VehicleData.FirstOrDefault(v => v.BaseVehicleId == fitment.BaseVehicleId && v.EngineConfigId == fitment.EngineConfigId);
|
||||
|
||||
// if (vehicle == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (positions.ContainsKey(fitment.Position))
|
||||
// {
|
||||
// positions[fitment.Position].Add(vehicle.VehicleToEngineConfigId.ToString());
|
||||
// }
|
||||
|
||||
// else
|
||||
// {
|
||||
// positions.Add(fitment.Position, new List<string>
|
||||
// {
|
||||
// vehicle.VehicleToEngineConfigId.ToString()
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// foreach (KeyValuePair<string, IList<string>> position in positions)
|
||||
// {
|
||||
// Metafield metafield = new Metafield
|
||||
// {
|
||||
// OwnerId = product.Id,
|
||||
// OwnerResource = "product",
|
||||
// Namespace = "partsource",
|
||||
// Key = position.Key,
|
||||
// Value = string.Join(',', position.Value),
|
||||
// ValueType = "string"
|
||||
// };
|
||||
|
||||
// var x = shopifyClient.Metafields.Add(metafield).Result;
|
||||
|
||||
// Console.WriteLine(product.Id);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"{ex.Message}");
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// i += _threadCount;
|
||||
// products = _shopifyService.GetManyProducts(250, i).Result;
|
||||
|
||||
// Console.WriteLine(i);
|
||||
// }
|
||||
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"{ex.Message}");
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// private MenuNode[] GetMenuNodes(int menuId, int numberOfLevels, int? parentMenuNodeId = null)
|
||||
// {
|
||||
// MenuNodesLookup request = new MenuNodesLookup
|
||||
// {
|
||||
// MenuId = menuId,
|
||||
// NumberOfLevels = numberOfLevels,
|
||||
// ParentMenuNodeId = parentMenuNodeId
|
||||
// };
|
||||
|
||||
// MenuNodesLookupResponse response = _nexpartService.SendRequest<MenuNodesLookup, MenuNodesLookupResponse>(request).Result;
|
||||
|
||||
// return response.ResponseBody.MenuNode;
|
||||
// }
|
||||
|
||||
// //private bool IsFitmentLineCode(string lineCode)
|
||||
// //{
|
||||
// // string sql = $"select WhiCode from DcfMapping where PartSourceCode='{importData.LineCode}'";
|
||||
|
||||
// // using (DataTable dataTable = new DataTable())
|
||||
// // {
|
||||
// // using (SqlConnection connection = new SqlConnection(_connectionString))
|
||||
// // {
|
||||
// // connection.Open();
|
||||
|
||||
// // using (SqlCommand command = new SqlCommand(sql, connection))
|
||||
// // {
|
||||
|
||||
// // SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
|
||||
// // dataAdapter.Fill(dataTable);
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // if (dataTable.Rows.Count == 0)
|
||||
// // {
|
||||
// // return false;
|
||||
// // }
|
||||
|
||||
// // lineCode = dataTable.Rows[0]["WhiCode"].ToString();
|
||||
|
||||
|
||||
// // }
|
||||
// //}
|
||||
// }
|
||||
//}
|
||||
184
PartSource.Automation/Jobs/UpdateFitment.cs
Normal file
184
PartSource.Automation/Jobs/UpdateFitment.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
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.Data.Shopify;
|
||||
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;
|
||||
|
||||
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<AutomationJobResult> Run()
|
||||
{
|
||||
IEnumerable<Product> products = await _shopifyClient.Products.Get();
|
||||
|
||||
while (products != null && products.Any())
|
||||
{
|
||||
foreach (Product product in products)
|
||||
{
|
||||
try
|
||||
{
|
||||
await DeleteFitmentMetafields(product.Id);
|
||||
|
||||
ImportData importData = _partSourceContext.ImportData.FirstOrDefault(i => i.VariantSku == product.Variants[0].Sku);
|
||||
IList<VehicleData> vehicles = _vehicleService.GetVehiclesForPart(importData?.PartNumber, importData?.LineCode);
|
||||
|
||||
if (vehicles.Count > 0)
|
||||
{
|
||||
bool isFitment = false;
|
||||
|
||||
IList<int> 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<string> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
catch
|
||||
{
|
||||
Console.WriteLine(product.Id);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console.Write('.');
|
||||
|
||||
products = await _shopifyClient.Products.GetNext();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
products = await _shopifyClient.Products.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
IsSuccess = true
|
||||
};
|
||||
}
|
||||
|
||||
private async Task DeleteFitmentMetafields(long shopifyId)
|
||||
{
|
||||
IDictionary<string, object> parameters = new Dictionary<string, object>
|
||||
{
|
||||
{ "metafield[owner_id]", shopifyId},
|
||||
{ "metafield[owner_resource]", "product" },
|
||||
{ "namespace", "fitment" },
|
||||
};
|
||||
|
||||
IEnumerable<Metafield> metafields = await _shopifyClient.Metafields.Get(parameters);
|
||||
|
||||
foreach (Metafield metafield in metafields)
|
||||
{
|
||||
await _shopifyClient.Metafields.Delete(metafield);
|
||||
}
|
||||
}
|
||||
|
||||
public IList<VehicleData> 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<VehicleData> vehicles = _partSourceContext.VehicleData.FromSql(sql).ToList();
|
||||
#pragma warning restore EF1000 // Possible SQL injection vulnerability.
|
||||
|
||||
return vehicles;
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
105
PartSource.Automation/Jobs/UpdatePricing.cs
Normal file
105
PartSource.Automation/Jobs/UpdatePricing.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using PartSource.Automation.Jobs.Interfaces;
|
||||
using PartSource.Automation.Models;
|
||||
using PartSource.Data;
|
||||
using PartSource.Data.Models;
|
||||
using PartSource.Data.Shopify;
|
||||
using PartSource.Services.Integrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PartSource.Automation.Jobs
|
||||
{
|
||||
public class UpdatePricing : IAutomationJob
|
||||
{
|
||||
private readonly PartSourceContext _partSourceContext;
|
||||
private readonly ShopifyClient _shopifyClient;
|
||||
|
||||
public UpdatePricing(PartSourceContext partSourceContext, ShopifyClient shopifyClient)
|
||||
{
|
||||
_partSourceContext = partSourceContext;
|
||||
_shopifyClient = shopifyClient;
|
||||
|
||||
}
|
||||
|
||||
public async Task<AutomationJobResult> Run()
|
||||
{
|
||||
IEnumerable<Product> products = null;
|
||||
int updateCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
products = await _shopifyClient.Products.Get();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO: Logging
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
Message = "Failed to get products from Shopify",
|
||||
IsSuccess = false
|
||||
};
|
||||
}
|
||||
|
||||
while (products != null && products.Any())
|
||||
{
|
||||
foreach (Product product in products)
|
||||
{
|
||||
if (product.Variants.Length > 0)
|
||||
{
|
||||
ProductVariant variant = product.Variants[0];
|
||||
PartPrice partPrice = _partSourceContext.PartPrices.Where(p => p.SKU == variant.Sku).FirstOrDefault();
|
||||
|
||||
if (partPrice == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (product.Variants[0].Price != partPrice.Your_Price.Value || product.Variants[0].CompareAtPrice != partPrice.Compare_Price.Value)
|
||||
{
|
||||
product.Variants[0].Price = partPrice.Your_Price.Value;
|
||||
product.Variants[0].CompareAtPrice = partPrice.Compare_Price.Value;
|
||||
|
||||
try
|
||||
{
|
||||
await _shopifyClient.Products.Update(product);
|
||||
|
||||
updateCount++;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO: Logged failed pricing update here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
products = await _shopifyClient.Products.GetNext();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO: Logging
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
Message = $"Failed to get the next set of products from Shopify. {updateCount} products were able to be updated.",
|
||||
IsSuccess = false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return new AutomationJobResult
|
||||
{
|
||||
Message = $"The nightly pricing update has completed. {updateCount} products were updated.",
|
||||
IsSuccess = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user