Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dynamicweb.DataIntegration" Version="10.9.4" />
<PackageReference Include="Dynamicweb.Ecommerce" Version="10.8.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Reference Include="Dynamicweb.DataIntegration">
<HintPath>..\..\..\Dynamicweb10\src\Features\DataIntegration\Dynamicweb.DataIntegration\bin\Debug\net8.0\Dynamicweb.DataIntegration.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
21 changes: 12 additions & 9 deletions src/OrderProvider.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Dynamicweb.Core;
using Dynamicweb.Data;
using Dynamicweb.DataIntegration.Integration;

Check failure on line 3 in src/OrderProvider.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'Integration' does not exist in the namespace 'Dynamicweb.DataIntegration' (are you missing an assembly reference?)
using Dynamicweb.DataIntegration.Integration.Interfaces;

Check failure on line 4 in src/OrderProvider.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'Integration' does not exist in the namespace 'Dynamicweb.DataIntegration' (are you missing an assembly reference?)
using Dynamicweb.DataIntegration.ProviderHelpers;

Check failure on line 5 in src/OrderProvider.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'ProviderHelpers' does not exist in the namespace 'Dynamicweb.DataIntegration' (are you missing an assembly reference?)
using Dynamicweb.Ecommerce.Orders;
using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Extensibility.Editors;
using Dynamicweb.Logging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
Expand All @@ -19,7 +20,7 @@
namespace Dynamicweb.DataIntegration.Providers.OrderProvider;

[AddInName("Dynamicweb.DataIntegration.Providers.Provider"), AddInLabel("Order Provider"), AddInDescription("Order provider"), AddInIgnore(false)]
public class OrderProvider : BaseSqlProvider, IParameterOptions, ISource, IDestination

Check failure on line 23 in src/OrderProvider.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'BaseSqlProvider' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 23 in src/OrderProvider.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'ISource' could not be found (are you missing a using directive or an assembly reference?)
{
private const string OrderCustomerAccessUserExternalId = "OrderCustomerAccessUserExternalId";
private const string OrderLineCalculatedDiscountPercentage = "OrderLineCalculatedDiscountPercentage";
Expand Down Expand Up @@ -104,14 +105,16 @@
var ordersTable = result.GetTables().FirstOrDefault(obj => string.Equals(obj.Name, "EcomOrders", StringComparison.OrdinalIgnoreCase));
if (orderLinesTable != null && ordersTable != null)
{
foreach (var column in ordersTable.Columns)
{
if (!column.Name.Equals(OrderCustomerAccessUserExternalId, StringComparison.OrdinalIgnoreCase))
{
orderLinesTable.AddColumn(new SqlColumn(column.Name, typeof(string), SqlDbType.NVarChar, orderLinesTable, -1, false, false, true));
}
}
var orderTableColumns = new ColumnCollection();
orderTableColumns.AddRange(ordersTable.Columns);

var orderLineTableColumns = new ColumnCollection();
orderLineTableColumns.AddRange(orderLinesTable.Columns);

ordersTable.AddColumn(new TableColumn(orderLinesTable.Name, orderLinesTable.Name, orderLinesTable, typeof(Collection<object>), orderLineTableColumns));

orderLinesTable.AddColumn(new SqlColumn(OrderLineCalculatedDiscountPercentage, typeof(double), SqlDbType.NVarChar, orderLinesTable, -1, false, false, true));
orderLinesTable.AddColumn(new TableColumn(ordersTable.Name, ordersTable.Name, orderLinesTable, typeof(object), orderTableColumns));
}

return result;
Expand Down Expand Up @@ -313,9 +316,9 @@
public override ISourceReader GetReader(Mapping mapping)
{
return new OrderSourceReader(mapping, Connection, ExportNotExportedOrders, ExportOnlyOrdersWithoutExtID, DoNotExportCarts);
}
}

public override void OrderTablesInJob(Job job, bool isSource) => OrderTablesByRelations(job, isSource);
public override void OrderTablesInJob(Job job, bool isSource) => OrderTablesByRelations(job, isSource);

