Skip to content

Commit

Permalink
Merge pull request #12 from dynamicweb/frn/15477-cleanup-dependencies
Browse files Browse the repository at this point in the history
Cleanup and moving funcitionality to bases
  • Loading branch information
frederik5480 authored Oct 17, 2023
2 parents b86ee49 + 1ec8d1c commit a263c48
Show file tree
Hide file tree
Showing 6 changed files with 4,389 additions and 4,094 deletions.
279 changes: 279 additions & 0 deletions src/AssortmentHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
using Dynamicweb.Core;
using Dynamicweb.Data;
using Dynamicweb.DataIntegration.Integration;
using Dynamicweb.DataIntegration.ProviderHelpers;
using Dynamicweb.Ecommerce.Assortments;
using Dynamicweb.Extensibility.Notifications;
using Dynamicweb.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace Dynamicweb.DataIntegration.Providers.EcomProvider;

public class AssortmentHandler
{
private Dictionary<string, List<AssortmentInfo>> assortmentsToRebuild = new Dictionary<string, List<AssortmentInfo>>();
private readonly string assortmentsProductsTempTableName = "AssortmentsProductsTempTable";
private readonly ILogger logger = null;
private SqlCommand sqlCommand = null;
private readonly string CurrentContextLanguageId = Ecommerce.Common.Context.LanguageID;

public SqlCommand SqlCommand
{
get
{
return sqlCommand;
}
set
{
sqlCommand = value;
}
}

public AssortmentHandler(SqlCommand sqlCommand, ILogger logger)
{
this.sqlCommand = sqlCommand;
this.logger = logger;
}

#region Assortments rebuild
public void ProcessAssortments(DataRow dataRow, Mapping mapping)
{
if (dataRow != null && mapping.DestinationTable != null)
{
string assortmentID = null;
string assortmentLanguageId = CurrentContextLanguageId;
string relationID = null;
AssortmentRelationType relationType = AssortmentRelationType.Product;

switch (mapping.DestinationTable.Name)
{
case "EcomAssortments":
if (dataRow.Table.Columns.Contains("AssortmentRebuildRequired") && dataRow["AssortmentRebuildRequired"] != DBNull.Value && Converter.ToBoolean(dataRow["AssortmentRebuildRequired"]) &&
dataRow.Table.Columns.Contains("AssortmentID") && dataRow["AssortmentID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentID"] as string))
{
assortmentID = (string)dataRow["AssortmentID"];
if (dataRow.Table.Columns.Contains("AssortmentLanguageID") && dataRow["AssortmentLanguageID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentLanguageID"] as string))
{
assortmentLanguageId = (string)dataRow["AssortmentLanguageID"];
}
}
break;
case "EcomAssortmentGroupRelations":
if (dataRow.Table.Columns.Contains("AssortmentGroupRelationAssortmentID") && dataRow["AssortmentGroupRelationAssortmentID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentGroupRelationAssortmentID"] as string) &&
dataRow.Table.Columns.Contains("AssortmentGroupRelationGroupID") && dataRow["AssortmentGroupRelationGroupID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentGroupRelationGroupID"] as string))
{
assortmentID = (string)dataRow["AssortmentGroupRelationAssortmentID"];
relationID = (string)dataRow["AssortmentGroupRelationGroupID"];
relationType = AssortmentRelationType.Group;
}
break;
case "EcomAssortmentProductRelations":
if (dataRow.Table.Columns.Contains("AssortmentProductRelationAssortmentID") && dataRow["AssortmentProductRelationAssortmentID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentProductRelationAssortmentID"] as string) &&
dataRow.Table.Columns.Contains("AssortmentProductRelationProductID") && dataRow["AssortmentProductRelationProductID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentProductRelationProductID"] as string))
{
assortmentID = (string)dataRow["AssortmentProductRelationAssortmentID"];
relationID = (string)dataRow["AssortmentProductRelationProductID"];
relationType = AssortmentRelationType.Product;
}
break;
case "EcomAssortmentShopRelations":
if (dataRow.Table.Columns.Contains("AssortmentShopRelationAssortmentID") && dataRow["AssortmentShopRelationAssortmentID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentShopRelationAssortmentID"] as string) &&
dataRow.Table.Columns.Contains("AssortmentShopRelationShopID") && dataRow["AssortmentShopRelationShopID"] != DBNull.Value && !string.IsNullOrEmpty(dataRow["AssortmentShopRelationShopID"] as string))
{
assortmentID = (string)dataRow["AssortmentShopRelationAssortmentID"];
relationID = (string)dataRow["AssortmentShopRelationShopID"];
relationType = AssortmentRelationType.Shop;
}
break;
}
if (!string.IsNullOrEmpty(assortmentID))
{
AssortmentInfo info = new AssortmentInfo();
info.AssortmentID = assortmentID;
info.RelationID = relationID;
info.RelationType = relationType;
if (string.IsNullOrEmpty(relationID) //this happens when AssortmentRebuildRequired = true
|| IsAssortmentToRebuild(info))
{
if (!assortmentsToRebuild.Keys.Contains(assortmentID))
{
assortmentsToRebuild.Add(assortmentID, new List<AssortmentInfo>());
}
if (!string.IsNullOrEmpty(relationID))
{
assortmentsToRebuild[assortmentID].Add(info);
}
}
}
}
}

