Posted on 09/06/2021 15:45:07
Hi Martin,
While waiting for a solution on the platform, below is a starting point for a table script. I didn't test it but I reused some proven table script elements I already had so it should be pretty close.
There are some considerations on how to map it.
- In your mapping, have ProductNumber on the left map to PriceProductId on the right.
- In your mapping, map PriceProductVariantId and PriceProductVariantId on the right to any dummy field on the left. You can create 2 empty fields in your XML just for that. You can't use a constant static field though. It needs to exist in the mapping.
- Select the table script and test!
using System;
using System.Linq;
using System.Collections.Generic;
using Dynamicweb.DataIntegration.Integration;
namespace Dna.TableScripts
{
public class EcomPricesSetProductIdByProductNumber : TableScript
{
private const string FilteredTableName = "EcomPrices";
public override string ScriptingName => "PriceMatrix: Set ProductId/VariantId/LanguageId from ProductNumber. Must also have empty VariantId and LanguageId fields mapped (any name is ok but it cannot be used for any other mapping and it cannot be a constant/static field).";
public override void ProcessInputRow(Mapping mapping, Dictionary<string, object> row)
{
if (mapping.DestinationTable == null || mapping.DestinationTable.Name != FilteredTableName)
{
return;
}
var productNumber = row[GetSourceColumnNameFromDestinationName(mapping, "PriceProductId")].ToString();
//don't map if the value is empty
if (string.IsNullOrEmpty(productNumber))
{
return;
}
//get Product by ProductNumber, giving preference to any with a variant ID
var sql = $"SELECT TOP 1 * FROM EcomProducts WHERE ProductNumber = '{productNumber.Replace("'", "''")}' ORDER BY ProductVariantID DESC, ProductLanguageID DESC";
var product = new Dynamicweb.Ecommerce.Products.ProductService().GetProductsBySql(sql).FirstOrDefault();
if (product == null)
{
//product wasn't found so leave the row as it is
return;
}
row[GetSourceColumnNameFromDestinationName(mapping, "PriceProductId")] = product.Id; //this will overwrite the one in the mapping
row[GetSourceColumnNameFromDestinationName(mapping, "PriceProductVariantId")] = product.VariantId;
row[GetSourceColumnNameFromDestinationName(mapping, "PriceProductLanguageId")] = product.LanguageId;
}
private string GetSourceColumnNameFromDestinationName(Mapping mapping, string destinationColumnName, bool destinationColumnExistenceIsOptional = false)
{
var activeColumn = mapping.GetColumnMappings().FirstOrDefault(c => destinationColumnName.Equals(c.DestinationColumn.Name, StringComparison.CurrentCultureIgnoreCase))?.SourceColumn?.Name;
if (destinationColumnExistenceIsOptional)
{
return activeColumn ?? null;
}
else
{
return activeColumn ?? throw new InvalidOperationException($"Table Script: unexpected error has occurred since the destination table doesn't have a column called {destinationColumnName}");
}
}
}
}