internal static List<Mapping> GetMappingsByName(MappingCollection collection, string name, bool isSourceLookup)
{
Expand Down
106 changes: 104 additions & 2 deletions src/OrderSourceReader.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
using Dynamicweb.DataIntegration.Integration;

Check failure on line 1 in src/OrderSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'Integration' does not exist in the namespace 'Dynamicweb.DataIntegration' (are you missing an assembly reference?)
using Dynamicweb.Ecommerce.Orders;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;

namespace Dynamicweb.DataIntegration.Providers.OrderProvider
{
internal class OrderSourceReader : BaseSqlReader

Check failure on line 11 in src/OrderSourceReader.cs

View workflow job for this annotation

GitHub Actions / call-workflow / Build

The type or namespace name 'BaseSqlReader' could not be found (are you missing a using directive or an assembly reference?)
{
private static MappingConditionalCollection _ordersConditions = null;
private static List<string> _ordersToExport = null;
private ColumnMappingCollection _columnMappings = null;
private bool _skipReading;

public OrderSourceReader(Mapping mapping, SqlConnection connection, bool exportNotExportedOrders, bool exportOnlyOrdersWithoutExtID, bool doNotExportCarts) : base(mapping, connection)
{
Expand Down Expand Up @@ -162,7 +164,7 @@
result = result + " inner join EcomOrders on EcomOrderLines.OrderLineOrderID = EcomOrders.OrderID";
break;
case "EcomOrders":
result = "[dbo].[EcomOrders] left join dbo.AccessUser on OrderCustomerAccessUserID = AccessUserID";
result = "[dbo].[EcomOrders] left join dbo.AccessUser on OrderCustomerAccessUserID = AccessUserID inner join EcomOrderLines on EcomOrderLines.OrderLineOrderID = EcomOrders.OrderID";
break;
default:
break;
Expand All @@ -172,7 +174,9 @@

public override Dictionary<string, object> GetNext()
{
Dictionary<string, object> row = _columnMappings.Where(columnMapping => columnMapping.SourceColumn != null).GroupBy(cm => cm.SourceColumn.Name, (key, group) => group.First()).ToDictionary(columnMapping => columnMapping.SourceColumn.Name, columnMapping => _reader[columnMapping.SourceColumn.Name]);
_skipReading = false;
var columnMappings = _columnMappings.Where(columnMapping => columnMapping.SourceColumn != null);
Dictionary<string, object> row = columnMappings.Where(cm => string.IsNullOrEmpty(cm.SourceColumn.Group)).GroupBy(cm => cm.SourceColumn.Name, (key, group) => group.First()).ToDictionary(columnMapping => columnMapping.SourceColumn.Name, columnMapping => _reader[columnMapping.SourceColumn.Name]);
if (mapping.SourceTable.Name == "EcomOrders")
{
string orderId = Core.Converter.ToString(_reader["OrderId"]);
Expand All @@ -187,10 +191,60 @@
row.Add("OrderId", orderId);
}
}
var nestedColumnMappings = columnMappings.Where(cm => !string.IsNullOrEmpty(cm.SourceColumn.Group));
if (nestedColumnMappings.Any())
{
var result = new Dictionary<string, List<Dictionary<string, object>>>();
var nestedListValueCollection = new List<Dictionary<string, object>>();
var nestedGroups = columnMappings.Where(cm => !string.IsNullOrEmpty(cm.SourceColumn.Group)).Select(cm => cm.SourceColumn.Group).ToList().Distinct();
foreach (var nestedGroup in nestedGroups)
{
var nestedValueCollection = nestedColumnMappings.Where(cm => cm.SourceColumn.Group.Equals(nestedGroup)).ToDictionary(columnMapping => columnMapping.SourceColumn.Name, columnMapping => _reader[columnMapping.SourceColumn.Name]);
var nestedValuesList = new List<Dictionary<string, object>> { nestedValueCollection };
result.Add(nestedGroup, nestedValuesList);
}

while (_reader.Read())
{
Dictionary<string, object> rootRow = columnMappings.Where(cm => string.IsNullOrEmpty(cm.SourceColumn.Group)).GroupBy(cm => cm.SourceColumn.Name, (key, group) => group.First()).ToDictionary(columnMapping => columnMapping.SourceColumn.Name, columnMapping => _reader[columnMapping.SourceColumn.Name]);
if(!AreDictionariesEqual(row,rootRow))
{
_skipReading = true;
break;
}

foreach (var nestedGroup in nestedGroups)
{
if (result.TryGetValue(nestedGroup, out var nestedList))
{
nestedList.Add(nestedColumnMappings.Where(cm => cm.SourceColumn.Group.Equals(nestedGroup)).ToDictionary(columnMapping => columnMapping.SourceColumn.Name, columnMapping => _reader[columnMapping.SourceColumn.Name]));
}
}
}

foreach (var item in result)
{
row.Add(item.Key, item.Value);
}
}
}

return row;
}

public override bool IsDone()
{
if (_skipReading)
return false;

if (_reader.Read())
return false;

_reader.Close();
return true;
}


public static void UpdateExportedOrdersInDb(string orderStateIDAfterExport, SqlConnection connection)
{
if (_ordersToExport != null && _ordersToExport.Count > 0)
Expand Down Expand Up @@ -256,6 +310,54 @@
os.RemoveOrderCache(id);
}
}

private static bool AreDictionariesEqual(Dictionary<string, object> dict1, Dictionary<string, object> dict2)
{
if (dict1 == null || dict2 == null)
return dict1 == dict2;

if (dict1.Count != dict2.Count)
return false;

foreach (var key in dict1.Keys)
{
if (!dict2.ContainsKey(key))
return false;

if (!AreValuesEqual(dict1[key], dict2[key]))
return false;
}

return true;
}

private static bool AreValuesEqual(object value1, object value2)
{
if (value1 == null || value2 == null)
return value1 == value2;

if (value1 is Dictionary<string, object> dict1 && value2 is Dictionary<string, object> dict2)
return AreDictionariesEqual(dict1, dict2);

if (value1 is IList list1 && value2 is IList list2)
return AreListsEqual(list1, list2);

return value1.Equals(value2);
}

private static bool AreListsEqual(IList list1, IList list2)
{
if (list1.Count != list2.Count)
return false;

for (int i = 0; i < list1.Count; i++)
{
if (!AreValuesEqual(list1[i], list2[i]))
return false;
}

return true;
}
}
}

Loading