public void RebuildAssortments()
{
var assortmentsForBuild = new List<Assortment>();
var failedAssortments = new List<Assortment>();

if (assortmentsToRebuild.Count > 0)
{
CreateAssortmentProductsTempTable();
InsertAssortmentProductsToTempTable(assortmentsToRebuild);
UpdateAssortmentsProducts(false);
Assortment assortment = null;
string msg = "";

foreach (string assortmentId in assortmentsToRebuild.Keys)
{
try
{
assortment = Ecommerce.Services.Assortments.GetAssortmentById(assortmentId);
if (assortment is object)
{
assortmentsForBuild.Add(assortment);
Ecommerce.Services.Assortments.BuildAssortment(assortment);
}
}
catch (Exception ex)
{
msg += string.Format("Error rebulding assortments: {0}. ", ex.Message);
if (assortment != null)
{
failedAssortments.Add(assortment);
msg += string.Format("AssortmentID: {0}. ", assortment.ID);
}
}
}

UpdateAssortmentsProducts(true);
DeleteAssortmentProductsTempTable();

if (!string.IsNullOrEmpty(msg))
{
logger.Log(msg);
}
}
NotificationManager.Notify(Dynamicweb.Ecommerce.Notifications.Ecommerce.Assortment.AssortmentsBuildFinished,
new Dynamicweb.Ecommerce.Notifications.Ecommerce.Assortment.AssortmentsBuildFinishedArgs(assortmentsForBuild, failedAssortments));
}

private bool IsAssortmentToRebuild(AssortmentInfo info)
{
bool rebuild = false;
if (info is object && !string.IsNullOrEmpty(info.RelationID))
{
Assortment assortment = Ecommerce.Services.Assortments.GetAssortmentById(info.AssortmentID);
if (assortment is object)
{
if (info.RelationType == AssortmentRelationType.Product)
{
rebuild = !assortment.ProductRelations.Values.Any(relation =>
string.Compare(relation.ProductID, info.RelationID, true) == 0);
}
else if (info.RelationType == AssortmentRelationType.Group)
{
rebuild = !assortment.GroupRelations.Keys.Any(groupID => string.Compare(groupID, info.RelationID, true) == 0);
}
else if (info.RelationType == AssortmentRelationType.Shop)
{
rebuild = !assortment.ShopRelations.Keys.Any(shopID => string.Compare(shopID, info.RelationID, true) == 0);
}
}
}
return rebuild;
}

private void InsertAssortmentProductsToTempTable(Dictionary<string, List<AssortmentInfo>> assortments)
{
if (assortments != null && assortments.Count > 0)
{
string sql = string.Format(@"insert into {0}(ProductAutoID) select ProductAutoID from EcomProducts
where ProductActive = 1 and ( ProductID in ( ", assortmentsProductsTempTableName);

string groupIDs = string.Join("','", assortments.SelectMany(v => v.Value).Where(x => x.RelationType == AssortmentRelationType.Group && !string.IsNullOrEmpty(x.RelationID)).Select(i => i.RelationID).Distinct());
string shopIDs = string.Join("','", assortments.SelectMany(v => v.Value).Where(x => x.RelationType == AssortmentRelationType.Shop && !string.IsNullOrEmpty(x.RelationID)).Select(i => i.RelationID).Distinct());
if (!string.IsNullOrEmpty(groupIDs) || !string.IsNullOrEmpty(shopIDs))
{
StringBuilder sb = new StringBuilder();
sb.Append(sql);
sb.Append("select GroupProductRelationProductID from EcomGroupProductRelation ");
sb.Append("where ");
if (!string.IsNullOrEmpty(shopIDs))
{
sb.AppendFormat("GroupProductRelationGroupID in( select ShopGroupGroupID from EcomShopGroupRelation where ShopGroupShopID in ( '{0}' )) or ",
shopIDs);
}
if (!string.IsNullOrEmpty(groupIDs))
{
sb.AppendFormat("GroupProductRelationGroupID in ( '{0}' )", groupIDs);
}
else
{
sb.Remove(sb.Length - 4, 3); //remove or
}
sb.Append(") )");
ExecuteInsertAssortmentProductsToTempTable(sb.ToString());
}

List<string> productIDs = assortments.SelectMany(v => v.Value).Where(x => x.RelationType == AssortmentRelationType.Product && !string.IsNullOrEmpty(x.RelationID)).Select(i => i.RelationID).Distinct().ToList();
if (productIDs.Count > 0)
{
int maxProductIDsInQuery = 3000;
if (productIDs.Count > maxProductIDsInQuery)
{
int chunks = productIDs.Count / maxProductIDsInQuery;
if (productIDs.Count % maxProductIDsInQuery != 0)
{
chunks++;
}
for (int i = 0; i < chunks; i++)
{
string pds = string.Join("','", productIDs.Skip(i * maxProductIDsInQuery).Take(maxProductIDsInQuery));
ExecuteInsertAssortmentProductsToTempTable(string.Format("{0} '{1}' ) )", sql, string.Join("','", productIDs)));
}
}
else
{
ExecuteInsertAssortmentProductsToTempTable(string.Format("{0} '{1}' ) )", sql, string.Join("','", productIDs)));
}
}
}
}

private void ExecuteInsertAssortmentProductsToTempTable(string sql)
{
sqlCommand.CommandText = sql;
try
{
sqlCommand.ExecuteScalar();
}
catch (Exception ex)
{
throw new Exception(string.Format("Error insert assortments products to temp table: {0}. Sql: {1}.", ex.Message, sql));
}
}

private void CreateAssortmentProductsTempTable()
{
List<SqlColumn> columns = new List<SqlColumn>();
columns.Add(new SqlColumn("ProductAutoID", "bigint", null, 0, true, true));
SQLTable.CreateTempTable(sqlCommand, null, assortmentsProductsTempTableName, null, columns, logger);
}

private void DeleteAssortmentProductsTempTable()
{
sqlCommand.CommandText = "if exists (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'" + assortmentsProductsTempTableName + "') AND type in (N'U')) drop table " + assortmentsProductsTempTableName;
sqlCommand.ExecuteScalar();
}

private void UpdateAssortmentsProducts(bool setActive)
{
sqlCommand.CommandText = string.Format("update EcomProducts set ProductActive = {0} where ProductAutoID in (select distinct(ProductAutoID) from {1})",
Database.SqlBool(setActive), assortmentsProductsTempTableName);
sqlCommand.ExecuteScalar();
}
#endregion Assortments rebuild
}
10 changes: 10 additions & 0 deletions src/AssortmentInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Dynamicweb.Ecommerce.Assortments;

namespace Dynamicweb.DataIntegration.Providers.EcomProvider;

public class AssortmentInfo
{
public string AssortmentID;
public AssortmentRelationType RelationType;
public string RelationID;
}
14 changes: 5 additions & 9 deletions src/Dynamicweb.DataIntegration.Providers.EcomProvider.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>10.0.5</Version>
<Version>10.0.6</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<Description>Ecommerce Provider</Description>
</PropertyGroup>
Expand All @@ -10,7 +10,7 @@
<Product>Dynamicweb CMS</Product>
<Company>Dynamicweb Software A/S</Company>
<Authors>Dynamicweb Software A/S</Authors>
<Copyright>Copyright © 2020 Dynamicweb Software A/S</Copyright>
<Copyright>Copyright © 2023 Dynamicweb Software A/S</Copyright>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
Expand All @@ -22,12 +22,8 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dynamicweb.Core" Version="10.0.0" />
<PackageReference Include="Dynamicweb.DataIntegration" Version="10.0.0" />
<PackageReference Include="Dynamicweb.DataIntegration.Providers.DynamicwebProvider" Version="10.0.5" />
<PackageReference Include="Dynamicweb.DataIntegration.Providers.XmlProvider" Version="10.0.0" />
<PackageReference Include="Dynamicweb.DataIntegration.Providers.SqlProvider" Version="10.0.0" />
<PackageReference Include="Dynamicweb.Ecommerce" Version="10.0.0" />
<PackageReference Include="Dynamicweb.DataIntegration" Version="10.0.14" />
<PackageReference Include="Dynamicweb.Ecommerce" Version="10.0.9" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
</Project>
</Project>
Loading

0 comments on commit a263c48

Please sign in to comment.