diff --git a/src/Dynamicweb.DataIntegration.Providers.ExcelProvider.csproj b/src/Dynamicweb.DataIntegration.Providers.ExcelProvider.csproj index 16d25a6..7b40f16 100644 --- a/src/Dynamicweb.DataIntegration.Providers.ExcelProvider.csproj +++ b/src/Dynamicweb.DataIntegration.Providers.ExcelProvider.csproj @@ -23,8 +23,8 @@ snupkg - - + + diff --git a/src/ExcelDestinationWriter.cs b/src/ExcelDestinationWriter.cs index 2c68804..216f149 100644 --- a/src/ExcelDestinationWriter.cs +++ b/src/ExcelDestinationWriter.cs @@ -1,249 +1,248 @@ -using Dynamicweb.Core; -using Dynamicweb.DataIntegration.Integration; -using Dynamicweb.DataIntegration.Integration.Interfaces; -using Dynamicweb.DataIntegration.ProviderHelpers; -using Dynamicweb.Logging; -using OfficeOpenXml; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Globalization; using System.IO; using System.Linq; +using Dynamicweb.Core; +using Dynamicweb.DataIntegration.Integration; +using Dynamicweb.DataIntegration.Integration.Interfaces; +using Dynamicweb.DataIntegration.ProviderHelpers; +using Dynamicweb.Logging; +using OfficeOpenXml; + +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider +public class ExcelDestinationWriter : IDestinationWriter, IDisposable { - public class ExcelDestinationWriter : IDestinationWriter, IDisposable + private readonly ILogger _logger; + private readonly CultureInfo _cultureInfo; + + public ExcelDestinationWriter() { - private readonly ILogger _logger; - private readonly CultureInfo _cultureInfo; + } - public ExcelDestinationWriter() + [Obsolete("Use overload method (string path, string destinationPath, MappingCollection mappings, ILogger logger, CultureInfo cultureInfo) instead.")] + public ExcelDestinationWriter(string path, string destinationPath, MappingCollection mappings, ILogger logger) + { + _path = path; + _mappings = mappings; + if (!Directory.Exists(path)) { + Directory.CreateDirectory(path); } + _destinationPath = destinationPath; + _logger = logger; + _cultureInfo = CultureInfo.CurrentCulture; + } - [Obsolete("Use overload method (string path, string destinationPath, MappingCollection mappings, ILogger logger, CultureInfo cultureInfo) instead.")] - public ExcelDestinationWriter(string path, string destinationPath, MappingCollection mappings, ILogger logger) - { - _path = path; - _mappings = mappings; - if (!Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } - _destinationPath = destinationPath; - _logger = logger; - _cultureInfo = CultureInfo.CurrentCulture; - } + public ExcelDestinationWriter(string path, string destinationPath, MappingCollection mappings, ILogger logger, CultureInfo cultureInfo) + { - public ExcelDestinationWriter(string path, string destinationPath, MappingCollection mappings, ILogger logger, CultureInfo cultureInfo) + _path = path; + _mappings = mappings; + if (!Directory.Exists(path)) { - - _path = path; - _mappings = mappings; - if (!Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } - _destinationPath = destinationPath; - _logger = logger; - _cultureInfo = cultureInfo ?? CultureInfo.CurrentCulture; + Directory.CreateDirectory(path); } + _destinationPath = destinationPath; + _logger = logger; + _cultureInfo = cultureInfo ?? CultureInfo.CurrentCulture; + } - private readonly MappingCollection _mappings; - private readonly string _path; - private DataSet setForExcel; - private DataTable tableForExcel; - private readonly string _destinationPath; - private Mapping _currentMapping; - private ColumnMappingCollection _currentColumnMappings; - public Mapping currentMapping + private readonly MappingCollection _mappings; + private readonly string _path; + private DataSet setForExcel; + private DataTable tableForExcel; + private readonly string _destinationPath; + private Mapping _currentMapping; + private ColumnMappingCollection _currentColumnMappings; + public Mapping currentMapping + { + get => _currentMapping; + set { - get => _currentMapping; - set - { - _currentMapping = value; - _currentColumnMappings = value.GetColumnMappings(); - } + _currentMapping = value; + _currentColumnMappings = value.GetColumnMappings(); } + } - public virtual Mapping Mapping - { - get { return currentMapping; } - } + public virtual Mapping Mapping + { + get { return currentMapping; } + } - public virtual MappingCollection Mappings - { - get { return _mappings; } - } + public virtual MappingCollection Mappings + { + get { return _mappings; } + } - public virtual void Write(Dictionary row) + public virtual void Write(Dictionary row) + { + if (tableForExcel == null) { - if (tableForExcel == null) - { - tableForExcel = GetTableForExcel(); - } + tableForExcel = GetTableForExcel(); + } - DataRow r = tableForExcel.NewRow(); + DataRow r = tableForExcel.NewRow(); - foreach (ColumnMapping columnMapping in _currentColumnMappings.Where(cm => cm.Active)) + foreach (ColumnMapping columnMapping in _currentColumnMappings.Where(cm => cm.Active)) + { + if (columnMapping.HasScriptWithValue) { - if (columnMapping.HasScriptWithValue) + if (columnMapping.DestinationColumn.Type == typeof(DateTime)) { - if (columnMapping.DestinationColumn.Type == typeof(DateTime)) - { - DateTime theDate = DateTime.Parse(columnMapping.GetScriptValue(), CultureInfo.InvariantCulture); - r[columnMapping.DestinationColumn.Name] = theDate.ToString("dd-MM-yyyy HH:mm:ss:fff", _cultureInfo); - } - else if (columnMapping.DestinationColumn.Type == typeof(decimal) || - columnMapping.DestinationColumn.Type == typeof(double) || - columnMapping.DestinationColumn.Type == typeof(float)) - { - r[columnMapping.DestinationColumn.Name] = ValueFormatter.GetFormattedValue(columnMapping.GetScriptValue(), _cultureInfo, columnMapping.ScriptType, columnMapping.ScriptValue); - } - else - { - r[columnMapping.DestinationColumn.Name] = columnMapping.GetScriptValue(); - } + DateTime theDate = DateTime.Parse(columnMapping.GetScriptValue(), CultureInfo.InvariantCulture); + r[columnMapping.DestinationColumn.Name] = theDate.ToString("dd-MM-yyyy HH:mm:ss:fff", _cultureInfo); } - else if (row[columnMapping.SourceColumn.Name] == DBNull.Value) + else if (columnMapping.DestinationColumn.Type == typeof(decimal) || + columnMapping.DestinationColumn.Type == typeof(double) || + columnMapping.DestinationColumn.Type == typeof(float)) { - r[columnMapping.DestinationColumn.Name] = "NULL"; + r[columnMapping.DestinationColumn.Name] = ValueFormatter.GetFormattedValue(columnMapping.GetScriptValue(), _cultureInfo, columnMapping.ScriptType, columnMapping.ScriptValue); } - else if (columnMapping.SourceColumn.Type == typeof(DateTime)) + else { - if (DateTime.TryParse(columnMapping.ConvertInputValueToOutputValue(row[columnMapping.SourceColumn.Name])?.ToString(), out var theDateTime)) - { - r[columnMapping.DestinationColumn.Name] = theDateTime.ToString("dd-MM-yyyy HH:mm:ss:fff", _cultureInfo); - } - else - { - r[columnMapping.DestinationColumn.Name] = DateTime.MinValue.ToString("dd-MM-yyyy HH:mm:ss:fff", CultureInfo.InvariantCulture); - } + r[columnMapping.DestinationColumn.Name] = columnMapping.GetScriptValue(); + } + } + else if (row[columnMapping.SourceColumn.Name] == DBNull.Value) + { + r[columnMapping.DestinationColumn.Name] = "NULL"; + } + else if (columnMapping.SourceColumn.Type == typeof(DateTime)) + { + if (DateTime.TryParse(columnMapping.ConvertInputValueToOutputValue(row[columnMapping.SourceColumn.Name])?.ToString(), out var theDateTime)) + { + r[columnMapping.DestinationColumn.Name] = theDateTime.ToString("dd-MM-yyyy HH:mm:ss:fff", _cultureInfo); } else { - r[columnMapping.DestinationColumn.Name] = string.Format(_cultureInfo, "{0}", columnMapping.ConvertInputValueToOutputValue(row[columnMapping.SourceColumn.Name])); + r[columnMapping.DestinationColumn.Name] = DateTime.MinValue.ToString("dd-MM-yyyy HH:mm:ss:fff", CultureInfo.InvariantCulture); } } - tableForExcel.Rows.Add(r); + else + { + r[columnMapping.DestinationColumn.Name] = string.Format(_cultureInfo, "{0}", columnMapping.ConvertInputValueToOutputValue(row[columnMapping.SourceColumn.Name])); + } } + tableForExcel.Rows.Add(r); + } - private DataTable GetTableForExcel() + private DataTable GetTableForExcel() + { + var table = new DataTable(currentMapping.DestinationTable.Name); + foreach (ColumnMapping c in _currentColumnMappings) { - var table = new DataTable(currentMapping.DestinationTable.Name); - foreach (ColumnMapping c in _currentColumnMappings) + if (c.Active) { - if (c.Active) - { - table.Columns.Add(c.DestinationColumn.Name); - } + table.Columns.Add(c.DestinationColumn.Name); } - return table; } + return table; + } - public void AddTableToSet() + public void AddTableToSet() + { + if (setForExcel == null) { - if (setForExcel == null) - { - setForExcel = new DataSet(); - } - if (tableForExcel == null) - { - tableForExcel = GetTableForExcel(); - } - setForExcel.Tables.Add(tableForExcel); - tableForExcel = null; + setForExcel = new DataSet(); + } + if (tableForExcel == null) + { + tableForExcel = GetTableForExcel(); } + setForExcel.Tables.Add(tableForExcel); + tableForExcel = null; + } - public void GenerateExcel() + public void GenerateExcel() + { + ExcelPackage.LicenseContext = LicenseContext.Commercial; + FileInfo newFileInfo = new FileInfo(_path.CombinePaths(_destinationPath)); + ExcelPackage pck = null; + if (newFileInfo.Exists) { - ExcelPackage.LicenseContext = LicenseContext.Commercial; - FileInfo newFileInfo = new FileInfo(_path.CombinePaths(_destinationPath)); - ExcelPackage pck = null; - if (newFileInfo.Exists) + try { - try - { - pck = new ExcelPackage(newFileInfo); - } - catch (Exception ex) - { - _logger.Log($"Can not write to the existing destination file: {ex.Message}. The file will be overwritten."); - File.Delete(newFileInfo.FullName); - pck = new ExcelPackage(newFileInfo); - } + pck = new ExcelPackage(newFileInfo); } - else + catch (Exception ex) { + _logger.Log($"Can not write to the existing destination file: {ex.Message}. The file will be overwritten."); + File.Delete(newFileInfo.FullName); pck = new ExcelPackage(newFileInfo); } - using (pck) + } + else + { + pck = new ExcelPackage(newFileInfo); + } + using (pck) + { + foreach (DataTable table in setForExcel.Tables) { - foreach (DataTable table in setForExcel.Tables) + List workSheetsToRemove = new List(); + foreach (var worksheet in pck.Workbook.Worksheets) { - List workSheetsToRemove = new List(); - foreach (var worksheet in pck.Workbook.Worksheets) - { - if (worksheet.Name.Equals(table.TableName, StringComparison.OrdinalIgnoreCase)) - { - workSheetsToRemove.Add(worksheet); - } - } - foreach (var worksheet in workSheetsToRemove) + if (worksheet.Name.Equals(table.TableName, StringComparison.OrdinalIgnoreCase)) { - pck.Workbook.Worksheets.Delete(worksheet); - } - ExcelWorksheet ws = pck.Workbook.Worksheets.Add(table.TableName); - ws.Cells["A1"].LoadFromDataTable(table, true); - if (_logger != null) - { - _logger.Log("Added table: " + table.TableName + " Rows: " + table.Rows.Count); + workSheetsToRemove.Add(worksheet); } } - pck.Save(); + foreach (var worksheet in workSheetsToRemove) + { + pck.Workbook.Worksheets.Delete(worksheet); + } + ExcelWorksheet ws = pck.Workbook.Worksheets.Add(table.TableName); + ws.Cells["A1"].LoadFromDataTable(table, true); if (_logger != null) { - _logger.Log("Writing to " + _destinationPath + " is saved and finished"); + _logger.Log("Added table: " + table.TableName + " Rows: " + table.Rows.Count); } } + pck.Save(); + if (_logger != null) + { + _logger.Log("Writing to " + _destinationPath + " is saved and finished"); + } } + } - public virtual void Close() - { - } + public virtual void Close() + { + } - #region IDisposable Implementation + #region IDisposable Implementation - protected bool Disposed; + protected bool Disposed; - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) + { + lock (this) { - lock (this) - { - // Do nothing if the object has already been disposed of. - if (Disposed) - return; + // Do nothing if the object has already been disposed of. + if (Disposed) + return; - if (disposing) - { - // Release diposable objects used by this instance here. - } - - // Release unmanaged resources here. Don't access reference type fields. - - // Remember that the object has been disposed of. - Disposed = true; + if (disposing) + { + // Release diposable objects used by this instance here. } - } - public virtual void Dispose() - { - Dispose(true); - // Unregister object for finalization. - GC.SuppressFinalize(this); + // Release unmanaged resources here. Don't access reference type fields. + + // Remember that the object has been disposed of. + Disposed = true; } + } - #endregion + public virtual void Dispose() + { + Dispose(true); + // Unregister object for finalization. + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/src/ExcelProvider.cs b/src/ExcelProvider.cs index 2c7243c..62eb88f 100644 --- a/src/ExcelProvider.cs +++ b/src/ExcelProvider.cs @@ -1,12 +1,4 @@ -using Dynamicweb.Core; -using Dynamicweb.Core.Helpers; -using Dynamicweb.DataIntegration.Integration; -using Dynamicweb.DataIntegration.Integration.Interfaces; -using Dynamicweb.Extensibility.AddIns; -using Dynamicweb.Extensibility.Editors; -using Dynamicweb.Logging; -using OfficeOpenXml; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Globalization; @@ -14,496 +6,503 @@ using System.Linq; using System.Xml; using System.Xml.Linq; +using Dynamicweb.Core; +using Dynamicweb.Core.Helpers; +using Dynamicweb.DataIntegration.Integration; +using Dynamicweb.DataIntegration.Integration.Interfaces; +using Dynamicweb.Extensibility.AddIns; +using Dynamicweb.Extensibility.Editors; +using Dynamicweb.Logging; +using OfficeOpenXml; + +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider +[AddInName("Dynamicweb.DataIntegration.Providers.Provider"), AddInLabel("Excel Provider"), AddInDescription("Excel Provider"), AddInIgnore(false)] +public class ExcelProvider : BaseProvider, ISource, IDestination, IParameterOptions { - [AddInName("Dynamicweb.DataIntegration.Providers.Provider"), AddInLabel("Excel Provider"), AddInDescription("Excel Provider"), AddInIgnore(false)] - public class ExcelProvider : BaseProvider, ISource, IDestination, IParameterOptions - { - private const string ExcelExtension = ".xlsx"; - private const string ExcelFilesSearchPattern = "*.xls*"; + private const string ExcelExtension = ".xlsx"; + private const string ExcelFilesSearchPattern = "*.xls*"; - [AddInParameter("Source folder"), AddInParameterEditor(typeof(FolderSelectEditor), "folder=/Files/;"), AddInParameterGroup("Source")] - public string SourceFolder { get; set; } + [AddInParameter("Source folder"), AddInParameterEditor(typeof(FolderSelectEditor), "folder=/Files/;"), AddInParameterGroup("Source")] + public string SourceFolder { get; set; } - [AddInParameter("Source file"), AddInParameterEditor(typeof(FileManagerEditor), "folder=/Files/;Tooltip=Selecting a source file will override source folder selection"), AddInParameterGroup("Source")] - public string SourceFile { get; set; } + [AddInParameter("Source file"), AddInParameterEditor(typeof(FileManagerEditor), "folder=/Files/;Tooltip=Selecting a source file will override source folder selection"), AddInParameterGroup("Source")] + public string SourceFile { get; set; } - [AddInParameter("Destination file"), AddInParameterEditor(typeof(TextParameterEditor), $"append={ExcelExtension};required"), AddInParameterGroup("Destination")] - public string DestinationFile + [AddInParameter("Destination file"), AddInParameterEditor(typeof(TextParameterEditor), $"append={ExcelExtension};required"), AddInParameterGroup("Destination")] + public string DestinationFile + { + get { - get - { - return Path.GetFileNameWithoutExtension(_destinationFileName); - } - set - { - _destinationFileName = Path.GetFileNameWithoutExtension(value); - } + return Path.GetFileNameWithoutExtension(_destinationFileName); + } + set + { + _destinationFileName = Path.GetFileNameWithoutExtension(value); } + } - private string _destinationFileName; + private string _destinationFileName; - [AddInParameter("Destination folder"), AddInParameterEditor(typeof(FolderSelectEditor), "folder=/Files/"), AddInParameterGroup("Destination")] - public string DestinationFolder { get; set; } = "/Files"; + [AddInParameter("Destination folder"), AddInParameterEditor(typeof(FolderSelectEditor), "folder=/Files/"), AddInParameterGroup("Destination")] + public string DestinationFolder { get; set; } = "/Files"; - private Schema schema; + private Schema schema; - private ExcelDestinationWriter destinationWriter; + private ExcelDestinationWriter destinationWriter; - public override Schema GetOriginalDestinationSchema() - { - schema ??= GetOriginalSourceSchema(); - return schema; - } + public override Schema GetOriginalDestinationSchema() + { + schema ??= GetOriginalSourceSchema(); + return schema; + } - public override bool SchemaIsEditable => true; + public override bool SchemaIsEditable => true; - private bool IsFolderUsed => string.IsNullOrEmpty(SourceFile); + private bool IsFolderUsed => string.IsNullOrEmpty(SourceFile); - public override Schema GetOriginalSourceSchema() - { - Schema result = new Schema(); + public override Schema GetOriginalSourceSchema() + { + Schema result = new Schema(); - if (!IsFolderUsed) + if (!IsFolderUsed) + { + var sourceFilePath = GetSourceFilePath(SourceFile); + if (File.Exists(sourceFilePath)) { - var sourceFilePath = GetSourceFilePath(SourceFile); - if (File.Exists(sourceFilePath)) + try { - try + if (SourceFile.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || + SourceFile.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || + SourceFile.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) { - if (SourceFile.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || - SourceFile.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || - SourceFile.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) - { - Dictionary excelReaders = new Dictionary + Dictionary excelReaders = new Dictionary { { sourceFilePath, new ExcelReader(sourceFilePath) } }; - GetSchemaForTableFromFile(result, excelReaders); - } - else - { - Logger?.Error("File is not an Excel file"); - } + GetSchemaForTableFromFile(result, excelReaders); } - catch (Exception ex) + else { - Logger?.Error(string.Format("GetOriginalSourceSchema error reading file: {0} message: {1} stack: {2}", sourceFilePath, ex.Message, ex.StackTrace)); + Logger?.Error("File is not an Excel file"); } } - else + catch (Exception ex) { - Logger?.Error($"Source file {sourceFilePath} does not exist"); + Logger?.Error(string.Format("GetOriginalSourceSchema error reading file: {0} message: {1} stack: {2}", sourceFilePath, ex.Message, ex.StackTrace)); } } else { - foreach (var sourceFilePath in GetSourceFolderFiles()) - { - try - { - Dictionary excelReaders = new Dictionary - { - { sourceFilePath, new ExcelReader(sourceFilePath) } - }; - GetSchemaForTableFromFile(result, excelReaders, true); - } - catch (Exception ex) - { - Logger?.Error(string.Format("GetOriginalSourceSchema error reading file: {0} message: {1} stack: {2}", sourceFilePath, ex.Message, ex.StackTrace)); - } - } - } - - return result; - } - - private string workingDirectory = SystemInformation.MapPath("/Files/"); - public override string WorkingDirectory - { - get - { - return workingDirectory; + Logger?.Error($"Source file {sourceFilePath} does not exist"); } - set { workingDirectory = value.Replace("\\", "/"); } } - - private string GetSourceFilePath(string filePath) + else { - string srcFilePath = string.Empty; - - if (!string.IsNullOrEmpty(filePath)) + foreach (var sourceFilePath in GetSourceFolderFiles()) { - if (filePath.StartsWith("..")) + try { - srcFilePath = WorkingDirectory.CombinePaths(filePath.TrimStart(new char[] { '.' })).Replace("\\", "/"); + Dictionary excelReaders = new Dictionary + { + { sourceFilePath, new ExcelReader(sourceFilePath) } + }; + GetSchemaForTableFromFile(result, excelReaders, true); } - else + catch (Exception ex) { - srcFilePath = SystemInformation.MapPath(FilePathHelper.GetRelativePath(filePath, "/Files")); + Logger?.Error(string.Format("GetOriginalSourceSchema error reading file: {0} message: {1} stack: {2}", sourceFilePath, ex.Message, ex.StackTrace)); } } - return srcFilePath; } - private string SourceFolderPath => SystemInformation.MapPath(FilePathHelper.GetRelativePath(SourceFolder, "/Files")); + return result; + } + + private string workingDirectory = SystemInformation.MapPath("/Files/"); + public override string WorkingDirectory + { + get + { + return workingDirectory; + } + set { workingDirectory = value.Replace("\\", "/"); } + } + + private string GetSourceFilePath(string filePath) + { + string srcFilePath = string.Empty; - private IEnumerable GetSourceFolderFiles() + if (!string.IsNullOrEmpty(filePath)) { - var folderPath = SourceFolderPath; - if (Directory.Exists(folderPath)) + if (filePath.StartsWith("..")) { - return Directory.EnumerateFiles(folderPath, ExcelFilesSearchPattern, SearchOption.TopDirectoryOnly); + srcFilePath = WorkingDirectory.CombinePaths(filePath.TrimStart(new char[] { '.' })).Replace("\\", "/"); + } + else + { + srcFilePath = SystemInformation.MapPath(FilePathHelper.GetRelativePath(filePath, "/Files")); } - return Enumerable.Empty(); } + return srcFilePath; + } - public override void UpdateSourceSettings(ISource source) + private string SourceFolderPath => SystemInformation.MapPath(FilePathHelper.GetRelativePath(SourceFolder, "/Files")); + + private IEnumerable GetSourceFolderFiles() + { + var folderPath = SourceFolderPath; + if (Directory.Exists(folderPath)) { - ExcelProvider newProvider = (ExcelProvider)source; - SourceFile = newProvider.SourceFile; - SourceFolder = newProvider.SourceFolder; + return Directory.EnumerateFiles(folderPath, ExcelFilesSearchPattern, SearchOption.TopDirectoryOnly); } + return Enumerable.Empty(); + } - public override string Serialize() - { - XDocument document = new XDocument(new XDeclaration("1.0", "utf-8", string.Empty)); + public override void UpdateSourceSettings(ISource source) + { + ExcelProvider newProvider = (ExcelProvider)source; + SourceFile = newProvider.SourceFile; + SourceFolder = newProvider.SourceFolder; + } - XElement root = new XElement("Parameters"); - document.Add(root); + public override string Serialize() + { + XDocument document = new XDocument(new XDeclaration("1.0", "utf-8", string.Empty)); - root.Add(CreateParameterNode(GetType(), "Source file", SourceFile)); - root.Add(CreateParameterNode(GetType(), "Source folder", SourceFolder)); - root.Add(CreateParameterNode(GetType(), "Destination file", DestinationFile)); - root.Add(CreateParameterNode(GetType(), "Destination folder", DestinationFolder)); + XElement root = new XElement("Parameters"); + document.Add(root); - return document.ToString(); - } + root.Add(CreateParameterNode(GetType(), "Source file", SourceFile)); + root.Add(CreateParameterNode(GetType(), "Source folder", SourceFolder)); + root.Add(CreateParameterNode(GetType(), "Destination file", DestinationFile)); + root.Add(CreateParameterNode(GetType(), "Destination folder", DestinationFolder)); - void ISource.SaveAsXml(XmlTextWriter xmlTextWriter) - { - xmlTextWriter.WriteElementString("SourcePath", SourceFile); - xmlTextWriter.WriteElementString("SourceFolder", SourceFolder); - (this as ISource).GetSchema().SaveAsXml(xmlTextWriter); - } + return document.ToString(); + } - void IDestination.SaveAsXml(XmlTextWriter xmlTextWriter) - { - xmlTextWriter.WriteElementString("DestinationFile", DestinationFile); - xmlTextWriter.WriteElementString("DestinationFolder", DestinationFolder); - (this as IDestination).GetSchema().SaveAsXml(xmlTextWriter); - } + void ISource.SaveAsXml(XmlTextWriter xmlTextWriter) + { + xmlTextWriter.WriteElementString("SourcePath", SourceFile); + xmlTextWriter.WriteElementString("SourceFolder", SourceFolder); + (this as ISource).GetSchema().SaveAsXml(xmlTextWriter); + } + + void IDestination.SaveAsXml(XmlTextWriter xmlTextWriter) + { + xmlTextWriter.WriteElementString("DestinationFile", DestinationFile); + xmlTextWriter.WriteElementString("DestinationFolder", DestinationFolder); + (this as IDestination).GetSchema().SaveAsXml(xmlTextWriter); + } - public new ISourceReader GetReader(Mapping mapping) + public new ISourceReader GetReader(Mapping mapping) + { + string filePath; + if (!IsFolderUsed) { - string filePath; - if (!IsFolderUsed) - { - filePath = SourceFile; + filePath = SourceFile; - if (filePath.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || + if (filePath.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || filePath.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || filePath.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) + { + if (!string.IsNullOrEmpty(WorkingDirectory)) { - if (!string.IsNullOrEmpty(WorkingDirectory)) - { - var sourceFilePath = GetSourceFilePath(filePath); - if (!File.Exists(sourceFilePath)) - throw new Exception($"Source file {SourceFile} does not exist - Working Directory {WorkingDirectory}"); - - return new ExcelSourceReader(sourceFilePath, mapping, this); - } - else - { - if (!File.Exists(filePath)) - throw new Exception($"Source file {filePath} does not exist - Working Directory {WorkingDirectory}"); + var sourceFilePath = GetSourceFilePath(filePath); + if (!File.Exists(sourceFilePath)) + throw new Exception($"Source file {SourceFile} does not exist - Working Directory {WorkingDirectory}"); - return new ExcelSourceReader(filePath, mapping, this); - } + return new ExcelSourceReader(sourceFilePath, mapping, this); } else - throw new Exception("The file is not a Excel file"); + { + if (!File.Exists(filePath)) + throw new Exception($"Source file {filePath} does not exist - Working Directory {WorkingDirectory}"); + + return new ExcelSourceReader(filePath, mapping, this); + } } else - { - string folderPath = SourceFolderPath; - var fileName = mapping.SourceTable.SqlSchema; - filePath = Directory.EnumerateFiles(folderPath, ExcelFilesSearchPattern, SearchOption.TopDirectoryOnly).FirstOrDefault(f => f.EndsWith(fileName, StringComparison.OrdinalIgnoreCase)); - if (!File.Exists(filePath)) - { - throw new Exception($"Source file {fileName} does not exist in the Directory {folderPath}"); - } - return new ExcelSourceReader(filePath, mapping, this); + throw new Exception("The file is not a Excel file"); + } + else + { + string folderPath = SourceFolderPath; + var fileName = mapping.SourceTable.SqlSchema; + filePath = Directory.EnumerateFiles(folderPath, ExcelFilesSearchPattern, SearchOption.TopDirectoryOnly).FirstOrDefault(f => f.EndsWith(fileName, StringComparison.OrdinalIgnoreCase)); + if (!File.Exists(filePath)) + { + throw new Exception($"Source file {fileName} does not exist in the Directory {folderPath}"); } + return new ExcelSourceReader(filePath, mapping, this); } + } - public override void Close() - { + public override void Close() + { - } + } - public override void UpdateDestinationSettings(IDestination destination) - { - ExcelProvider newProvider = (ExcelProvider)destination; - newProvider.DestinationFile = DestinationFile; - newProvider.DestinationFolder = DestinationFolder; - } + public override void UpdateDestinationSettings(IDestination destination) + { + ExcelProvider newProvider = (ExcelProvider)destination; + newProvider.DestinationFile = DestinationFile; + newProvider.DestinationFolder = DestinationFolder; + } - public override bool RunJob(Job job) + public override bool RunJob(Job job) + { + ReplaceMappingConditionalsWithValuesFromRequest(job); + Dictionary sourceRow = null; + try { - ReplaceMappingConditionalsWithValuesFromRequest(job); - Dictionary sourceRow = null; - try - { - CultureInfo ci = GetCultureInfo(job.Culture); + CultureInfo ci = GetCultureInfo(job.Culture); - if (destinationWriter == null) + if (destinationWriter == null) + { + if (!string.IsNullOrEmpty(WorkingDirectory)) { - if (!string.IsNullOrEmpty(WorkingDirectory)) - { - destinationWriter = new ExcelDestinationWriter(workingDirectory.CombinePaths(DestinationFolder), $"{Path.GetFileNameWithoutExtension(DestinationFile)}{ExcelExtension}", job.Mappings, Logger, ci); - } - else - { - destinationWriter = new ExcelDestinationWriter($"{Path.GetFileNameWithoutExtension(SourceFile)}{ExcelExtension}", "", job.Mappings, Logger, ci); - } + destinationWriter = new ExcelDestinationWriter(workingDirectory.CombinePaths(DestinationFolder), $"{Path.GetFileNameWithoutExtension(DestinationFile)}{ExcelExtension}", job.Mappings, Logger, ci); + } + else + { + destinationWriter = new ExcelDestinationWriter($"{Path.GetFileNameWithoutExtension(SourceFile)}{ExcelExtension}", "", job.Mappings, Logger, ci); } - foreach (var mapping in destinationWriter.Mappings) + } + foreach (var mapping in destinationWriter.Mappings) + { + destinationWriter.currentMapping = mapping; + using (ISourceReader sourceReader = mapping.Source.GetReader(mapping)) { - destinationWriter.currentMapping = mapping; - using (ISourceReader sourceReader = mapping.Source.GetReader(mapping)) + while (!sourceReader.IsDone()) { - while (!sourceReader.IsDone()) + sourceRow = sourceReader.GetNext(); + if (ProcessInputRow(sourceRow, mapping)) { - sourceRow = sourceReader.GetNext(); - if (ProcessInputRow(sourceRow, mapping)) - { - destinationWriter.Write(sourceRow); - } + destinationWriter.Write(sourceRow); } - destinationWriter.AddTableToSet(); } + destinationWriter.AddTableToSet(); } - destinationWriter.GenerateExcel(); - sourceRow = null; } - catch (Exception ex) - { - string msg = ex.Message; - string stackTrace = ex.StackTrace; + destinationWriter.GenerateExcel(); + sourceRow = null; + } + catch (Exception ex) + { + string msg = ex.Message; + string stackTrace = ex.StackTrace; - Logger?.Error($"Error: {msg.Replace(System.Environment.NewLine, " ")} Stack: {stackTrace.Replace(System.Environment.NewLine, " ")}", ex); - LogManager.System.GetLogger(LogCategory.Application, "Dataintegration").Error($"{GetType().Name} error: {msg} Stack: {stackTrace}", ex); - if (sourceRow != null) - { - msg += GetFailedSourceRowMessage(sourceRow); - } - Logger.Log("Job failed " + msg); - return false; - } - finally + Logger?.Error($"Error: {msg.Replace(System.Environment.NewLine, " ")} Stack: {stackTrace.Replace(System.Environment.NewLine, " ")}", ex); + LogManager.System.GetLogger(LogCategory.Application, "Dataintegration").Error($"{GetType().Name} error: {msg} Stack: {stackTrace}", ex); + if (sourceRow != null) { - sourceRow = null; + msg += GetFailedSourceRowMessage(sourceRow); } - return true; + Logger.Log("Job failed " + msg); + return false; + } + finally + { + sourceRow = null; } + return true; + } - private CultureInfo GetCultureInfo(string culture) + private CultureInfo GetCultureInfo(string culture) + { + try { - try - { - return string.IsNullOrWhiteSpace(culture) ? CultureInfo.CurrentCulture : CultureInfo.GetCultureInfo(culture); - } - catch (CultureNotFoundException ex) - { - Logger?.Log(string.Format("Error getting culture: {0}. Using {1} instead", ex.Message, CultureInfo.CurrentCulture.Name)); - } - return CultureInfo.CurrentCulture; + return string.IsNullOrWhiteSpace(culture) ? CultureInfo.CurrentCulture : CultureInfo.GetCultureInfo(culture); } + catch (CultureNotFoundException ex) + { + Logger?.Log(string.Format("Error getting culture: {0}. Using {1} instead", ex.Message, CultureInfo.CurrentCulture.Name)); + } + return CultureInfo.CurrentCulture; + } - private void GetSchemaForTableFromFile(Schema schema, Dictionary excelReaders, bool isFolderUsed = false) + private void GetSchemaForTableFromFile(Schema schema, Dictionary excelReaders, bool isFolderUsed = false) + { + foreach (var reader in excelReaders) { - foreach (var reader in excelReaders) + foreach (DataTable dt in reader.Value.ExcelSet.Tables) { - foreach (DataTable dt in reader.Value.ExcelSet.Tables) + Table excelTable = schema.AddTable(dt.TableName); + if (isFolderUsed) { - Table excelTable = schema.AddTable(dt.TableName); - if (isFolderUsed) + excelTable.SqlSchema = Path.GetFileName(reader.Key); + } + try + { + int columnCount; + try { - excelTable.SqlSchema = Path.GetFileName(reader.Key); + columnCount = dt.Columns.Count; } - try + catch (System.ArgumentException) { - int columnCount; - try - { - columnCount = dt.Columns.Count; - } - catch (System.ArgumentException) - { - columnCount = dt.Columns.Count; - } - foreach (System.Data.DataColumn c in dt.Columns) - { - Column column = new Column(c.ColumnName, c.DataType, excelTable); - if (!string.IsNullOrEmpty(c.Caption) && !string.Equals(c.Caption, c.ColumnName, StringComparison.OrdinalIgnoreCase)) - { - column.NameWithWhitespaceStripped = c.Caption; - } - excelTable.AddColumn(column); - } - + columnCount = dt.Columns.Count; } - catch (System.ArgumentException ae) + foreach (System.Data.DataColumn c in dt.Columns) { - string msg = string.Format("Error reading Excel file: {0} ", reader.Key); - Exception ex = new Exception(msg, ae); - throw ex; + Column column = new Column(c.ColumnName, c.DataType, excelTable); + if (!string.IsNullOrEmpty(c.Caption) && !string.Equals(c.Caption, c.ColumnName, StringComparison.OrdinalIgnoreCase)) + { + column.NameWithWhitespaceStripped = c.Caption; + } + excelTable.AddColumn(column); } - } + } + catch (System.ArgumentException ae) + { + string msg = string.Format("Error reading Excel file: {0} ", reader.Key); + Exception ex = new Exception(msg, ae); + throw ex; + } } - } - Schema IDestination.GetSchema() - { - schema ??= GetOriginalSourceSchema(); - return schema; } + } - Schema ISource.GetSchema() - { - schema ??= GetOriginalSourceSchema(); - return schema; - } + Schema IDestination.GetSchema() + { + schema ??= GetOriginalSourceSchema(); + return schema; + } + + Schema ISource.GetSchema() + { + schema ??= GetOriginalSourceSchema(); + return schema; + } - public ExcelProvider() + public ExcelProvider() + { + if (string.IsNullOrEmpty(FilesFolderName)) { - if (string.IsNullOrEmpty(FilesFolderName)) - { - FilesFolderName = "Files"; - } + FilesFolderName = "Files"; } + } - public ExcelProvider(XmlNode xmlNode) + public ExcelProvider(XmlNode xmlNode) + { + foreach (XmlNode node in xmlNode.ChildNodes) { - foreach (XmlNode node in xmlNode.ChildNodes) + switch (node.Name) { - switch (node.Name) - { - case "Schema": - schema = new Schema(node); - break; - case "SourcePath": - if (node.HasChildNodes) - { - SourceFile = node.FirstChild.Value; - } - break; - case "SourceFolder": - if (node.HasChildNodes) - { - SourceFolder = node.FirstChild.Value; - } - break; - case "DestinationFile": - if (node.HasChildNodes) - { - DestinationFile = node.FirstChild.Value; - } - break; - case "DestinationFolder": - if (node.HasChildNodes) - { - DestinationFolder = node.FirstChild.Value; - } - break; + case "Schema": + schema = new Schema(node); + break; + case "SourcePath": + if (node.HasChildNodes) + { + SourceFile = node.FirstChild.Value; + } + break; + case "SourceFolder": + if (node.HasChildNodes) + { + SourceFolder = node.FirstChild.Value; + } + break; + case "DestinationFile": + if (node.HasChildNodes) + { + DestinationFile = node.FirstChild.Value; + } + break; + case "DestinationFolder": + if (node.HasChildNodes) + { + DestinationFolder = node.FirstChild.Value; + } + break; - } } } + } - internal ExcelProvider(Dictionary excelReaders, Schema schema, ExcelDestinationWriter writer) - { - this.schema = schema; - destinationWriter = writer; - } + internal ExcelProvider(Dictionary excelReaders, Schema schema, ExcelDestinationWriter writer) + { + this.schema = schema; + destinationWriter = writer; + } - public ExcelProvider(string path) - { - SourceFile = path; - } + public ExcelProvider(string path) + { + SourceFile = path; + } - public override void OverwriteSourceSchemaToOriginal() - { - schema = GetOriginalSourceSchema(); - } + public override void OverwriteSourceSchemaToOriginal() + { + schema = GetOriginalSourceSchema(); + } - public override void OverwriteDestinationSchemaToOriginal() + public override void OverwriteDestinationSchemaToOriginal() + { + } + + public override string ValidateDestinationSettings() + { + string extension = Path.GetFileNameWithoutExtension(DestinationFile); + if (!string.Equals(extension, DestinationFile, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(extension) && !(extension.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || extension.EndsWith(".xls", StringComparison.OrdinalIgnoreCase))) { + return "File has to end with .xlsx or .xls"; } + return ""; + } - public override string ValidateDestinationSettings() + public override string ValidateSourceSettings() + { + if (string.IsNullOrEmpty(SourceFile) && string.IsNullOrEmpty(SourceFolder)) { - string extension = Path.GetFileNameWithoutExtension(DestinationFile); - if (!string.Equals(extension, DestinationFile, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(extension) && !(extension.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || extension.EndsWith(".xls", StringComparison.OrdinalIgnoreCase))) - { - return "File has to end with .xlsx or .xls"; - } - return ""; + return "No Source file neither folder are selected"; } - - public override string ValidateSourceSettings() + if (IsFolderUsed) { - if (string.IsNullOrEmpty(SourceFile) && string.IsNullOrEmpty(SourceFolder)) + string srcFolderPath = SourceFolderPath; + + if (!Directory.Exists(srcFolderPath)) { - return "No Source file neither folder are selected"; + return "Source folder \"" + SourceFolder + "\" does not exist"; } - if (IsFolderUsed) + else { - string srcFolderPath = SourceFolderPath; + var files = GetSourceFolderFiles(); - if (!Directory.Exists(srcFolderPath)) + if (files.Count() == 0) { - return "Source folder \"" + SourceFolder + "\" does not exist"; - } - else - { - var files = GetSourceFolderFiles(); - - if (files.Count() == 0) - { - return "There are no Excel files with the extensions: [*.xlsx, *.xls, *.xlsm] in the source folder "; - } + return "There are no Excel files with the extensions: [*.xlsx, *.xls, *.xlsm] in the source folder "; } } - else + } + else + { + ExcelPackage.LicenseContext = LicenseContext.Commercial; + if (SourceFile.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || + SourceFile.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || + SourceFile.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) { - ExcelPackage.LicenseContext = LicenseContext.Commercial; - if (SourceFile.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || - SourceFile.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || - SourceFile.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) - { - string filename = GetSourceFilePath(SourceFile); - if (!File.Exists(filename)) - { - return $"Excel file \"{SourceFile}\" does not exist. WorkingDirectory - {WorkingDirectory}"; - } - } - else + string filename = GetSourceFilePath(SourceFile); + if (!File.Exists(filename)) { - return "The file is not an Excel file"; - } + return $"Excel file \"{SourceFile}\" does not exist. WorkingDirectory - {WorkingDirectory}"; + } } - if (!string.IsNullOrEmpty(SourceFile) && !string.IsNullOrEmpty(SourceFolder)) + else { - return "Warning: In your Excel Provider source, you selected both a source file and a source folder. The source folder selection will be ignored, and only the source file will be used."; + return "The file is not an Excel file"; } - return null; } - - public IEnumerable GetParameterOptions(string parameterName) => new List(); + if (!string.IsNullOrEmpty(SourceFile) && !string.IsNullOrEmpty(SourceFolder)) + { + return "Warning: In your Excel Provider source, you selected both a source file and a source folder. The source folder selection will be ignored, and only the source file will be used."; + } + return null; } -} + + public IEnumerable GetParameterOptions(string parameterName) => new List(); +} \ No newline at end of file diff --git a/src/ExcelReader.cs b/src/ExcelReader.cs index eb9d078..efd050e 100644 --- a/src/ExcelReader.cs +++ b/src/ExcelReader.cs @@ -1,118 +1,117 @@ -using OfficeOpenXml; -using System; +using System; using System.Collections.Generic; using System.Data; using System.IO; +using OfficeOpenXml; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider; + +public class ExcelReader : IDisposable { - public class ExcelReader : IDisposable - { - public string Filename { get; set; } - public DataSet ExcelSet { get; set; } + public string Filename { get; set; } + public DataSet ExcelSet { get; set; } - public ExcelReader(string filename) + public ExcelReader(string filename) + { + Filename = filename; + if (filename.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || + filename.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || + filename.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) { - Filename = filename; - if (filename.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) || - filename.EndsWith(".xls", StringComparison.OrdinalIgnoreCase) || - filename.EndsWith(".xlsm", StringComparison.OrdinalIgnoreCase)) + if (ExcelSet == null) { - if (ExcelSet == null) + if (File.Exists(filename)) { - if (File.Exists(filename)) - { - LoadExcelFile(); - } + LoadExcelFile(); } } - else - { - throw new Exception("File is not an Excel file"); - } } + else + { + throw new Exception("File is not an Excel file"); + } + } - private void LoadExcelFile() + private void LoadExcelFile() + { + ExcelPackage.LicenseContext = LicenseContext.Commercial; + var fileInfo = new FileInfo(Filename); + using var package = new ExcelPackage(fileInfo); + var ds = new DataSet(); + foreach (var worksheet in package.Workbook.Worksheets) { - ExcelPackage.LicenseContext = LicenseContext.Commercial; - var fileInfo = new FileInfo(Filename); - using var package = new ExcelPackage(fileInfo); - var ds = new DataSet(); - foreach (var worksheet in package.Workbook.Worksheets) - { - var firstRowNumberWithData = GetFirstRowNumberWithData(worksheet); - if (firstRowNumberWithData <= 0) - continue; + var firstRowNumberWithData = GetFirstRowNumberWithData(worksheet); + if (firstRowNumberWithData <= 0) + continue; - var emptyRows = new List(); - var dataTable = new DataTable(worksheet.Name); - var firstRow = worksheet.Cells[firstRowNumberWithData, 1, firstRowNumberWithData, worksheet.Dimension.End.Column]; - for (var colNum = 1; colNum <= worksheet.Dimension.End.Column; colNum++) + var emptyRows = new List(); + var dataTable = new DataTable(worksheet.Name); + var firstRow = worksheet.Cells[firstRowNumberWithData, 1, firstRowNumberWithData, worksheet.Dimension.End.Column]; + for (var colNum = 1; colNum <= worksheet.Dimension.End.Column; colNum++) + { + var firstRowCell = firstRow[firstRowNumberWithData, colNum]; + DataColumn column; + var header = firstRowCell.Text; + if (!dataTable.Columns.Contains(header) && !string.IsNullOrWhiteSpace(header)) + { + column = dataTable.Columns.Add(header); + } + else { - var firstRowCell = firstRow[firstRowNumberWithData, colNum]; - DataColumn column; - var header = firstRowCell.Text; - if (!dataTable.Columns.Contains(header) && !string.IsNullOrWhiteSpace(header)) - { - column = dataTable.Columns.Add(header); - } - else - { - column = dataTable.Columns.Add(header + colNum); - } + column = dataTable.Columns.Add(header + colNum); + } - if (!string.IsNullOrEmpty(firstRowCell.Comment?.Text)) - { - column.Caption = firstRowCell.Comment.Text; - } + if (!string.IsNullOrEmpty(firstRowCell.Comment?.Text)) + { + column.Caption = firstRowCell.Comment.Text; } + } - for (var rowNum = firstRowNumberWithData + 1; rowNum <= worksheet.Dimension.End.Row; rowNum++) + for (var rowNum = firstRowNumberWithData + 1; rowNum <= worksheet.Dimension.End.Row; rowNum++) + { + var hasValue = false; + var wsRow = worksheet.Cells[rowNum, 1, rowNum, worksheet.Dimension.End.Column]; + var row = dataTable.Rows.Add(); + for(var colNum = 1; colNum <= worksheet.Dimension.End.Column; colNum++) { - var hasValue = false; - var wsRow = worksheet.Cells[rowNum, 1, rowNum, worksheet.Dimension.End.Column]; - var row = dataTable.Rows.Add(); - for(var colNum = 1; colNum <= worksheet.Dimension.End.Column; colNum++) - { - string cellText = wsRow[rowNum, colNum].Text; - row[colNum - 1] = cellText; + string cellText = wsRow[rowNum, colNum].Text; + row[colNum - 1] = cellText; - if (!string.IsNullOrWhiteSpace(cellText)) - hasValue = true; - } - - if (!hasValue) - emptyRows.Add(row); + if (!string.IsNullOrWhiteSpace(cellText)) + hasValue = true; } - foreach (var row in emptyRows) - dataTable.Rows.Remove(row); - - ds.Tables.Add(dataTable); + if (!hasValue) + emptyRows.Add(row); } - ExcelSet = ds; + foreach (var row in emptyRows) + dataTable.Rows.Remove(row); + + ds.Tables.Add(dataTable); } - private static int GetFirstRowNumberWithData(ExcelWorksheet worksheet) - { - for (var rowNum = 1; rowNum <= worksheet.Dimension?.End?.Row; rowNum++) - { - var wsRow = worksheet.Cells[rowNum, 1, rowNum, worksheet.Dimension.End.Column]; - for (var colNum = 1; colNum <= worksheet.Dimension.End.Column; colNum++) - { - string cellText = wsRow[rowNum, colNum].Text; - if (!string.IsNullOrWhiteSpace(cellText)) - return rowNum; - } + ExcelSet = ds; + } + + private static int GetFirstRowNumberWithData(ExcelWorksheet worksheet) + { + for (var rowNum = 1; rowNum <= worksheet.Dimension?.End?.Row; rowNum++) + { + var wsRow = worksheet.Cells[rowNum, 1, rowNum, worksheet.Dimension.End.Column]; + for (var colNum = 1; colNum <= worksheet.Dimension.End.Column; colNum++) + { + string cellText = wsRow[rowNum, colNum].Text; + if (!string.IsNullOrWhiteSpace(cellText)) + return rowNum; } - return -1; } + return -1; + } - public void Dispose() - { - ExcelSet.Clear(); - ExcelSet.Dispose(); - } + public void Dispose() + { + ExcelSet.Clear(); + ExcelSet.Dispose(); } -} +} \ No newline at end of file diff --git a/src/ExcelSourceReader.cs b/src/ExcelSourceReader.cs index 976106e..eee52be 100644 --- a/src/ExcelSourceReader.cs +++ b/src/ExcelSourceReader.cs @@ -1,201 +1,200 @@ -using Dynamicweb.DataIntegration.Integration; -using Dynamicweb.DataIntegration.Integration.Interfaces; -using System; +using System; using System.Collections.Generic; using System.Data; +using Dynamicweb.DataIntegration.Integration; +using Dynamicweb.DataIntegration.Integration.Interfaces; + +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider +/// +/// ExcelSourceReader +/// +public class ExcelSourceReader : ISourceReader { + private readonly Mapping mapping; + private readonly string path; + private ExcelReader reader; + private int rowsCount = 0; + private Dictionary nextResult; + private readonly ExcelProvider _provider; + + private HashSet NumericTypes = new HashSet + { + typeof(decimal), typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(long), typeof(double), typeof(float) + }; + /// - /// ExcelSourceReader + /// ColumnCount /// - public class ExcelSourceReader : ISourceReader + public virtual int ColumnCount { - private readonly Mapping mapping; - private readonly string path; - private ExcelReader reader; - private int rowsCount = 0; - private Dictionary nextResult; - private readonly ExcelProvider _provider; - - private HashSet NumericTypes = new HashSet - { - typeof(decimal), typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(long), typeof(double), typeof(float) - }; - - /// - /// ColumnCount - /// - public virtual int ColumnCount - { - get { throw new NotImplementedException(); } - } + get { throw new NotImplementedException(); } + } - private ExcelReader Reader + private ExcelReader Reader + { + get { - get + if (reader == null) { - if (reader == null) - { - reader = new ExcelReader(path); - } - return reader; + reader = new ExcelReader(path); } + return reader; } + } - internal ExcelSourceReader(ExcelReader reader, Mapping mapping) - { - this.reader = reader; - this.mapping = mapping; - VerifyDuplicateColumns(); - } + internal ExcelSourceReader(ExcelReader reader, Mapping mapping) + { + this.reader = reader; + this.mapping = mapping; + VerifyDuplicateColumns(); + } - public ExcelSourceReader(string filename, Mapping mapping, ExcelProvider provider) - { - path = filename; - this.mapping = mapping; - VerifyDuplicateColumns(); - _provider = provider; - } + public ExcelSourceReader(string filename, Mapping mapping, ExcelProvider provider) + { + path = filename; + this.mapping = mapping; + VerifyDuplicateColumns(); + _provider = provider; + } - public ExcelSourceReader() - { - } + public ExcelSourceReader() + { + } - public bool IsDone() + public bool IsDone() + { + if (Reader?.ExcelSet?.Tables != null && Reader.ExcelSet.Tables.Count > 0) { - if (Reader?.ExcelSet?.Tables != null && Reader.ExcelSet.Tables.Count > 0) + Dictionary result = new Dictionary(); + DataTable dt = null; + foreach (DataTable table in Reader.ExcelSet.Tables) { - Dictionary result = new Dictionary(); - DataTable dt = null; - foreach (DataTable table in Reader.ExcelSet.Tables) + if (table.TableName.Equals(mapping.SourceTable.Name)) { - if (table.TableName.Equals(mapping.SourceTable.Name)) - { - dt = table; - break; - } + dt = table; + break; } - if (dt.Rows.Count == rowsCount) - { - rowsCount = 0; - return true; - } - if (dt != null) - { - DataRow dr = dt.Rows[rowsCount]; + } + if (dt.Rows.Count == rowsCount) + { + rowsCount = 0; + return true; + } + if (dt != null) + { + DataRow dr = dt.Rows[rowsCount]; - foreach (Column column in mapping.GetSourceColumns(true, true)) + foreach (Column column in mapping.GetSourceColumns(true, true)) + { + if (!result.ContainsKey(column.Name) && dt.Columns.Contains(column.Name)) { - if (!result.ContainsKey(column.Name) && dt.Columns.Contains(column.Name)) + if (dr[column.Name] == null) { - if (dr[column.Name] == null) - { - result.Add(column.Name, DBNull.Value); - } - else + result.Add(column.Name, DBNull.Value); + } + else + { + string value = dr[column.Name].ToString(); + if (NumericTypes.Contains(column.Type)) { - string value = dr[column.Name].ToString(); - if (NumericTypes.Contains(column.Type)) + if (string.IsNullOrEmpty(value)) { - if (string.IsNullOrEmpty(value)) - { - result.Add(column.Name, 0); - } - else - { - result.Add(column.Name, dr[column.Name]); - } + result.Add(column.Name, 0); } else { - result.Add(column.Name, value); + result.Add(column.Name, dr[column.Name]); } } + else + { + result.Add(column.Name, value); + } } } - rowsCount++; } + rowsCount++; + } - nextResult = result; + nextResult = result; - if (RowMatchesConditions()) - { - return false; - } - - return IsDone(); + if (RowMatchesConditions()) + { + return false; } - return true; - } - private bool RowMatchesConditions() - { - return mapping.Conditionals?.CheckConditionals(nextResult) ?? true; + return IsDone(); } + return true; + } - public Dictionary GetNext() - { - return nextResult; - } + private bool RowMatchesConditions() + { + return mapping.Conditionals?.CheckConditionals(nextResult) ?? true; + } - private void VerifyDuplicateColumns() + public Dictionary GetNext() + { + return nextResult; + } + + private void VerifyDuplicateColumns() + { + if (Reader != null) { - if (Reader != null) + foreach (DataTable dt in Reader.ExcelSet.Tables) { - foreach (DataTable dt in Reader.ExcelSet.Tables) + List headers = new List(); + foreach (System.Data.DataColumn c in dt.Columns) { - List headers = new List(); - foreach (System.Data.DataColumn c in dt.Columns) + if (!headers.Contains(c.ColumnName)) { - if (!headers.Contains(c.ColumnName)) - { - headers.Add(c.ColumnName); - } - else - { - throw new Exception(string.Format("File {0}.xlsx : repeated columns found: {1}. ", + headers.Add(c.ColumnName); + } + else + { + throw new Exception(string.Format("File {0}.xlsx : repeated columns found: {1}. ", mapping.SourceTable.Name, string.Join(",", headers.ToArray()))); - } } } } } + } - #region IDisposable Implementation + #region IDisposable Implementation - protected bool Disposed; + protected bool Disposed; - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) + { + reader.Dispose(); + lock (this) { - reader.Dispose(); - lock (this) - { - // Do nothing if the object has already been disposed of. - if (Disposed) - return; - - if (disposing) - { - // Release diposable objects used by this instance here. - if (reader != null) - reader.Dispose(); - } - - // Release unmanaged resources here. Don't access reference type fields. + // Do nothing if the object has already been disposed of. + if (Disposed) + return; - // Remember that the object has been disposed of. - Disposed = true; + if (disposing) + { + // Release diposable objects used by this instance here. + if (reader != null) + reader.Dispose(); } - } - public virtual void Dispose() - { - Dispose(true); - // Unregister object for finalization. - GC.SuppressFinalize(this); + // Release unmanaged resources here. Don't access reference type fields. + + // Remember that the object has been disposed of. + Disposed = true; } + } - #endregion + public virtual void Dispose() + { + Dispose(true); + // Unregister object for finalization. + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/src/ExportDataToExcelProvider.cs b/src/ExportDataToExcelProvider.cs index 7429133..240f16d 100644 --- a/src/ExportDataToExcelProvider.cs +++ b/src/ExportDataToExcelProvider.cs @@ -1,260 +1,259 @@ -using Dynamicweb.Core; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using Dynamicweb.Core; using Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; using Dynamicweb.Extensibility; using OfficeOpenXml; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.IO; -using System.Linq; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider; + +public class ExportDataToExcelProvider : Integration.Interfaces.IDataExportProvider { - public class ExportDataToExcelProvider : Integration.Interfaces.IDataExportProvider + private FieldsHelper FieldsHelper = new FieldsHelper(); + private IEnumerable CustomFields = ProductField.GetProductFields(); + private const string CommentsAuthor = "Dynamicweb"; + + public ExportDataToExcelProvider() { - private FieldsHelper FieldsHelper = new FieldsHelper(); - private IEnumerable CustomFields = ProductField.GetProductFields(); - private const string CommentsAuthor = "Dynamicweb"; + } - public ExportDataToExcelProvider() - { - } + public bool ExportData(string destinationFilePath, IEnumerable data, IDictionary fields) + { + if (data is null) + return false; - public bool ExportData(string destinationFilePath, IEnumerable data, IDictionary fields) + using (ExcelPackage package = GetExcelPackage(destinationFilePath)) { - if (data is null) - return false; + ExcelWorksheet worksheet = GetExcelWorksheet(package, Path.GetFileName(destinationFilePath)); - using (ExcelPackage package = GetExcelPackage(destinationFilePath)) + if (fields is null || !fields.Any()) { - ExcelWorksheet worksheet = GetExcelWorksheet(package, Path.GetFileName(destinationFilePath)); - - if (fields is null || !fields.Any()) - { - fields = data.FirstOrDefault().GetType().GetProperties().Select(f => f.Name).Distinct().ToDictionary(p => p); - } - - AddHeader(worksheet, fields); - - int rowIndex = 2; - foreach (var row in data) - { - AddDataRow(worksheet, ref rowIndex, row, fields.Keys.ToList()); - rowIndex++; - } - - SetColumnsWidth(worksheet); - - package.Save(); + fields = data.FirstOrDefault().GetType().GetProperties().Select(f => f.Name).Distinct().ToDictionary(p => p); } - return true; - } + AddHeader(worksheet, fields); - private ExcelPackage GetExcelPackage(string file) - { - FileInfo newFile = new FileInfo(file); - if (newFile.Exists) + int rowIndex = 2; + foreach (var row in data) { - newFile.Delete(); - newFile = new FileInfo(file); + AddDataRow(worksheet, ref rowIndex, row, fields.Keys.ToList()); + rowIndex++; } - ExcelPackage.LicenseContext = LicenseContext.Commercial; - var excelPackage = new ExcelPackage(newFile); - excelPackage.Workbook.Properties.Keywords += "Dynamicweb"; - return excelPackage; - } - private ExcelWorksheet GetExcelWorksheet(ExcelPackage package, string title) - { - ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(title); - return worksheet; + SetColumnsWidth(worksheet); + + package.Save(); } - private ExcelRange AddCell(ExcelWorksheet worksheet, string text, int row, int column) + return true; + } + + private ExcelPackage GetExcelPackage(string file) + { + FileInfo newFile = new FileInfo(file); + if (newFile.Exists) { - ExcelRange cell = worksheet.Cells[row, column]; - cell.Value = text; - return cell; + newFile.Delete(); + newFile = new FileInfo(file); } + ExcelPackage.LicenseContext = LicenseContext.Commercial; + var excelPackage = new ExcelPackage(newFile); + excelPackage.Workbook.Properties.Keywords += "Dynamicweb"; + return excelPackage; + } + + private ExcelWorksheet GetExcelWorksheet(ExcelPackage package, string title) + { + ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(title); + return worksheet; + } - private void AddHeaderCell(ExcelWorksheet worksheet, string caption, int row, int column, string fieldSystemName) + private ExcelRange AddCell(ExcelWorksheet worksheet, string text, int row, int column) + { + ExcelRange cell = worksheet.Cells[row, column]; + cell.Value = text; + return cell; + } + + private void AddHeaderCell(ExcelWorksheet worksheet, string caption, int row, int column, string fieldSystemName) + { + var cell = AddCell(worksheet, caption, row, column); + if(!string.IsNullOrEmpty(fieldSystemName) && + (!string.Equals(caption, fieldSystemName, System.StringComparison.OrdinalIgnoreCase) || + fieldSystemName.StartsWith("CustomFields|", System.StringComparison.OrdinalIgnoreCase) || + fieldSystemName.StartsWith("CategoryFields|", System.StringComparison.OrdinalIgnoreCase))) { - var cell = AddCell(worksheet, caption, row, column); - if(!string.IsNullOrEmpty(fieldSystemName) && - (!string.Equals(caption, fieldSystemName, System.StringComparison.OrdinalIgnoreCase) || - fieldSystemName.StartsWith("CustomFields|", System.StringComparison.OrdinalIgnoreCase) || - fieldSystemName.StartsWith("CategoryFields|", System.StringComparison.OrdinalIgnoreCase))) - { - cell.AddComment(fieldSystemName, CommentsAuthor); - } + cell.AddComment(fieldSystemName, CommentsAuthor); } + } - private void AddHeader(ExcelWorksheet worksheet, IDictionary fields) - { - int lastColumnIndex = 1; - int firstRowIndex = 1; - var defaultLanguage = Ecommerce.Services.Languages.GetLanguages().FirstOrDefault(l => l.IsDefault); + private void AddHeader(ExcelWorksheet worksheet, IDictionary fields) + { + int lastColumnIndex = 1; + int firstRowIndex = 1; + var defaultLanguage = Ecommerce.Services.Languages.GetLanguages().FirstOrDefault(l => l.IsDefault); - worksheet.Row(firstRowIndex).Height = 30; + worksheet.Row(firstRowIndex).Height = 30; - foreach (string field in fields.Keys) + foreach (string field in fields.Keys) + { + string caption = fields[field]; + if (string.IsNullOrEmpty(caption)) { - string caption = fields[field]; - if (string.IsNullOrEmpty(caption)) - { - caption = GetFieldCaption(field, defaultLanguage); - } - AddHeaderCell(worksheet, caption, firstRowIndex, lastColumnIndex++, field); + caption = GetFieldCaption(field, defaultLanguage); } + AddHeaderCell(worksheet, caption, firstRowIndex, lastColumnIndex++, field); } + } - private void AddDataRow(ExcelWorksheet worksheet, ref int rowIndex, object dataRow, IEnumerable fields) - { - int lastColumnIndex = 1; - object value = null; + private void AddDataRow(ExcelWorksheet worksheet, ref int rowIndex, object dataRow, IEnumerable fields) + { + int lastColumnIndex = 1; + object value = null; - foreach (var field in fields) + foreach (var field in fields) + { + var customFieldSystemName = GetCustomFieldSystemName(field); + if (CustomFields.Any(f => string.Equals(f.SystemName, customFieldSystemName))) + { + value = GetCustomFieldValue(dataRow, customFieldSystemName); + } + else { - var customFieldSystemName = GetCustomFieldSystemName(field); - if (CustomFields.Any(f => string.Equals(f.SystemName, customFieldSystemName))) + if (CategoryFieldTryParseUniqueId(field, out _, out _)) { - value = GetCustomFieldValue(dataRow, customFieldSystemName); + value = GetCategoryFieldValue(dataRow, GetCategoryFieldSystemName(field)); } else { - if (CategoryFieldTryParseUniqueId(field, out _, out _)) - { - value = GetCategoryFieldValue(dataRow, GetCategoryFieldSystemName(field)); - } - else - { - value = TypeHelper.GetPropertyValue(dataRow, field); - } + value = TypeHelper.GetPropertyValue(dataRow, field); } - AddCell(worksheet, Converter.ToString(value), rowIndex, lastColumnIndex++); } - - worksheet.Row(rowIndex).Height = 15; + AddCell(worksheet, Converter.ToString(value), rowIndex, lastColumnIndex++); } - private string GetTranslatedValue(object value, string systemName) + worksheet.Row(rowIndex).Height = 15; + } + + private string GetTranslatedValue(object value, string systemName) + { + if (value is not null && value.ToString()?.Split(",") is string[] options) { - if (value is not null && value.ToString()?.Split(",") is string[] options) + var fieldOptions = Ecommerce.Services.FieldOptions.GetOptionsByFieldIdAndValues(systemName, options.ToHashSet()); + if (fieldOptions.Any()) { - var fieldOptions = Ecommerce.Services.FieldOptions.GetOptionsByFieldIdAndValues(systemName, options.ToHashSet()); - if (fieldOptions.Any()) - { - return string.Join(",", fieldOptions.Select(fo => fo.Translations.Get(Ecommerce.Services.Languages.GetDefaultLanguageId()).Name)); - } + return string.Join(",", fieldOptions.Select(fo => fo.Translations.Get(Ecommerce.Services.Languages.GetDefaultLanguageId()).Name)); } - return Converter.ToString(value); } + return Converter.ToString(value); + } - public string GetCategoryFieldSystemName(string fieldSystemName) - { - return fieldSystemName.StartsWith("CategoryFields|") - ? fieldSystemName.Substring("CategoryFields|".Length) - : fieldSystemName; - } + public string GetCategoryFieldSystemName(string fieldSystemName) + { + return fieldSystemName.StartsWith("CategoryFields|") + ? fieldSystemName.Substring("CategoryFields|".Length) + : fieldSystemName; + } - public string GetCustomFieldSystemName(string fieldSystemName) - { - return fieldSystemName.StartsWith("CustomFields|") - ? fieldSystemName.Substring("CustomFields|".Length) - : fieldSystemName; - } + public string GetCustomFieldSystemName(string fieldSystemName) + { + return fieldSystemName.StartsWith("CustomFields|") + ? fieldSystemName.Substring("CustomFields|".Length) + : fieldSystemName; + } - private string GetCustomFieldValue(object dataRow, string field) => GetCustomFieldValue("CustomFields", dataRow, FieldsHelper.GetFieldSystemName(field)); + private string GetCustomFieldValue(object dataRow, string field) => GetCustomFieldValue("CustomFields", dataRow, FieldsHelper.GetFieldSystemName(field)); - private string GetCategoryFieldValue(object dataRow, string fieldSystemName) => GetCustomFieldValue("CategoryFields", dataRow, fieldSystemName); + private string GetCategoryFieldValue(object dataRow, string fieldSystemName) => GetCustomFieldValue("CategoryFields", dataRow, fieldSystemName); - private string GetCustomFieldValue(string fieldPropertyName, object dataRow, string field) - { - string fieldSystemName = FieldsHelper.GetFieldSystemName(field); + private string GetCustomFieldValue(string fieldPropertyName, object dataRow, string field) + { + string fieldSystemName = FieldsHelper.GetFieldSystemName(field); - var property = dataRow.GetType().GetProperty(fieldPropertyName); - if (property is not null) + var property = dataRow.GetType().GetProperty(fieldPropertyName); + if (property is not null) + { + var customFields = TypeHelper.GetPropertyValue(dataRow, fieldPropertyName); + if (customFields != null) { - var customFields = TypeHelper.GetPropertyValue(dataRow, fieldPropertyName); - if (customFields != null) + var groups = TypeHelper.GetPropertyValue(customFields, "Groups"); + if (groups != null && groups is IEnumerable enumerable) { - var groups = TypeHelper.GetPropertyValue(customFields, "Groups"); - if (groups != null && groups is IEnumerable enumerable) + foreach (var group in enumerable) { - foreach (var group in enumerable) + var fieldsCollection = TypeHelper.GetPropertyValue(group, "Fields"); + if (fieldsCollection != null && fieldsCollection is IEnumerable fieldsEnumerable) { - var fieldsCollection = TypeHelper.GetPropertyValue(group, "Fields"); - if (fieldsCollection != null && fieldsCollection is IEnumerable fieldsEnumerable) + foreach (var fieldObj in fieldsEnumerable) { - foreach (var fieldObj in fieldsEnumerable) - { - if (string.Equals(Converter.ToString(TypeHelper.GetPropertyValue(fieldObj, "SystemName")), + if (string.Equals(Converter.ToString(TypeHelper.GetPropertyValue(fieldObj, "SystemName")), fieldSystemName, System.StringComparison.OrdinalIgnoreCase)) - { - return GetTranslatedValue(TypeHelper.GetPropertyValue(fieldObj, "Value"), fieldSystemName); - } + { + return GetTranslatedValue(TypeHelper.GetPropertyValue(fieldObj, "Value"), fieldSystemName); } } } } } } - return null; } + return null; + } - public string GetFieldCaption(string fieldSystemName, Language language) + public string GetFieldCaption(string fieldSystemName, Language language) + { + string result = fieldSystemName; + ProductField field = null; + if (fieldSystemName.StartsWith("CustomFields|")) { - string result = fieldSystemName; - ProductField field = null; - if (fieldSystemName.StartsWith("CustomFields|")) + fieldSystemName = GetCustomFieldSystemName(fieldSystemName); + field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); + if (field != null) { - fieldSystemName = GetCustomFieldSystemName(fieldSystemName); - field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); - if (field != null) - { - result = ProductFieldTranslation.GetTranslatedFieldName(field, language.LanguageId); - } - if (string.IsNullOrEmpty(result)) - { - result = field != null ? field.Name : fieldSystemName; - } + result = ProductFieldTranslation.GetTranslatedFieldName(field, language.LanguageId); } - else if (CategoryFieldTryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + if (string.IsNullOrEmpty(result)) { - var categoryField = Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryId, fieldId); - if (categoryField != null && categoryField.Category != null) - { - result = $"{categoryField.Category.GetName(language.LanguageId)} - {categoryField.GetLabel(language.LanguageId)}"; - } - if (string.IsNullOrEmpty(result)) - { - result = fieldSystemName; - } + result = field != null ? field.Name : fieldSystemName; } - return result; } - - private bool CategoryFieldTryParseUniqueId(string uniqueId, out string categoryId, out string fieldId) + else if (CategoryFieldTryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) { - var idParts = Converter.ToString(uniqueId).Split('|'); - if (idParts.Length == 4) + var categoryField = Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryId, fieldId); + if (categoryField != null && categoryField.Category != null) { - categoryId = idParts[2]; - fieldId = idParts[3]; - return !string.IsNullOrEmpty(categoryId) && !string.IsNullOrEmpty(fieldId); + result = $"{categoryField.Category.GetName(language.LanguageId)} - {categoryField.GetLabel(language.LanguageId)}"; + } + if (string.IsNullOrEmpty(result)) + { + result = fieldSystemName; } - - categoryId = string.Empty; - fieldId = string.Empty; - return false; } + return result; + } - private void SetColumnsWidth(ExcelWorksheet worksheet) + private bool CategoryFieldTryParseUniqueId(string uniqueId, out string categoryId, out string fieldId) + { + var idParts = Converter.ToString(uniqueId).Split('|'); + if (idParts.Length == 4) { - worksheet.Cells.AutoFitColumns(10); + categoryId = idParts[2]; + fieldId = idParts[3]; + return !string.IsNullOrEmpty(categoryId) && !string.IsNullOrEmpty(fieldId); } + + categoryId = string.Empty; + fieldId = string.Empty; + return false; + } + + private void SetColumnsWidth(ExcelWorksheet worksheet) + { + worksheet.Cells.AutoFitColumns(10); } } \ No newline at end of file diff --git a/src/PIM/BaseExportExcelProvider.cs b/src/PIM/BaseExportExcelProvider.cs index 05aceda..bb1fb43 100644 --- a/src/PIM/BaseExportExcelProvider.cs +++ b/src/PIM/BaseExportExcelProvider.cs @@ -1,539 +1,534 @@ -using Dynamicweb.Core; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using Dynamicweb.Core; +using Dynamicweb.Ecommerce; using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; using Dynamicweb.Ecommerce.Products.Categories; -using Dynamicweb.Ecommerce.Variants; using OfficeOpenXml; using OfficeOpenXml.Style; using OfficeOpenXml.Style.XmlAccess; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Linq; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +internal class BaseExportExcelProvider { - internal class BaseExportExcelProvider + [Flags] + private enum PredefinedCellStyle { - [Flags] - private enum PredefinedCellStyle - { - None = 1 << 0, - Gray = 1 << 1, - List = 1 << 2, - Formula = 1 << 3, - MultiLine = 1 << 4, - Integer = 1 << 5, - Decimal = 1 << 6, - ReadOnly = 1 << 7 - } + None = 1 << 0, + Gray = 1 << 1, + List = 1 << 2, + Formula = 1 << 3, + MultiLine = 1 << 4, + Integer = 1 << 5, + Decimal = 1 << 6, + ReadOnly = 1 << 7 + } - private class ListFormulaRange - { - public int Column { get; set; } - public int RowStart { get; set; } - public int RowEnd { get; set; } - public string Formula { get; set; } - } + private class ListFormulaRange + { + public int Column { get; set; } + public int RowStart { get; set; } + public int RowEnd { get; set; } + public string Formula { get; set; } + } - protected bool ListFormulaCanBeRangedByColumn = false; - protected const string CommentsAuthor = "Dynamicweb"; - protected string[] SkipFields = new string[] { "ProductStockGroupID" }; - protected ListFieldsHelper ListFieldsHelper = null; - protected FieldsHelper FieldsHelper = new FieldsHelper(); - protected VariantCombinationService VariantCombinationService = new VariantCombinationService(); - protected ProductService ProductService = new ProductService(); - protected LanguageService LanguageService = new LanguageService(); - - protected Language DefaultLanguage = null; - protected IEnumerable Languages = null; - protected readonly int ListTypeId = 15; - protected int LastHiddenListOptionsColumnRowIndex = 1; - private readonly string HiddenListOptionsWorksheetName = "ListOptionsValues"; - private ExcelWorksheet ListOptionsWorksheet = null; - protected VariantService VariantService = new VariantService(); - protected ExcelNamedStyleXml LockedGrayStyle; - - internal bool ExportVariants { get; set; } = true; - - private readonly Dictionary predefinedCellStyles = new Dictionary(); - - protected BaseExportExcelProvider(IEnumerable fields, IEnumerable languages) - { - DefaultLanguage = LanguageService.GetLanguages().FirstOrDefault(l => l.IsDefault); - Languages = LanguageService.GetLanguages().Where(l => languages.Contains(l.LanguageId)); + protected bool ListFormulaCanBeRangedByColumn = false; + protected const string CommentsAuthor = "Dynamicweb"; + protected string[] SkipFields = new string[] { "ProductStockGroupID" }; + protected ListFieldsHelper ListFieldsHelper = null; + protected FieldsHelper FieldsHelper = new FieldsHelper(); - ListFieldsHelper = new ListFieldsHelper(fields); - } + protected Language DefaultLanguage = null; + protected IEnumerable Languages = null; + protected readonly int ListTypeId = 15; + protected int LastHiddenListOptionsColumnRowIndex = 1; + private readonly string HiddenListOptionsWorksheetName = "ListOptionsValues"; + private ExcelWorksheet ListOptionsWorksheet = null; + protected ExcelNamedStyleXml LockedGrayStyle; + + internal bool ExportVariants { get; set; } = true; - /// - /// Gets whether the field can be shown - /// - protected bool ShowField(Product product, string field) + private readonly Dictionary predefinedCellStyles = new Dictionary(); + + protected BaseExportExcelProvider(IEnumerable fields, IEnumerable languages) + { + DefaultLanguage = Services.Languages.GetLanguages().FirstOrDefault(l => l.IsDefault); + Languages = Services.Languages.GetLanguages().Where(l => languages.Contains(l.LanguageId)); + + ListFieldsHelper = new ListFieldsHelper(fields); + } + + /// + /// Gets whether the field can be shown + /// + protected bool ShowField(Product product, string field) + { + bool showField = false; + if (field == "ProductNumber" || field == "ProductName") { - bool showField = false; - if (field == "ProductNumber" || field == "ProductName") + showField = true; + } + else + { + bool isVariantEditingAllowed = false; + Field categoryField = FieldsHelper.GetCategoryField(field); + if (categoryField != null) { - showField = true; + isVariantEditingAllowed = FieldsHelper.IsCategoryFieldVariantEditingAllowed(categoryField); } else { - bool isVariantEditingAllowed = false; - Field categoryField = FieldsHelper.GetCategoryField(field); - if (categoryField != null) - { - isVariantEditingAllowed = FieldsHelper.IsCategoryFieldVariantEditingAllowed(categoryField); - } - else - { - isVariantEditingAllowed = FieldsHelper.IsVariantEditingAllowed(field); - } - if (string.IsNullOrEmpty(product.VariantId) && string.IsNullOrEmpty(product.VirtualVariantId)) - { - var variantCombinations = VariantCombinationService.GetVariantCombinations(product.Id); - showField = variantCombinations.Count == 0 || !variantCombinations.Any(combination => combination.HasRowInProductTable) || !isVariantEditingAllowed; - } - else - { - showField = isVariantEditingAllowed; - } + isVariantEditingAllowed = FieldsHelper.IsVariantEditingAllowed(field); } - return showField; - } - - protected string GetFieldValue(Product product, string field, KeyValuePair> options, bool multipleSelectionList, string languageId) - { - string fieldValue = FieldsHelper.GetProductFieldValue(product, field); - if (!string.IsNullOrEmpty(fieldValue) && options.Key != null && options.Value != null) + if (string.IsNullOrEmpty(product.VariantId) && string.IsNullOrEmpty(product.VirtualVariantId)) + { + var variantCombinations = Services.VariantCombinations.GetVariantCombinations(product.Id); + showField = variantCombinations.Count == 0 || !variantCombinations.Any(combination => combination.HasRowInProductTable) || !isVariantEditingAllowed; + } + else { - fieldValue = ListFieldsHelper.GetFieldOptionValue(fieldValue, options, multipleSelectionList, languageId); + showField = isVariantEditingAllowed; } - return fieldValue; } + return showField; + } - /// - /// Gets the numeric fiels from the exported fields - /// - protected Dictionary GetNumericFields(Product product, IEnumerable fields) + protected string GetFieldValue(Product product, string field, KeyValuePair> options, bool multipleSelectionList, string languageId) + { + string fieldValue = FieldsHelper.GetProductFieldValue(product, field); + if (!string.IsNullOrEmpty(fieldValue) && options.Key != null && options.Value != null) { - Dictionary numericFields = new Dictionary(); + fieldValue = ListFieldsHelper.GetFieldOptionValue(fieldValue, options, multipleSelectionList, languageId); + } + return fieldValue; + } + + /// + /// Gets the numeric fiels from the exported fields + /// + protected Dictionary GetNumericFields(Product product, IEnumerable fields) + { + Dictionary numericFields = new Dictionary(); - foreach (string field in fields) + foreach (string field in fields) + { + if (!numericFields.ContainsKey(field)) { - if (!numericFields.ContainsKey(field)) + Type fieldType = FieldsHelper.GetNumericFieldType(FieldsHelper.GetFieldSystemName(field)); + if (fieldType != null) { - Type fieldType = FieldsHelper.GetNumericFieldType(FieldsHelper.GetFieldSystemName(field)); - if (fieldType != null) - { - numericFields.Add(field, fieldType); - } + numericFields.Add(field, fieldType); } } - return numericFields; } + return numericFields; + } - /// - /// Gets the numeric fiels from the exported fields - /// - protected Dictionary GetNumericFields(IEnumerable fields) - { - return GetNumericFields(null, fields); - } + /// + /// Gets the numeric fiels from the exported fields + /// + protected Dictionary GetNumericFields(IEnumerable fields) + { + return GetNumericFields(null, fields); + } - protected ExcelPackage GetExcelPackage(string file) + protected ExcelPackage GetExcelPackage(string file) + { + FileInfo newFile = new FileInfo(file); + if (newFile.Exists) { - FileInfo newFile = new FileInfo(file); - if (newFile.Exists) - { - newFile.Delete(); // ensures we create a new workbook - newFile = new FileInfo(file); - } - ExcelPackage.LicenseContext = LicenseContext.Commercial; - var excelPackage = new ExcelPackage(newFile); - excelPackage.Workbook.Properties.Keywords += "Dynamicweb"; - return excelPackage; + newFile.Delete(); // ensures we create a new workbook + newFile = new FileInfo(file); } + ExcelPackage.LicenseContext = LicenseContext.Commercial; + var excelPackage = new ExcelPackage(newFile); + excelPackage.Workbook.Properties.Keywords += "Dynamicweb"; + return excelPackage; + } - protected ExcelWorksheet GetExcelWorksheet(ExcelPackage package, string title) - { - ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(title); - SetProtection(worksheet); - //Header - worksheet.Row(1).Height = 30; + protected ExcelWorksheet GetExcelWorksheet(ExcelPackage package, string title) + { + ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(title); + SetProtection(worksheet); + //Header + worksheet.Row(1).Height = 30; - CreateListOptionsWorksheet(package.Workbook, HiddenListOptionsWorksheetName + "1"); + CreateListOptionsWorksheet(package.Workbook, HiddenListOptionsWorksheetName + "1"); - return worksheet; - } + return worksheet; + } - private void CreateListOptionsWorksheet(ExcelWorkbook workbook, string workbookName) - { - ListOptionsWorksheet = workbook.Worksheets.Add(workbookName); - ListOptionsWorksheet.Hidden = eWorkSheetHidden.Hidden; - LastHiddenListOptionsColumnRowIndex = 1; - } + private void CreateListOptionsWorksheet(ExcelWorkbook workbook, string workbookName) + { + ListOptionsWorksheet = workbook.Worksheets.Add(workbookName); + ListOptionsWorksheet.Hidden = eWorkSheetHidden.Hidden; + LastHiddenListOptionsColumnRowIndex = 1; + } - protected Dictionary GetLanguageIdProductDictionary(Product mainProduct, IEnumerable familyProducts, IEnumerable languages) + protected Dictionary GetLanguageIdProductDictionary(Product mainProduct, IEnumerable familyProducts, IEnumerable languages) + { + Dictionary languageIdProductDictionary = new Dictionary(); + foreach (string languageId in languages) { - Dictionary languageIdProductDictionary = new Dictionary(); - foreach (string languageId in languages) + Product languageProduct = familyProducts.FirstOrDefault(product => product.Id == mainProduct.Id && string.IsNullOrEmpty(product.VariantId) && product.LanguageId == languageId); + if (languageProduct != null) { - Product languageProduct = familyProducts.FirstOrDefault(product => product.Id == mainProduct.Id && string.IsNullOrEmpty(product.VariantId) && product.LanguageId == languageId); - if (languageProduct != null) - { - languageIdProductDictionary.Add(languageId, languageProduct); - } + languageIdProductDictionary.Add(languageId, languageProduct); } - return languageIdProductDictionary; } + return languageIdProductDictionary; + } - protected Dictionary> GetVariantIdLanguageIdVariantProductDictionary(IEnumerable familyProducts, IEnumerable languages) + protected Dictionary> GetVariantIdLanguageIdVariantProductDictionary(IEnumerable familyProducts, IEnumerable languages) + { + var langsHash = new HashSet(languages); + Dictionary> variantIdLanguageIdVariantProductDictionary = new Dictionary>(); + foreach (var product in familyProducts) { - var langsHash = new HashSet(languages); - Dictionary> variantIdLanguageIdVariantProductDictionary = new Dictionary>(); - foreach (var product in familyProducts) + if (string.IsNullOrEmpty(product.VariantId) || !langsHash.Contains(product.LanguageId)) { - if (string.IsNullOrEmpty(product.VariantId) || !langsHash.Contains(product.LanguageId)) - { - continue; - } + continue; + } - Dictionary languageVariantDictionary; - if (!variantIdLanguageIdVariantProductDictionary.ContainsKey(product.VariantId)) - { - languageVariantDictionary = new Dictionary(); - variantIdLanguageIdVariantProductDictionary.Add(product.VariantId, languageVariantDictionary); - } - else - { - languageVariantDictionary = variantIdLanguageIdVariantProductDictionary[product.VariantId]; - } - if (!languageVariantDictionary.ContainsKey(product.LanguageId)) - { - languageVariantDictionary.Add(product.LanguageId, product); - } + Dictionary languageVariantDictionary; + if (!variantIdLanguageIdVariantProductDictionary.ContainsKey(product.VariantId)) + { + languageVariantDictionary = new Dictionary(); + variantIdLanguageIdVariantProductDictionary.Add(product.VariantId, languageVariantDictionary); + } + else + { + languageVariantDictionary = variantIdLanguageIdVariantProductDictionary[product.VariantId]; + } + if (!languageVariantDictionary.ContainsKey(product.LanguageId)) + { + languageVariantDictionary.Add(product.LanguageId, product); } - return variantIdLanguageIdVariantProductDictionary; } + return variantIdLanguageIdVariantProductDictionary; + } - /// - /// Makes excel worksheet protected - /// - private void SetProtection(ExcelWorksheet worksheet) - { - worksheet.Protection.AllowSelectLockedCells = false; - worksheet.Protection.IsProtected = true; - worksheet.Protection.AllowFormatColumns = true; - worksheet.Protection.AllowFormatCells = true; - worksheet.Protection.AllowFormatRows = true; - //Additionally don't allow user to change sheet names - //package.Workbook.Protection.LockStructure = true; - } + /// + /// Makes excel worksheet protected + /// + private void SetProtection(ExcelWorksheet worksheet) + { + worksheet.Protection.AllowSelectLockedCells = false; + worksheet.Protection.IsProtected = true; + worksheet.Protection.AllowFormatColumns = true; + worksheet.Protection.AllowFormatCells = true; + worksheet.Protection.AllowFormatRows = true; + //Additionally don't allow user to change sheet names + //package.Workbook.Protection.LockStructure = true; + } - /// - /// Gets lines count for the specified text and column width - /// - /// - protected int GetLineCount(string text, int columnWidth) + /// + /// Gets lines count for the specified text and column width + /// + /// + protected int GetLineCount(string text, int columnWidth) + { + if (!string.IsNullOrEmpty(text) && columnWidth > 0) { - if (!string.IsNullOrEmpty(text) && columnWidth > 0) - { - return (int)Math.Ceiling((double)(text.Length / columnWidth)); - } - return 1; + return (int)Math.Ceiling((double)(text.Length / columnWidth)); } + return 1; + } - private readonly Dictionary listsFormulas = new Dictionary(); + private readonly Dictionary listsFormulas = new Dictionary(); - protected void SetListFormulas(ExcelWorksheet worksheet) + protected void SetListFormulas(ExcelWorksheet worksheet) + { + foreach (var range in listsFormulas.Values) { - foreach (var range in listsFormulas.Values) - { - var fieldListRange = ListFormulaCanBeRangedByColumn - ? worksheet.Cells[range.RowStart, range.Column, range.RowEnd, range.Column] - : worksheet.Cells[range.RowStart, range.Column]; - var list = worksheet.DataValidations.AddListValidation(fieldListRange.Address); - list.Formula.ExcelFormula = range.Formula; - } + var fieldListRange = ListFormulaCanBeRangedByColumn + ? worksheet.Cells[range.RowStart, range.Column, range.RowEnd, range.Column] + : worksheet.Cells[range.RowStart, range.Column]; + var list = worksheet.DataValidations.AddListValidation(fieldListRange.Address); + list.Formula.ExcelFormula = range.Formula; } + } - protected ExcelRange AddCell(ExcelWorksheet worksheet, string text, int row, int column, bool isReadOnly = false, bool isGray = false, bool multiLine = false, string formula = null, Type numericFieldType = null, - bool isList = false) + protected ExcelRange AddCell(ExcelWorksheet worksheet, string text, int row, int column, bool isReadOnly = false, bool isGray = false, bool multiLine = false, string formula = null, Type numericFieldType = null, + bool isList = false) + { + ExcelRange cell = worksheet.Cells[row, column]; + cell.Value = text; + PredefinedCellStyle styleKey = PredefinedCellStyle.None; + if (isGray) + { + styleKey |= PredefinedCellStyle.Gray; + } + if (isList) { - ExcelRange cell = worksheet.Cells[row, column]; - cell.Value = text; - PredefinedCellStyle styleKey = PredefinedCellStyle.None; - if (isGray) + styleKey |= PredefinedCellStyle.List; + } + var hasFormula = !string.IsNullOrEmpty(formula); + if (hasFormula) + { + styleKey |= PredefinedCellStyle.Formula; + } + if (isList && hasFormula) + { + var cacheKey = ListFormulaCanBeRangedByColumn ? column : column + row; + ListFormulaRange formulaRange; + if (!listsFormulas.TryGetValue(cacheKey, out formulaRange)) { - styleKey |= PredefinedCellStyle.Gray; + formulaRange = new ListFormulaRange + { + Column = column, + RowStart = row, + RowEnd = row, + Formula = formula + }; + listsFormulas.Add(cacheKey, formulaRange); } - if (isList) + else if (ListFormulaCanBeRangedByColumn) { - styleKey |= PredefinedCellStyle.List; + formulaRange.RowEnd = row; } - var hasFormula = !string.IsNullOrEmpty(formula); - if (hasFormula) + } + else + { + if (multiLine) { - styleKey |= PredefinedCellStyle.Formula; + styleKey |= PredefinedCellStyle.MultiLine; } - if (isList && hasFormula) + if (hasFormula) { - var cacheKey = ListFormulaCanBeRangedByColumn ? column : column + row; - ListFormulaRange formulaRange; - if (!listsFormulas.TryGetValue(cacheKey, out formulaRange)) - { - formulaRange = new ListFormulaRange - { - Column = column, - RowStart = row, - RowEnd = row, - Formula = formula - }; - listsFormulas.Add(cacheKey, formulaRange); - } - else if (ListFormulaCanBeRangedByColumn) - { - formulaRange.RowEnd = row; - } + CellSetFormula(worksheet, cell, formula); } - else + + if (numericFieldType != null) { - if (multiLine) + if (numericFieldType == typeof(int)) { - styleKey |= PredefinedCellStyle.MultiLine; + styleKey |= PredefinedCellStyle.Integer; } - if (hasFormula) + else if (numericFieldType == typeof(double)) { - CellSetFormula(worksheet, cell, formula); + styleKey |= PredefinedCellStyle.Decimal; } - - if (numericFieldType != null) - { - if (numericFieldType == typeof(int)) - { - styleKey |= PredefinedCellStyle.Integer; - } - else if (numericFieldType == typeof(double)) - { - styleKey |= PredefinedCellStyle.Decimal; - } - } - } - if (isReadOnly) - { - styleKey |= PredefinedCellStyle.ReadOnly; } - var namedStyle = GetPredefinedCellStyle(worksheet, styleKey); - if (namedStyle != null) - { - cell.StyleName = namedStyle.Name; - } - return cell; } + if (isReadOnly) + { + styleKey |= PredefinedCellStyle.ReadOnly; + } + var namedStyle = GetPredefinedCellStyle(worksheet, styleKey); + if (namedStyle != null) + { + cell.StyleName = namedStyle.Name; + } + return cell; + } - private ExcelNamedStyleXml GetPredefinedCellStyle(ExcelWorksheet worksheet, PredefinedCellStyle styleKey) + private ExcelNamedStyleXml GetPredefinedCellStyle(ExcelWorksheet worksheet, PredefinedCellStyle styleKey) + { + ExcelNamedStyleXml namedStyle = null; + if (!predefinedCellStyles.TryGetValue(styleKey, out namedStyle)) { - ExcelNamedStyleXml namedStyle = null; - if (!predefinedCellStyles.TryGetValue(styleKey, out namedStyle)) + namedStyle = worksheet.Workbook.Styles.CreateNamedStyle(styleKey == PredefinedCellStyle.None ? "Cell" : $"Cell {styleKey ^ PredefinedCellStyle.None}"); + var style = namedStyle.Style; + if (styleKey.HasFlag(PredefinedCellStyle.Gray)) + { + style.Font.Color.SetColor(Color.Gray); + } + var isList = styleKey.HasFlag(PredefinedCellStyle.List); + var hasFormula = styleKey.HasFlag(PredefinedCellStyle.Formula); + if (!isList || !hasFormula) { - namedStyle = worksheet.Workbook.Styles.CreateNamedStyle(styleKey == PredefinedCellStyle.None ? "Cell" : $"Cell {styleKey ^ PredefinedCellStyle.None}"); - var style = namedStyle.Style; - if (styleKey.HasFlag(PredefinedCellStyle.Gray)) + if (styleKey.HasFlag(PredefinedCellStyle.MultiLine)) + { + style.WrapText = true; + } + style.VerticalAlignment = ExcelVerticalAlignment.Center; + if (styleKey.HasFlag(PredefinedCellStyle.Integer)) { - style.Font.Color.SetColor(Color.Gray); + style.Numberformat.Format = "0"; } - var isList = styleKey.HasFlag(PredefinedCellStyle.List); - var hasFormula = styleKey.HasFlag(PredefinedCellStyle.Formula); - if (!isList || !hasFormula) + else if (styleKey.HasFlag(PredefinedCellStyle.Decimal)) { - if (styleKey.HasFlag(PredefinedCellStyle.MultiLine)) - { - style.WrapText = true; - } - style.VerticalAlignment = ExcelVerticalAlignment.Center; - if (styleKey.HasFlag(PredefinedCellStyle.Integer)) - { - style.Numberformat.Format = "0"; - } - else if (styleKey.HasFlag(PredefinedCellStyle.Decimal)) - { - style.Numberformat.Format = "0.00"; - } + style.Numberformat.Format = "0.00"; } - style.Locked = styleKey.HasFlag(PredefinedCellStyle.ReadOnly); - predefinedCellStyles.Add(styleKey, namedStyle); } - return namedStyle; + style.Locked = styleKey.HasFlag(PredefinedCellStyle.ReadOnly); + predefinedCellStyles.Add(styleKey, namedStyle); } + return namedStyle; + } - private void CellSetFormula(ExcelWorksheet worksheet, ExcelRange cell, string formula) + private void CellSetFormula(ExcelWorksheet worksheet, ExcelRange cell, string formula) + { + if (!worksheet.Cells[formula].Style.Locked) { - if (!worksheet.Cells[formula].Style.Locked) - { - cell.AddComment("Link to Default language", CommentsAuthor); - } - cell.Formula = formula; + cell.AddComment("Link to Default language", CommentsAuthor); } + cell.Formula = formula; + } - protected ExcelRange AddCell(ExcelWorksheet worksheet, string text, int row, int column, ExcelNamedStyleXml style) - { - ExcelRange cell = worksheet.Cells[row, column]; - cell.Value = text; - cell.StyleName = style.Name; - return cell; - } + protected ExcelRange AddCell(ExcelWorksheet worksheet, string text, int row, int column, ExcelNamedStyleXml style) + { + ExcelRange cell = worksheet.Cells[row, column]; + cell.Value = text; + cell.StyleName = style.Name; + return cell; + } - private readonly Dictionary listRangeFormulas = new Dictionary(); + private readonly Dictionary listRangeFormulas = new Dictionary(); - protected string GetListRangeFormula(KeyValuePair> options, string languageId) - { - if (options.Value?.Any() != true) - return null; + protected string GetListRangeFormula(KeyValuePair> options, string languageId) + { + if (options.Value?.Any() != true) + return null; - var translatedOptions = ListFieldsHelper.GetTranslatedOptions(languageId, options); - if (translatedOptions.Count < 1) - return null; + var translatedOptions = ListFieldsHelper.GetTranslatedOptions(languageId, options); + if (translatedOptions.Count < 1) + return null; - string formula; - var cacheKey = string.Join("|", translatedOptions); - if (listRangeFormulas.TryGetValue(cacheKey, out formula)) - { - return formula; - } + string formula; + var cacheKey = string.Join("|", translatedOptions); + if (listRangeFormulas.TryGetValue(cacheKey, out formula)) + { + return formula; + } - var maxWorksheetRowsCount = 1048578; // Maximum rows amount per worksheet - int columnIndex = 1; - int startRow = LastHiddenListOptionsColumnRowIndex; - if (startRow + translatedOptions.Count > maxWorksheetRowsCount) - { - var workbook = ListOptionsWorksheet.Workbook; - var workbookName = ListOptionsWorksheet.Name; - var workbookNumber = Converter.ToInt32(workbookName.Substring(HiddenListOptionsWorksheetName.Length)) + 1; - CreateListOptionsWorksheet(workbook, HiddenListOptionsWorksheetName + workbookNumber.ToString()); - startRow = LastHiddenListOptionsColumnRowIndex; - } - foreach (var option in translatedOptions) - { - ListOptionsWorksheet.Cells[LastHiddenListOptionsColumnRowIndex++, columnIndex].Value = option; - } + var maxWorksheetRowsCount = 1048578; // Maximum rows amount per worksheet + int columnIndex = 1; + int startRow = LastHiddenListOptionsColumnRowIndex; + if (startRow + translatedOptions.Count > maxWorksheetRowsCount) + { + var workbook = ListOptionsWorksheet.Workbook; + var workbookName = ListOptionsWorksheet.Name; + var workbookNumber = Converter.ToInt32(workbookName.Substring(HiddenListOptionsWorksheetName.Length)) + 1; + CreateListOptionsWorksheet(workbook, HiddenListOptionsWorksheetName + workbookNumber.ToString()); + startRow = LastHiddenListOptionsColumnRowIndex; + } + foreach (var option in translatedOptions) + { + ListOptionsWorksheet.Cells[LastHiddenListOptionsColumnRowIndex++, columnIndex].Value = option; + } - string column = ListOptionsWorksheet.GetColumnName(columnIndex); - formula = $"{ListOptionsWorksheet.Name}!${column}${startRow}:${column}${LastHiddenListOptionsColumnRowIndex - 1}"; - listRangeFormulas[cacheKey] = formula; + string column = ListOptionsWorksheet.GetColumnName(columnIndex); + formula = $"{ListOptionsWorksheet.Name}!${column}${startRow}:${column}${LastHiddenListOptionsColumnRowIndex - 1}"; + listRangeFormulas[cacheKey] = formula; - return formula; - } + return formula; + } - protected int GetMaxLineCount(int maxLineCount, string fieldValue) + protected int GetMaxLineCount(int maxLineCount, string fieldValue) + { + int lineCount = GetLineCount(fieldValue, 60); + if (lineCount > maxLineCount) { - int lineCount = GetLineCount(fieldValue, 60); - if (lineCount > maxLineCount) - { - maxLineCount = lineCount; - } - return maxLineCount; + maxLineCount = lineCount; } + return maxLineCount; + } - protected int AddFieldValueCell(ExcelWorksheet worksheet, bool extractFieldValue, string field, string languageId, Dictionary languageIdProductDictionary, - bool isVariantProduct, bool isList, bool multipleSelectionList, KeyValuePair> options, string formula, - int rowIndex, ref int lastColumnIndex, Type numericFieldType, bool multiLine, int maxLineCount) + protected int AddFieldValueCell(ExcelWorksheet worksheet, bool extractFieldValue, string field, string languageId, Dictionary languageIdProductDictionary, + bool isVariantProduct, bool isList, bool multipleSelectionList, KeyValuePair> options, string formula, + int rowIndex, ref int lastColumnIndex, Type numericFieldType, bool multiLine, int maxLineCount) + { + string fieldValue = null; + bool isEnabled = false; + bool isInherited = false; + if (extractFieldValue) { - string fieldValue = null; - bool isEnabled = false; - bool isInherited = false; - if (extractFieldValue) + Product languageProduct = null; + if (languageIdProductDictionary.ContainsKey(languageId)) { - Product languageProduct = null; - if (languageIdProductDictionary.ContainsKey(languageId)) - { - languageProduct = languageIdProductDictionary[languageId]; - } - Field categoryField = FieldsHelper.GetCategoryField(field, languageId); - if (categoryField != null) + languageProduct = languageIdProductDictionary[languageId]; + } + Field categoryField = FieldsHelper.GetCategoryField(field, languageId); + if (categoryField != null) + { + isInherited = FieldsHelper.IsCategoryFieldInherited(categoryField, isVariantProduct, languageId); + isEnabled = !FieldsHelper.IsCategoryFieldReadOnly(categoryField); + if (languageProduct != null) { - isInherited = FieldsHelper.IsCategoryFieldInherited(categoryField, isVariantProduct, languageId); - isEnabled = !FieldsHelper.IsCategoryFieldReadOnly(categoryField); - if (languageProduct != null) - { - fieldValue = Converter.ToString(FieldsHelper.GetCategoryFieldValue(languageProduct, categoryField)); - } - else - { - fieldValue = categoryField.DefaultValue; - } - if (isList && !string.IsNullOrEmpty(fieldValue)) - { - fieldValue = ListFieldsHelper.GetFieldOptionValue(fieldValue, options, multipleSelectionList, languageId); - } + fieldValue = Converter.ToString(FieldsHelper.GetCategoryFieldValue(languageProduct, categoryField)); } else { - isInherited = FieldsHelper.IsFieldInherited(field, isVariantProduct, languageId); - isEnabled = !FieldsHelper.IsFieldReadOnly(field); - fieldValue = null; - if (languageProduct != null) - { - fieldValue = GetFieldValue(languageProduct, field, options, multipleSelectionList, languageId); - } + fieldValue = categoryField.DefaultValue; } - if (isEnabled && isList) + if (isList && !string.IsNullOrEmpty(fieldValue)) { - formula = GetListRangeFormula(options, languageId); + fieldValue = ListFieldsHelper.GetFieldOptionValue(fieldValue, options, multipleSelectionList, languageId); } - formula = isInherited ? formula : (isList ? formula : null); } else { - if (isList) + isInherited = FieldsHelper.IsFieldInherited(field, isVariantProduct, languageId); + isEnabled = !FieldsHelper.IsFieldReadOnly(field); + fieldValue = null; + if (languageProduct != null) { - formula = GetListRangeFormula(options, languageId); + fieldValue = GetFieldValue(languageProduct, field, options, multipleSelectionList, languageId); } } + if (isEnabled && isList) + { + formula = GetListRangeFormula(options, languageId); + } + formula = isInherited ? formula : (isList ? formula : null); + } + else + { + if (isList) + { + formula = GetListRangeFormula(options, languageId); + } + } - AddCell(worksheet, fieldValue, rowIndex, lastColumnIndex++, !isEnabled, !isEnabled, multiLine, formula, numericFieldType, isList); + AddCell(worksheet, fieldValue, rowIndex, lastColumnIndex++, !isEnabled, !isEnabled, multiLine, formula, numericFieldType, isList); - return GetMaxLineCount(maxLineCount, fieldValue); - } + return GetMaxLineCount(maxLineCount, fieldValue); + } + + protected void InitializeStyles(ExcelWorksheet worksheet) + { + LockedGrayStyle = worksheet.Workbook.Styles.CreateNamedStyle("LockedGrayStyle"); + LockedGrayStyle.Style.Locked = true; + LockedGrayStyle.Style.Font.Color.SetColor(Color.Gray); + LockedGrayStyle.Style.VerticalAlignment = ExcelVerticalAlignment.Center; + } - protected void InitializeStyles(ExcelWorksheet worksheet) + protected void AddNumericValidation(ExcelRange cells, Type numericFieldType) + { + if (numericFieldType == typeof(int)) { - LockedGrayStyle = worksheet.Workbook.Styles.CreateNamedStyle("LockedGrayStyle"); - LockedGrayStyle.Style.Locked = true; - LockedGrayStyle.Style.Font.Color.SetColor(Color.Gray); - LockedGrayStyle.Style.VerticalAlignment = ExcelVerticalAlignment.Center; + var validation = cells.DataValidation.AddIntegerDataValidation(); + validation.AllowBlank = true; + validation.ErrorStyle = OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle.stop; + validation.PromptTitle = "Note"; + validation.Prompt = "Enter an integer value here"; + validation.ShowInputMessage = true; + validation.Error = "An invalid value was entered"; + validation.ShowErrorMessage = true; + validation.Operator = OfficeOpenXml.DataValidation.ExcelDataValidationOperator.between; + validation.Formula.Value = int.MinValue; + validation.Formula2.Value = int.MaxValue; } - - protected void AddNumericValidation(ExcelRange cells, Type numericFieldType) + else if (numericFieldType == typeof(double)) { - if (numericFieldType == typeof(int)) - { - var validation = cells.DataValidation.AddIntegerDataValidation(); - validation.AllowBlank = true; - validation.ErrorStyle = OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle.stop; - validation.PromptTitle = "Note"; - validation.Prompt = "Enter an integer value here"; - validation.ShowInputMessage = true; - validation.Error = "An invalid value was entered"; - validation.ShowErrorMessage = true; - validation.Operator = OfficeOpenXml.DataValidation.ExcelDataValidationOperator.between; - validation.Formula.Value = int.MinValue; - validation.Formula2.Value = int.MaxValue; - } - else if (numericFieldType == typeof(double)) - { - var validation = cells.DataValidation.AddDecimalDataValidation(); - validation.AllowBlank = true; - validation.ErrorStyle = OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle.stop; - validation.PromptTitle = "Note"; - validation.Prompt = "Enter double value here"; - validation.ShowInputMessage = true; - validation.Error = "An invalid value was entered"; - validation.ShowErrorMessage = true; - validation.Operator = OfficeOpenXml.DataValidation.ExcelDataValidationOperator.between; - validation.Formula.Value = (double)decimal.MinValue; - validation.Formula2.Value = (double)decimal.MaxValue; - } + var validation = cells.DataValidation.AddDecimalDataValidation(); + validation.AllowBlank = true; + validation.ErrorStyle = OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle.stop; + validation.PromptTitle = "Note"; + validation.Prompt = "Enter double value here"; + validation.ShowInputMessage = true; + validation.Error = "An invalid value was entered"; + validation.ShowErrorMessage = true; + validation.Operator = OfficeOpenXml.DataValidation.ExcelDataValidationOperator.between; + validation.Formula.Value = (double)decimal.MinValue; + validation.Formula2.Value = (double)decimal.MaxValue; } } -} +} \ No newline at end of file diff --git a/src/PIM/BaseImportExcelProvider.cs b/src/PIM/BaseImportExcelProvider.cs index 804eac6..d1b6c5a 100644 --- a/src/PIM/BaseImportExcelProvider.cs +++ b/src/PIM/BaseImportExcelProvider.cs @@ -1,550 +1,544 @@ -using Dynamicweb.Configuration; -using Dynamicweb.Content; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Dynamicweb.Configuration; using Dynamicweb.Core; -using Dynamicweb.Ecommerce.Common; +using Dynamicweb.Ecommerce; using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; using Dynamicweb.Ecommerce.Products.Categories; using Dynamicweb.Ecommerce.Variants; using OfficeOpenXml; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +internal abstract class BaseImportExcelProvider : IImportExcelProvider, IDisposable { - internal abstract class BaseImportExcelProvider : IImportExcelProvider, IDisposable - { - protected ExcelPackage ExcelPackage = null; - private Dictionary _numericFields = null; - - protected LanguageService LanguageService = new LanguageService(); - protected VariantCombinationService VariantCombinationService = new VariantCombinationService(); - protected ProductService ProductService = new ProductService(); - protected FieldsHelper FieldsHelper = new FieldsHelper(); - protected readonly int ListTypeId = 15; - - protected abstract VariantCombination GetSimpleVariantFromExcel(Product mainProduct, string variantId, bool isNewVariantLanguageProduct); - protected abstract IEnumerable GetSimpleVariantsFromExcel(Product mainProduct); - - public abstract string GetProductId(); - public abstract IEnumerable GetLanguages(); - public abstract IEnumerable GetFields(); - public abstract IEnumerable GetInvalidFields(string languageId); - public abstract Dictionary> GetSimpleVariants(IEnumerable languages); - public abstract bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status); - public virtual bool LoadExcel(byte[] excelData) - { - bool isLoaded = true; - ExcelPackage.LicenseContext = LicenseContext.Commercial; - using (MemoryStream ms = new MemoryStream(excelData)) - { - try - { - ExcelPackage = new ExcelPackage(ms); - } - catch - { - isLoaded = false; - } + protected ExcelPackage ExcelPackage = null; + private Dictionary _numericFields = null; + protected FieldsHelper FieldsHelper = new FieldsHelper(); + protected readonly int ListTypeId = 15; + + protected abstract VariantCombination GetSimpleVariantFromExcel(Product mainProduct, string variantId, bool isNewVariantLanguageProduct); + protected abstract IEnumerable GetSimpleVariantsFromExcel(Product mainProduct); + + public abstract string GetProductId(); + public abstract IEnumerable GetLanguages(); + public abstract IEnumerable GetFields(); + public abstract IEnumerable GetInvalidFields(string languageId); + public abstract Dictionary> GetSimpleVariants(IEnumerable languages); + public abstract bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status); + public virtual bool LoadExcel(byte[] excelData) + { + bool isLoaded = true; + ExcelPackage.LicenseContext = LicenseContext.Commercial; + using (MemoryStream ms = new MemoryStream(excelData)) + { + try + { + ExcelPackage = new ExcelPackage(ms); + } + catch + { + isLoaded = false; } - return isLoaded; } + return isLoaded; + } - protected Dictionary NumericFields + protected Dictionary NumericFields + { + get { - get + if (_numericFields == null) { - if (_numericFields == null) + _numericFields = new Dictionary(); + foreach (string field in GetFields()) { - _numericFields = new Dictionary(); - foreach (string field in GetFields()) + if (!_numericFields.ContainsKey(field)) { - if (!_numericFields.ContainsKey(field)) + Type fieldType = FieldsHelper.GetNumericFieldType(field); + if (fieldType != null) { - Type fieldType = FieldsHelper.GetNumericFieldType(field); - if (fieldType != null) - { - _numericFields.Add(field, fieldType); - } + _numericFields.Add(field, fieldType); } } - } - return _numericFields; + } + return _numericFields; } + } - protected ExcelWorksheet Worksheet + protected ExcelWorksheet Worksheet + { + get { - get + if (ExcelPackage?.Workbook?.Worksheets.Count > 0) { - if (ExcelPackage?.Workbook?.Worksheets.Count > 0) - { - return ExcelPackage.Workbook.Worksheets.FirstOrDefault(); - } - else - { - return null; - } + return ExcelPackage.Workbook.Worksheets.FirstOrDefault(); } + else + { + return null; + } + } + } + + public void Dispose() + { + if (ExcelPackage != null) + { + ExcelPackage.Dispose(); } + } - public void Dispose() + protected bool IsProductFieldChanged(Product product, string field, string fieldValue, string fieldValueLanguageId) + { + bool isChanged = false; + ProductField customField = FieldsHelper.GetCustomField(field); + if (customField != null) { - if (ExcelPackage != null) + if (!string.IsNullOrEmpty(fieldValue) && customField.TypeId == ListTypeId) { - ExcelPackage.Dispose(); + fieldValue = GetListSelectedOptionValueByName(fieldValue, customField, fieldValueLanguageId); } - } - - protected bool IsProductFieldChanged(Product product, string field, string fieldValue, string fieldValueLanguageId) + if (!IsFieldValueEqual(product.ProductFieldValues?.GetProductFieldValue(field)?.Value, fieldValue)) + { + Services.Products.SetProductFieldValue(product, field, fieldValue); + isChanged = true; + } + } + else { - bool isChanged = false; - ProductField customField = FieldsHelper.GetCustomField(field); - if (customField != null) + var categoryField = FieldsHelper.GetCategoryField(field); + if (categoryField != null) { - if (!string.IsNullOrEmpty(fieldValue) && customField.TypeId == ListTypeId) - { - fieldValue = GetListSelectedOptionValueByName(fieldValue, customField, fieldValueLanguageId); + if(!string.IsNullOrEmpty(fieldValue) && categoryField.Type == ListTypeId.ToString()) + { + fieldValue = GetListSelectedOptionValueByName(field, fieldValue, categoryField, fieldValueLanguageId); } - if (!IsFieldValueEqual(product.ProductFieldValues?.GetProductFieldValue(field)?.Value, fieldValue)) + if (!IsFieldValueEqual(product.GetCategoryValue(categoryField.Category.Id, categoryField.Id, true), fieldValue)) { - ProductService.SetProductFieldValue(product, field, fieldValue); + product.SetCategoryValue(categoryField.Category.Id, categoryField, fieldValue); isChanged = true; } } else { - var categoryField = FieldsHelper.GetCategoryField(field); - if (categoryField != null) - { - if(!string.IsNullOrEmpty(fieldValue) && categoryField.Type == ListTypeId.ToString()) - { - fieldValue = GetListSelectedOptionValueByName(field, fieldValue, categoryField, fieldValueLanguageId); - } - if (!IsFieldValueEqual(product.GetCategoryValue(categoryField.Category.Id, categoryField.Id, true), fieldValue)) - { - product.SetCategoryValue(categoryField.Category.Id, categoryField, fieldValue); - isChanged = true; - } - } - else + if (FieldsHelper.SetStandardFieldValue(product, field, fieldValue)) { - if (FieldsHelper.SetStandardFieldValue(product, field, fieldValue)) - { - isChanged = true; - } + isChanged = true; } } - return isChanged; } + return isChanged; + } - protected bool IsFieldChangeAllowed(Language language, string field) + protected bool IsFieldChangeAllowed(Language language, string field) + { + bool result = language.IsDefault; + if (!result) { - bool result = language.IsDefault; - if (!result) + if (FieldsHelper.IsCustomField(field)) { - if (FieldsHelper.IsCustomField(field)) + result = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(FieldsHelper.GetFieldCheckSettingKeyFor(field, + FieldDifferentiationSection.ProductFields, FieldDifferentiationType.Language))); + } + else + { + FieldDifferentiationSection section = FieldsHelper.GetFieldSection(field); + if (section == FieldDifferentiationSection.ProductCategories) { - result = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(FieldsHelper.GetFieldCheckSettingKeyFor(field, - FieldDifferentiationSection.ProductFields, FieldDifferentiationType.Language))); + Field categoryField = FieldsHelper.GetCategoryField(field); + result = categoryField != null ? Converter.ToBoolean(SystemConfiguration.Instance.GetValue(FieldsHelper.GetFieldCheckSettingKeyFor(categoryField.Category.Id + "." + categoryField.Id, + FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.Language))) : false; } else { - FieldDifferentiationSection section = FieldsHelper.GetFieldSection(field); - if (section == FieldDifferentiationSection.ProductCategories) - { - Field categoryField = FieldsHelper.GetCategoryField(field); - result = categoryField != null ? Converter.ToBoolean(SystemConfiguration.Instance.GetValue(FieldsHelper.GetFieldCheckSettingKeyFor(categoryField.Category.Id + "." + categoryField.Id, - FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.Language))) : false; - } - else - { - result = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(FieldsHelper.GetFieldCheckSettingKeyFor(field, - FieldDifferentiationSection.CommonFields, FieldDifferentiationType.Language))); - } + result = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(FieldsHelper.GetFieldCheckSettingKeyFor(field, + FieldDifferentiationSection.CommonFields, FieldDifferentiationType.Language))); } } - return result; } + return result; + } - protected bool TryGetFieldLanguageValue(Dictionary> fieldLanguageIdValues, string languageId, string field, out string fieldValue) + protected bool TryGetFieldLanguageValue(Dictionary> fieldLanguageIdValues, string languageId, string field, out string fieldValue) + { + fieldValue = null; + foreach (string fieldLanguageId in fieldLanguageIdValues[field].Keys) { - fieldValue = null; - foreach (string fieldLanguageId in fieldLanguageIdValues[field].Keys) + if (string.Equals(fieldLanguageId, languageId, StringComparison.InvariantCultureIgnoreCase)) { - if (string.Equals(fieldLanguageId, languageId, StringComparison.InvariantCultureIgnoreCase)) - { - fieldValue = fieldLanguageIdValues[field][languageId].Text; - return true; - } + fieldValue = fieldLanguageIdValues[field][languageId].Text; + return true; } - return false; } + return false; + } - //check if any product extended variants have old value which needs to be updated due to main product changes - protected void UpdateExtendedVariantsForMainProductFieldsChanges(Product product, Language language, Dictionary> fieldLanguageIdValues, - IEnumerable languages) + //check if any product extended variants have old value which needs to be updated due to main product changes + protected void UpdateExtendedVariantsForMainProductFieldsChanges(Product product, Language language, Dictionary> fieldLanguageIdValues, + IEnumerable languages) + { + foreach (VariantCombination variantCombination in Services.VariantCombinations.GetVariantCombinations(product.Id).Where(vc => vc.HasRowInProductTable)) { - foreach (VariantCombination variantCombination in VariantCombinationService.GetVariantCombinations(product.Id).Where(vc => vc.HasRowInProductTable)) + Product variantProduct = Services.Products.GetProductById(variantCombination.ProductId, variantCombination.VariantId, language.LanguageId); + string fieldValue = null; + bool isChanged = false; + foreach (string field in fieldLanguageIdValues.Keys.Where(f => !FieldsHelper.IsVariantEditingAllowed(f))) { - Product variantProduct = ProductService.GetProductById(variantCombination.ProductId, variantCombination.VariantId, language.LanguageId); - string fieldValue = null; - bool isChanged = false; - foreach (string field in fieldLanguageIdValues.Keys.Where(f => !FieldsHelper.IsVariantEditingAllowed(f))) + if (TryGetFieldLanguageValue(fieldLanguageIdValues, language.LanguageId, field, out fieldValue) + && IsFieldChangeAllowed(language, field) + && IsProductFieldChanged(variantProduct, field, fieldValue, language.LanguageId)) { - if (TryGetFieldLanguageValue(fieldLanguageIdValues, language.LanguageId, field, out fieldValue) - && IsFieldChangeAllowed(language, field) - && IsProductFieldChanged(variantProduct, field, fieldValue, language.LanguageId)) - { - isChanged = true; - } + isChanged = true; } + } - if (isChanged) - { - variantProduct.Updated = DateTime.Now; - ProductService.SaveAndConfirm(variantProduct, variantProduct.Id, variantProduct.VariantId, variantProduct.LanguageId, true); - } + if (isChanged) + { + variantProduct.Updated = DateTime.Now; + Services.Products.SaveAndConfirm(variantProduct, variantProduct.Id, variantProduct.VariantId, variantProduct.LanguageId, true); } } + } - //Auto creates extended variants due to main product changes (all product simple variants became extended) - protected void CreateExtendedVariantsForMainProductFieldsChanges(Product product, Language language, Dictionary> fieldLanguageIdValues, - Dictionary> failedVariants) + //Auto creates extended variants due to main product changes (all product simple variants became extended) + protected void CreateExtendedVariantsForMainProductFieldsChanges(Product product, Language language, Dictionary> fieldLanguageIdValues, + Dictionary> failedVariants) + { + foreach (VariantCombination variantCombination in Services.VariantCombinations.GetVariantCombinations(product.Id).Where(vc => !vc.HasRowInProductTable)) { - foreach (VariantCombination variantCombination in VariantCombinationService.GetVariantCombinations(product.Id).Where(vc => !vc.HasRowInProductTable)) + Product variantProduct = Services.Products.GetProductById(variantCombination.ProductId, variantCombination.VariantId, language.LanguageId); + bool isNewVariantLanguageProduct = variantProduct != null && string.IsNullOrWhiteSpace(variantProduct.VariantId) && !string.IsNullOrWhiteSpace(variantProduct.VirtualVariantId); + if (isNewVariantLanguageProduct && failedVariants.ContainsKey(language.LanguageId) + && failedVariants[language.LanguageId].Any(vc => string.Equals(vc.VariantId, variantProduct.VirtualVariantId, StringComparison.InvariantCultureIgnoreCase))) { - Product variantProduct = ProductService.GetProductById(variantCombination.ProductId, variantCombination.VariantId, language.LanguageId); - bool isNewVariantLanguageProduct = variantProduct != null && string.IsNullOrWhiteSpace(variantProduct.VariantId) && !string.IsNullOrWhiteSpace(variantProduct.VirtualVariantId); - if (isNewVariantLanguageProduct && failedVariants.ContainsKey(language.LanguageId) - && failedVariants[language.LanguageId].Any(vc => string.Equals(vc.VariantId, variantProduct.VirtualVariantId, StringComparison.InvariantCultureIgnoreCase))) + string variantId = variantProduct.VirtualVariantId; + if (variantProduct.LanguageId != language.LanguageId) { - string variantId = variantProduct.VirtualVariantId; - if (variantProduct.LanguageId != language.LanguageId) - { - variantProduct = ProductService.Clone(product); - } - variantProduct.VariantId = variantId; - variantProduct.LanguageId = language.LanguageId; - - variantProduct.Updated = DateTime.Now; - ProductService.SaveAndConfirm(variantProduct, variantProduct.Id, variantProduct.VariantId, variantProduct.LanguageId, true); + variantProduct = Services.Products.Clone(product); } + variantProduct.VariantId = variantId; + variantProduct.LanguageId = language.LanguageId; + + variantProduct.Updated = DateTime.Now; + Services.Products.SaveAndConfirm(variantProduct, variantProduct.Id, variantProduct.VariantId, variantProduct.LanguageId, true); } } + } - protected Dictionary> GetInvalidVariantsFromProduct(string productId, string variantId, IEnumerable languages, Dictionary> fieldLanguageIdValues) + protected Dictionary> GetInvalidVariantsFromProduct(string productId, string variantId, IEnumerable languages, Dictionary> fieldLanguageIdValues) + { + var simpleVariantsWhereVariantEditingIsNotAllowed = new Dictionary>(); + + foreach (Language language in languages.OrderByDescending(lang => lang.IsDefault)) { - var simpleVariantsWhereVariantEditingIsNotAllowed = new Dictionary>(); + Product languageProduct = Services.Products.GetProductById(productId, variantId, language.LanguageId); - foreach (Language language in languages.OrderByDescending(lang => lang.IsDefault)) - { - Product languageProduct = ProductService.GetProductById(productId, variantId, language.LanguageId); + bool isNewVariantLanguageProduct = languageProduct != null && string.IsNullOrWhiteSpace(languageProduct.VariantId) && !string.IsNullOrWhiteSpace(languageProduct.VirtualVariantId); - bool isNewVariantLanguageProduct = languageProduct != null && string.IsNullOrWhiteSpace(languageProduct.VariantId) && !string.IsNullOrWhiteSpace(languageProduct.VirtualVariantId); + bool newProductValues = FieldHasAnyValue(language.LanguageId, fieldLanguageIdValues); - bool newProductValues = FieldHasAnyValue(language.LanguageId, fieldLanguageIdValues); + if (isNewVariantLanguageProduct && !newProductValues) + { + //no values set in any field for a product in this language - nothing to check + continue; + } + if (languageProduct != null) + { + string fieldValue = null; + bool valueExists = false; - if (isNewVariantLanguageProduct && !newProductValues) + foreach (string field in fieldLanguageIdValues.Keys) { - //no values set in any field for a product in this language - nothing to check - continue; - } - if (languageProduct != null) - { - string fieldValue = null; - bool valueExists = false; - - foreach (string field in fieldLanguageIdValues.Keys) + foreach (string languageId in fieldLanguageIdValues[field].Keys) + { + if (string.Equals(language.LanguageId, languageId, StringComparison.InvariantCultureIgnoreCase)) + { + fieldValue = fieldLanguageIdValues[field][languageId].Text; + valueExists = true; + break; + } + } + if (valueExists) { - foreach (string languageId in fieldLanguageIdValues[field].Keys) + if (FieldsHelper.IsCustomField(field)) { - if (string.Equals(language.LanguageId, languageId, StringComparison.InvariantCultureIgnoreCase)) + if (!IsFieldValueEqual(languageProduct.ProductFieldValues?.GetProductFieldValue(field)?.Value, fieldValue)) { - fieldValue = fieldLanguageIdValues[field][languageId].Text; - valueExists = true; - break; + ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref simpleVariantsWhereVariantEditingIsNotAllowed, + languageProduct, variantId, FieldsHelper.IsVariantEditingAllowed(field), language.LanguageId, isNewVariantLanguageProduct); } } - if (valueExists) + else { - if (FieldsHelper.IsCustomField(field)) + var categoryField = FieldsHelper.GetCategoryField(field); + if (categoryField != null) { - if (!IsFieldValueEqual(languageProduct.ProductFieldValues?.GetProductFieldValue(field)?.Value, fieldValue)) + if (!IsFieldValueEqual(languageProduct.GetCategoryValue(categoryField.Category.Id, categoryField.Id, true), fieldValue)) { ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref simpleVariantsWhereVariantEditingIsNotAllowed, - languageProduct, variantId, FieldsHelper.IsVariantEditingAllowed(field), language.LanguageId, isNewVariantLanguageProduct); + languageProduct, variantId, FieldsHelper.IsCategoryFieldVariantEditingAllowed(categoryField), language.LanguageId, isNewVariantLanguageProduct); } } else { - var categoryField = FieldsHelper.GetCategoryField(field); - if (categoryField != null) + if (!IsFieldValueEqual(FieldsHelper.GetStandardFieldValue(languageProduct, field), fieldValue)) { - if (!IsFieldValueEqual(languageProduct.GetCategoryValue(categoryField.Category.Id, categoryField.Id, true), fieldValue)) - { - ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref simpleVariantsWhereVariantEditingIsNotAllowed, - languageProduct, variantId, FieldsHelper.IsCategoryFieldVariantEditingAllowed(categoryField), language.LanguageId, isNewVariantLanguageProduct); - } - } - else - { - if (!IsFieldValueEqual(FieldsHelper.GetStandardFieldValue(languageProduct, field), fieldValue)) - { - ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref simpleVariantsWhereVariantEditingIsNotAllowed, - languageProduct, variantId, FieldsHelper.IsVariantEditingAllowed(field), language.LanguageId, isNewVariantLanguageProduct); - } + ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref simpleVariantsWhereVariantEditingIsNotAllowed, + languageProduct, variantId, FieldsHelper.IsVariantEditingAllowed(field), language.LanguageId, isNewVariantLanguageProduct); } } } - if (simpleVariantsWhereVariantEditingIsNotAllowed.ContainsKey(language.LanguageId) && - simpleVariantsWhereVariantEditingIsNotAllowed[language.LanguageId].Any(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase))) - { - break; - } + } + if (simpleVariantsWhereVariantEditingIsNotAllowed.ContainsKey(language.LanguageId) && + simpleVariantsWhereVariantEditingIsNotAllowed[language.LanguageId].Any(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase))) + { + break; } } } - return simpleVariantsWhereVariantEditingIsNotAllowed; } + return simpleVariantsWhereVariantEditingIsNotAllowed; + } - protected void ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref Dictionary> result, Product product, string variantId, bool isVariantEditingAllowed, - string languageId, bool isNewVariantLanguageProduct) + protected void ProcessSimpleVariantsWhereVariantEditingIsNotAllowed(ref Dictionary> result, Product product, string variantId, bool isVariantEditingAllowed, + string languageId, bool isNewVariantLanguageProduct) + { + if (string.IsNullOrEmpty(variantId)) { - if (string.IsNullOrEmpty(variantId)) + if (!isVariantEditingAllowed && !Services.VariantCombinations.GetVariantCombinations(product.Id).All(vc => !vc.HasRowInProductTable)) { - if (!isVariantEditingAllowed && !VariantCombinationService.GetVariantCombinations(product.Id).All(vc => !vc.HasRowInProductTable)) + foreach (var combination in GetSimpleVariantsFromExcel(product)) { - foreach (var combination in GetSimpleVariantsFromExcel(product)) + if (!result.ContainsKey(product.LanguageId)) { - if (!result.ContainsKey(product.LanguageId)) - { - result.Add(product.LanguageId, new List()); - } - result[product.LanguageId].Add(combination); + result.Add(product.LanguageId, new List()); } + result[product.LanguageId].Add(combination); } } - else + } + else + { + var variant = GetSimpleVariantFromExcel(product, variantId, isNewVariantLanguageProduct); + if (variant != null) { - var variant = GetSimpleVariantFromExcel(product, variantId, isNewVariantLanguageProduct); - if (variant != null) + string realLanguageId = product.LanguageId; + if (isNewVariantLanguageProduct && !string.Equals(product.LanguageId, languageId, StringComparison.InvariantCultureIgnoreCase)) { - string realLanguageId = product.LanguageId; - if (isNewVariantLanguageProduct && !string.Equals(product.LanguageId, languageId, StringComparison.InvariantCultureIgnoreCase)) - { - realLanguageId = languageId; - } - if (!result.ContainsKey(realLanguageId)) - { - result.Add(realLanguageId, new List()); - } - result[realLanguageId].Add(variant); + realLanguageId = languageId; + } + if (!result.ContainsKey(realLanguageId)) + { + result.Add(realLanguageId, new List()); } + result[realLanguageId].Add(variant); } - } + } + } - protected bool FieldHasAnyValue(string language, Dictionary> fieldLanguageIdValues) + protected bool FieldHasAnyValue(string language, Dictionary> fieldLanguageIdValues) + { + foreach (string field in fieldLanguageIdValues.Keys) { - foreach (string field in fieldLanguageIdValues.Keys) + foreach (string languageId in fieldLanguageIdValues[field].Keys) { - foreach (string languageId in fieldLanguageIdValues[field].Keys) + if (string.Equals(language, languageId, StringComparison.InvariantCultureIgnoreCase)) { - if (string.Equals(language, languageId, StringComparison.InvariantCultureIgnoreCase)) - { - if (!fieldLanguageIdValues[field][languageId].IsFormula && !string.IsNullOrEmpty(fieldLanguageIdValues[field][languageId].Text)) - return true; - } + if (!fieldLanguageIdValues[field][languageId].IsFormula && !string.IsNullOrEmpty(fieldLanguageIdValues[field][languageId].Text)) + return true; } } - return false; - } + } + return false; + } - protected bool IsFieldValueEqual(object dbFieldValue, string excelFieldValue) + protected bool IsFieldValueEqual(object dbFieldValue, string excelFieldValue) + { + bool isEqual = false; + if ((dbFieldValue == null || dbFieldValue == DBNull.Value) && string.IsNullOrEmpty(excelFieldValue)) { - bool isEqual = false; - if ((dbFieldValue == null || dbFieldValue == DBNull.Value) && string.IsNullOrEmpty(excelFieldValue)) - { - isEqual = true; - } - else + isEqual = true; + } + else + { + if (dbFieldValue != null && dbFieldValue != DBNull.Value) { - if (dbFieldValue != null && dbFieldValue != DBNull.Value) + if (dbFieldValue.GetType() == typeof(string)) { - if (dbFieldValue.GetType() == typeof(string)) + if (string.IsNullOrEmpty((string)dbFieldValue) && string.IsNullOrEmpty(excelFieldValue)) { - if (string.IsNullOrEmpty((string)dbFieldValue) && string.IsNullOrEmpty(excelFieldValue)) - { - isEqual = true; - } - else - { - isEqual = Equals(dbFieldValue, excelFieldValue); - } + isEqual = true; } - if (dbFieldValue.GetType() == typeof(double) || dbFieldValue.GetType() == typeof(int)) + else { - if (dbFieldValue.ToString() == "0" && string.IsNullOrEmpty(excelFieldValue)) - { - isEqual = true; - } - else - { - isEqual = string.Equals(dbFieldValue.ToString(), excelFieldValue); - } + isEqual = Equals(dbFieldValue, excelFieldValue); + } + } + if (dbFieldValue.GetType() == typeof(double) || dbFieldValue.GetType() == typeof(int)) + { + if (dbFieldValue.ToString() == "0" && string.IsNullOrEmpty(excelFieldValue)) + { + isEqual = true; + } + else + { + isEqual = string.Equals(dbFieldValue.ToString(), excelFieldValue); } } } - return isEqual; } + return isEqual; + } - protected void UpdateProduct(string productId, string variantId, IEnumerable languages, Dictionary> fieldLanguageIdValues, - bool autoCreateExtendedVariants, Dictionary> failedVariants) + protected void UpdateProduct(string productId, string variantId, IEnumerable languages, Dictionary> fieldLanguageIdValues, + bool autoCreateExtendedVariants, Dictionary> failedVariants) + { + var product = Services.Products.GetProductById(productId, variantId, false); + var productExistInDefaultLang = false; + foreach (Language language in languages.OrderByDescending(lang => lang.IsDefault)) { - var product = ProductService.GetProductById(productId, variantId, false); - var productExistInDefaultLang = false; - foreach (Language language in languages.OrderByDescending(lang => lang.IsDefault)) + if (!autoCreateExtendedVariants && (failedVariants.ContainsKey(language.LanguageId) + && failedVariants[language.LanguageId].Any(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)))) { - if (!autoCreateExtendedVariants && (failedVariants.ContainsKey(language.LanguageId) - && failedVariants[language.LanguageId].Any(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)))) - { - continue; - } - if (!string.IsNullOrEmpty(variantId) && Context.Current != null && Context.Current.Items != null && - Context.Current.Items.Contains($"{productId}_{variantId}_{language.LanguageId}")) - { - //clear cached product to take the latest from database - Context.Current.Items.Remove($"{productId}_{variantId}_{language.LanguageId}"); - } - Product languageProduct = ProductService.GetProductById(productId, variantId, language.LanguageId); + continue; + } + if (!string.IsNullOrEmpty(variantId) && Context.Current != null && Context.Current.Items != null && + Context.Current.Items.Contains($"{productId}_{variantId}_{language.LanguageId}")) + { + //clear cached product to take the latest from database + Context.Current.Items.Remove($"{productId}_{variantId}_{language.LanguageId}"); + } + Product languageProduct = Services.Products.GetProductById(productId, variantId, language.LanguageId); - if (language.IsDefault) - { - productExistInDefaultLang = true; - } + if (language.IsDefault) + { + productExistInDefaultLang = true; + } - bool isNewlanguageProduct = false; + bool isNewlanguageProduct = false; - bool isNewVariantLanguageProduct = languageProduct != null && string.IsNullOrWhiteSpace(languageProduct.VariantId) && !string.IsNullOrWhiteSpace(languageProduct.VirtualVariantId); + bool isNewVariantLanguageProduct = languageProduct != null && string.IsNullOrWhiteSpace(languageProduct.VariantId) && !string.IsNullOrWhiteSpace(languageProduct.VirtualVariantId); - bool newProductValues = FieldHasAnyValue(language.LanguageId, fieldLanguageIdValues); + bool newProductValues = FieldHasAnyValue(language.LanguageId, fieldLanguageIdValues); - if (newProductValues || (languageProduct != null && !isNewVariantLanguageProduct)) + if (newProductValues || (languageProduct != null && !isNewVariantLanguageProduct)) + { + if (languageProduct == null) { - if (languageProduct == null) - { - if (product != null) - { - languageProduct = ProductService.Clone(product); - languageProduct.LanguageId = language.LanguageId; - isNewlanguageProduct = true; - } - } - else if (isNewVariantLanguageProduct && (autoCreateExtendedVariants || (!language.IsDefault && productExistInDefaultLang))) + if (product != null) { - languageProduct.VariantId = languageProduct.VirtualVariantId; + languageProduct = Services.Products.Clone(product); languageProduct.LanguageId = language.LanguageId; isNewlanguageProduct = true; } } - else if (isNewVariantLanguageProduct) - { - languageProduct = null; - } - if ((isNewVariantLanguageProduct || isNewlanguageProduct) && !newProductValues) + else if (isNewVariantLanguageProduct && (autoCreateExtendedVariants || (!language.IsDefault && productExistInDefaultLang))) { - //no values set in any field for a product in this language - nothing to update - continue; + languageProduct.VariantId = languageProduct.VirtualVariantId; + languageProduct.LanguageId = language.LanguageId; + isNewlanguageProduct = true; } + } + else if (isNewVariantLanguageProduct) + { + languageProduct = null; + } + if ((isNewVariantLanguageProduct || isNewlanguageProduct) && !newProductValues) + { + //no values set in any field for a product in this language - nothing to update + continue; + } - if (languageProduct != null) - { - bool isChanged = false; - string fieldValue = null; + if (languageProduct != null) + { + bool isChanged = false; + string fieldValue = null; - foreach (string field in fieldLanguageIdValues.Keys) + foreach (string field in fieldLanguageIdValues.Keys) + { + if (TryGetFieldLanguageValue(fieldLanguageIdValues, language.LanguageId, field, out fieldValue) + && IsFieldChangeAllowed(language, field) + && IsProductFieldChanged(languageProduct, field, fieldValue, language.LanguageId)) { - if (TryGetFieldLanguageValue(fieldLanguageIdValues, language.LanguageId, field, out fieldValue) - && IsFieldChangeAllowed(language, field) - && IsProductFieldChanged(languageProduct, field, fieldValue, language.LanguageId)) - { - isChanged = true; - } + isChanged = true; } + } - if (isChanged && (!isNewVariantLanguageProduct || autoCreateExtendedVariants || (!language.IsDefault && productExistInDefaultLang))) - { - languageProduct.Updated = DateTime.Now; - bool skipExtendedSave = !string.IsNullOrWhiteSpace(languageProduct.VariantId); - ProductService.SaveAndConfirm(languageProduct, languageProduct.Id, languageProduct.VariantId, languageProduct.LanguageId, skipExtendedSave); - } - if (isChanged && autoCreateExtendedVariants && string.IsNullOrEmpty(variantId)) - { - CreateExtendedVariantsForMainProductFieldsChanges(languageProduct, language, fieldLanguageIdValues, failedVariants); - } - if (!isChanged && string.IsNullOrEmpty(variantId)) - { - UpdateExtendedVariantsForMainProductFieldsChanges(languageProduct, language, fieldLanguageIdValues, languages); - } + if (isChanged && (!isNewVariantLanguageProduct || autoCreateExtendedVariants || (!language.IsDefault && productExistInDefaultLang))) + { + languageProduct.Updated = DateTime.Now; + bool skipExtendedSave = !string.IsNullOrWhiteSpace(languageProduct.VariantId); + Services.Products.SaveAndConfirm(languageProduct, languageProduct.Id, languageProduct.VariantId, languageProduct.LanguageId, skipExtendedSave); + } + if (isChanged && autoCreateExtendedVariants && string.IsNullOrEmpty(variantId)) + { + CreateExtendedVariantsForMainProductFieldsChanges(languageProduct, language, fieldLanguageIdValues, failedVariants); + } + if (!isChanged && string.IsNullOrEmpty(variantId)) + { + UpdateExtendedVariantsForMainProductFieldsChanges(languageProduct, language, fieldLanguageIdValues, languages); } } } + } - private string GetListSelectedOptionValueByName(string value, ProductField field, string languageId) - { - if (!string.IsNullOrEmpty(value) && field.TypeId == ListTypeId) - { - FieldOptionCollection options = Ecommerce.Services.FieldOptions.GetOptionsByFieldId(field.Id); - return GetListSelectedOptionValueByName(value, options, languageId); - } - return value; + private string GetListSelectedOptionValueByName(string value, ProductField field, string languageId) + { + if (!string.IsNullOrEmpty(value) && field.TypeId == ListTypeId) + { + FieldOptionCollection options = Ecommerce.Services.FieldOptions.GetOptionsByFieldId(field.Id); + return GetListSelectedOptionValueByName(value, options, languageId); } + return value; + } - private string GetListSelectedOptionValueByName(string field, string value, Field categoryField, string languageId) - { - if (!string.IsNullOrEmpty(value) && categoryField.Type == ListTypeId.ToString()) - { - if (!string.Equals(Ecommerce.Services.Languages.GetDefaultLanguageId(), languageId, StringComparison.OrdinalIgnoreCase)) + private string GetListSelectedOptionValueByName(string field, string value, Field categoryField, string languageId) + { + if (!string.IsNullOrEmpty(value) && categoryField.Type == ListTypeId.ToString()) + { + if (!string.Equals(Ecommerce.Services.Languages.GetDefaultLanguageId(), languageId, StringComparison.OrdinalIgnoreCase)) + { + Field languageField = FieldsHelper.GetCategoryField(field, languageId); + if (languageField != null) { - Field languageField = FieldsHelper.GetCategoryField(field, languageId); - if (languageField != null) - { - categoryField = languageField; - } - } - return GetListSelectedOptionValueByName(value, Ecommerce.Services.FieldOptions.GetOptionsByFieldId(categoryField.Id), languageId); - } - return value; + categoryField = languageField; + } + } + return GetListSelectedOptionValueByName(value, Ecommerce.Services.FieldOptions.GetOptionsByFieldId(categoryField.Id), languageId); } + return value; + } - private string GetListSelectedOptionValueByName(string value, FieldOptionCollection options, string languageId) + private string GetListSelectedOptionValueByName(string value, FieldOptionCollection options, string languageId) + { + List ids = new List(); + if (!string.IsNullOrEmpty(value)) { - List ids = new List(); - if (!string.IsNullOrEmpty(value)) + List multipleValues = new List(); + if (value.Contains(",")) { - List multipleValues = new List(); - if (value.Contains(",")) - { - multipleValues = value.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList(); - } - else - { - multipleValues.Add(value); - } + multipleValues = value.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList(); + } + else + { + multipleValues.Add(value); + } - foreach (string fieldValue in multipleValues) + foreach (string fieldValue in multipleValues) + { + var option = options.FirstOrDefault(o => !string.IsNullOrEmpty(o.GetName(languageId)) && string.Equals(o.GetName(languageId), fieldValue)); + if (option != null) { - var option = options.FirstOrDefault(o => !string.IsNullOrEmpty(o.GetName(languageId)) && string.Equals(o.GetName(languageId), fieldValue)); - if (option != null) - { - ids.Add(option.Value); - } + ids.Add(option.Value); } } - return string.Join(",", ids); } + return string.Join(",", ids); } -} +} \ No newline at end of file diff --git a/src/PIM/ExcelExtensions.cs b/src/PIM/ExcelExtensions.cs index 27baaed..f7d4f12 100644 --- a/src/PIM/ExcelExtensions.cs +++ b/src/PIM/ExcelExtensions.cs @@ -1,52 +1,51 @@ -using OfficeOpenXml; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using OfficeOpenXml; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +public static class ExcelExtensions { - public static class ExcelExtensions + /// + /// Convert a column number into an excel column + /// + /// excel sheet + /// column number + /// + public static string GetColumnName(this ExcelWorksheet sheet, int columnNumber) { - /// - /// Convert a column number into an excel column - /// - /// excel sheet - /// column number - /// - public static string GetColumnName(this ExcelWorksheet sheet, int columnNumber) + int dividend = columnNumber; + string columnName = String.Empty; + int baseValue = Convert.ToInt32('A');//65 + int alphabetLength = Convert.ToInt32('Z') - Convert.ToInt32('A') + 1;//26 + + int modulo; + while (dividend > 0) { - int dividend = columnNumber; - string columnName = String.Empty; - int baseValue = Convert.ToInt32('A');//65 - int alphabetLength = Convert.ToInt32('Z') - Convert.ToInt32('A') + 1;//26 + modulo = (dividend - 1) % alphabetLength; + columnName = Convert.ToChar(baseValue + modulo).ToString() + columnName; + dividend = (int)((dividend - modulo) / alphabetLength); + } - int modulo; - while (dividend > 0) - { - modulo = (dividend - 1) % alphabetLength; - columnName = Convert.ToChar(baseValue + modulo).ToString() + columnName; - dividend = (int)((dividend - modulo) / alphabetLength); - } + return columnName; + } - return columnName; - } + public static int GetProductRow(this ExcelWorksheet sheet, string productId) + { + List result = new List(); - public static int GetProductRow(this ExcelWorksheet sheet, string productId) + for (int row = 2; row <= sheet.Dimension.End.Row; row++) { - List result = new List(); - - for (int row = 2; row <= sheet.Dimension.End.Row; row++) + string text = sheet.Cells[row, 1].Text; + if (!string.IsNullOrEmpty(text) && string.Equals(text, productId, StringComparison.OrdinalIgnoreCase) && string.IsNullOrEmpty(sheet.Cells[row, 2].Text)) { - string text = sheet.Cells[row, 1].Text; - if (!string.IsNullOrEmpty(text) && string.Equals(text, productId, StringComparison.OrdinalIgnoreCase) && string.IsNullOrEmpty(sheet.Cells[row, 2].Text)) - { - return row; - } - + return row; } - return -1; + } + return -1; } -} +} \ No newline at end of file diff --git a/src/PIM/ExportExcelProvider.cs b/src/PIM/ExportExcelProvider.cs index b4a6d17..3b61e75 100644 --- a/src/PIM/ExportExcelProvider.cs +++ b/src/PIM/ExportExcelProvider.cs @@ -1,38 +1,37 @@ using System.Collections.Generic; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM -{ +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +/// +/// Export to Excel provider +/// +public class ExportExcelProvider : IExportExcelProvider +{ /// - /// Export to Excel provider + /// Exports product to excel /// - public class ExportExcelProvider : IExportExcelProvider - { - /// - /// Exports product to excel - /// - /// excel file - /// product id - /// variant id - /// exported languages ids - /// fields to export - /// export status - /// - public bool ExportProduct(string fullFileName, string productId, string productVariantId, - IEnumerable languages, IEnumerable fields, out string statusMessage) - { - ExportOneProductExcelProvider exportOneProductExcelProvider = new ExportOneProductExcelProvider(fields, languages) { ExportVariants = ExportVariants }; - return exportOneProductExcelProvider.ExportProduct(fullFileName, productId, productVariantId, languages, fields, out statusMessage); - } - - public bool ExportProducts(string fullFileName, IEnumerable productIds, IEnumerable languages, IEnumerable fields, out string status) - { - ExportMultipleProductsExcelProvider exportMultipleProductsExcelProvider = new ExportMultipleProductsExcelProvider(fields, languages) { ExportVariants = ExportVariants }; - return exportMultipleProductsExcelProvider.ExportProducts(fullFileName, productIds, languages, fields, out status); - } + /// excel file + /// product id + /// variant id + /// exported languages ids + /// fields to export + /// export status + /// + public bool ExportProduct(string fullFileName, string productId, string productVariantId, + IEnumerable languages, IEnumerable fields, out string statusMessage) + { + ExportOneProductExcelProvider exportOneProductExcelProvider = new ExportOneProductExcelProvider(fields, languages) { ExportVariants = ExportVariants }; + return exportOneProductExcelProvider.ExportProduct(fullFileName, productId, productVariantId, languages, fields, out statusMessage); + } - /// - /// Specifies value indicating whether to include extended variants to product export - /// - public bool ExportVariants { get; set; } = true; + public bool ExportProducts(string fullFileName, IEnumerable productIds, IEnumerable languages, IEnumerable fields, out string status) + { + ExportMultipleProductsExcelProvider exportMultipleProductsExcelProvider = new ExportMultipleProductsExcelProvider(fields, languages) { ExportVariants = ExportVariants }; + return exportMultipleProductsExcelProvider.ExportProducts(fullFileName, productIds, languages, fields, out status); } -} + + /// + /// Specifies value indicating whether to include extended variants to product export + /// + public bool ExportVariants { get; set; } = true; +} \ No newline at end of file diff --git a/src/PIM/ExportMultipleProductsExcelProvider.cs b/src/PIM/ExportMultipleProductsExcelProvider.cs index 0b36778..07fc89c 100644 --- a/src/PIM/ExportMultipleProductsExcelProvider.cs +++ b/src/PIM/ExportMultipleProductsExcelProvider.cs @@ -1,333 +1,325 @@ -using Dynamicweb.Core; -using Dynamicweb.Ecommerce.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Dynamicweb.Ecommerce; using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; -using Dynamicweb.Ecommerce.Products.Categories; using Dynamicweb.Ecommerce.Variants; using OfficeOpenXml; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +internal class ExportMultipleProductsExcelProvider : BaseExportExcelProvider { - internal class ExportMultipleProductsExcelProvider : BaseExportExcelProvider + private readonly List DefaultFields = new List(new string[] { "ProductID", "VariantID", "Variant name" }); + private int LastVisibleColumnIndex = 1; + + public ExportMultipleProductsExcelProvider(IEnumerable fields, IEnumerable languages) : base(fields, languages) { - private readonly List DefaultFields = new List(new string[] { "ProductID", "VariantID", "Variant name" }); - private int LastVisibleColumnIndex = 1; + ListFormulaCanBeRangedByColumn = true; + } - public ExportMultipleProductsExcelProvider(IEnumerable fields, IEnumerable languages) : base(fields, languages) - { - ListFormulaCanBeRangedByColumn = true; - } + public bool ExportProducts(string fullFileName, IEnumerable productIds, IEnumerable languages, IEnumerable fields, out string status) + { + bool result = true; + status = string.Empty; - public bool ExportProducts(string fullFileName, IEnumerable productIds, IEnumerable languages, IEnumerable fields, out string status) + if (productIds.Count() > 0) { - bool result = true; - status = string.Empty; - - if (productIds.Count() > 0) + using (ExcelPackage package = GetExcelPackage(fullFileName)) { - using (ExcelPackage package = GetExcelPackage(fullFileName)) - { - ExcelWorksheet worksheet = GetExcelWorksheet(package, (new FileInfo(fullFileName)).Name); - InitializeStyles(worksheet); + ExcelWorksheet worksheet = GetExcelWorksheet(package, (new FileInfo(fullFileName)).Name); + InitializeStyles(worksheet); - IEnumerable filteredFields = fields.Where(f => !SkipFields.Contains(f)); + IEnumerable filteredFields = fields.Where(f => !SkipFields.Contains(f)); - AddHeader(worksheet, fields); + AddHeader(worksheet, fields); - int rowIndex = 3; - Dictionary numericFields = GetNumericFields(fields); + int rowIndex = 3; + Dictionary numericFields = GetNumericFields(fields); - bool allProductsAreNotAvailableInTheDefaultLanguage = true; - bool allProductsAreNotAvailableInTheSelectedLanguages = true; - var allProductsFamilies = Enumerable.Empty(); - if (ExportVariants) + bool allProductsAreNotAvailableInTheDefaultLanguage = true; + bool allProductsAreNotAvailableInTheSelectedLanguages = true; + var allProductsFamilies = Enumerable.Empty(); + if (ExportVariants) + { + allProductsFamilies = Services.Products.GetByProductIDs(productIds.ToArray(), false, string.Empty, false, false); + } + else + { + var productVariantIdsCollection = new List>(); + foreach (var productId in productIds) { - allProductsFamilies = ProductService.GetByProductIDs(productIds.ToArray(), false, string.Empty, false, false); + productVariantIdsCollection.Add(new Tuple(productId, string.Empty)); } - else + var productsWithoutVariants = new List(); + foreach (var languageId in languages) { - var productVariantIdsCollection = new List>(); - foreach (var productId in productIds) - { - productVariantIdsCollection.Add(new Tuple(productId, string.Empty)); - } - var productsWithoutVariants = new List(); - foreach (var languageId in languages) - { - productsWithoutVariants.AddRange(ProductService.GetByProductIDsAndVariantIDs(productVariantIdsCollection, languageId, false, false)); - } - allProductsFamilies = productsWithoutVariants; + productsWithoutVariants.AddRange(Services.Products.GetByProductIDsAndVariantIDs(productVariantIdsCollection, languageId, false, false)); } + allProductsFamilies = productsWithoutVariants; + } - PrepareCategoryValues(allProductsFamilies); + PrepareCategoryValues(allProductsFamilies); - var exportFieldsInfos = GetExportFieldInfos(filteredFields, numericFields); + var exportFieldsInfos = GetExportFieldInfos(filteredFields, numericFields); - foreach (var familyProducts in allProductsFamilies.GroupBy(product => product.Id)) + foreach (var familyProducts in allProductsFamilies.GroupBy(product => product.Id)) + { + var productId = familyProducts.Key; + var mainProduct = familyProducts.FirstOrDefault(product => string.IsNullOrEmpty(product.VariantId) && product.LanguageId == Ecommerce.Services.Languages.GetDefaultLanguageId()); + if (mainProduct != null) { - var productId = familyProducts.Key; - var mainProduct = familyProducts.FirstOrDefault(product => string.IsNullOrEmpty(product.VariantId) && product.LanguageId == Ecommerce.Services.Languages.GetDefaultLanguageId()); - if (mainProduct != null) + allProductsAreNotAvailableInTheDefaultLanguage = false; + + var languageIdProductDictionary = GetLanguageIdProductDictionary(mainProduct, familyProducts, languages); + if (languageIdProductDictionary.Keys.Count > 0) { - allProductsAreNotAvailableInTheDefaultLanguage = false; + allProductsAreNotAvailableInTheSelectedLanguages = false; - var languageIdProductDictionary = GetLanguageIdProductDictionary(mainProduct, familyProducts, languages); - if (languageIdProductDictionary.Keys.Count > 0) + AddProductRow(worksheet, ref rowIndex, mainProduct, languageIdProductDictionary, + exportFieldsInfos, -1); + rowIndex++; + if (ExportVariants) { - allProductsAreNotAvailableInTheSelectedLanguages = false; - - AddProductRow(worksheet, ref rowIndex, mainProduct, languageIdProductDictionary, - exportFieldsInfos, -1); - rowIndex++; - if (ExportVariants) - { - var variantIdLanguageIdVariantProductDictionary = GetVariantIdLanguageIdVariantProductDictionary(familyProducts, languages); - AddProductVariantsRows(worksheet, variantIdLanguageIdVariantProductDictionary, mainProduct, ref rowIndex, - exportFieldsInfos); - } + var variantIdLanguageIdVariantProductDictionary = GetVariantIdLanguageIdVariantProductDictionary(familyProducts, languages); + AddProductVariantsRows(worksheet, variantIdLanguageIdVariantProductDictionary, mainProduct, ref rowIndex, + exportFieldsInfos); } } } - - if (allProductsAreNotAvailableInTheDefaultLanguage) - { - status = "All products are not available in the default language"; - result = false; - } - if (allProductsAreNotAvailableInTheSelectedLanguages) - { - status = "All products are not available in the selected languages"; - result = false; - } - if (result) - { - SetListFormulas(worksheet); - SetColumnsWidth(worksheet, languages.Count(), filteredFields.Count()); - package.Save(); - } } - } - return result; - } - private IList GetExportFieldInfos(IEnumerable filteredFields, Dictionary numericFields) - { - var result = new List(); - foreach (var field in filteredFields) - { - var exportInfo = new FieldExportInfo(); - exportInfo.SystemName = field; - exportInfo.NumericFieldType = numericFields.ContainsKey(field) ? numericFields[field] : null; - exportInfo.IsReadOnly = FieldsHelper.IsFieldReadOnly(field); - string fieldType = FieldsHelper.GetFieldType(field); - exportInfo.IsMultiLine = !(fieldType == "System" || fieldType == "Text" || fieldType == "Tekst"); - exportInfo.FieldOptions = ListFieldsHelper.GetFieldOptions(field); - exportInfo.MultipleSelectionList = ListFieldsHelper.IsMultipleSelectionListBoxField(exportInfo.FieldOptions); - exportInfo.isList = exportInfo.FieldOptions.Key != null && exportInfo.FieldOptions.Value != null && exportInfo.FieldOptions.Value.Any(); - if (exportInfo.isList) + if (allProductsAreNotAvailableInTheDefaultLanguage) { - exportInfo.ListRangeFormula = GetListRangeFormula(exportInfo.FieldOptions, null); + status = "All products are not available in the default language"; + result = false; + } + if (allProductsAreNotAvailableInTheSelectedLanguages) + { + status = "All products are not available in the selected languages"; + result = false; + } + if (result) + { + SetListFormulas(worksheet); + SetColumnsWidth(worksheet, languages.Count(), filteredFields.Count()); + package.Save(); } - - result.Add(exportInfo); } - return result; } + return result; + } - private static void PrepareCategoryValues(IEnumerable allProductsFamilies) + private IList GetExportFieldInfos(IEnumerable filteredFields, Dictionary numericFields) + { + var result = new List(); + foreach (var field in filteredFields) { - var fieldService = new ProductCategoryFieldValueService(); - var prepareValuesMethod = typeof(ProductCategoryFieldValueService).GetMethod("PrepareProductValues", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - if (prepareValuesMethod != null) + var exportInfo = new FieldExportInfo(); + exportInfo.SystemName = field; + exportInfo.NumericFieldType = numericFields.ContainsKey(field) ? numericFields[field] : null; + exportInfo.IsReadOnly = FieldsHelper.IsFieldReadOnly(field); + string fieldType = FieldsHelper.GetFieldType(field); + exportInfo.IsMultiLine = !(fieldType == "System" || fieldType == "Text" || fieldType == "Tekst"); + exportInfo.FieldOptions = ListFieldsHelper.GetFieldOptions(field); + exportInfo.MultipleSelectionList = ListFieldsHelper.IsMultipleSelectionListBoxField(exportInfo.FieldOptions); + exportInfo.isList = exportInfo.FieldOptions.Key != null && exportInfo.FieldOptions.Value != null && exportInfo.FieldOptions.Value.Any(); + if (exportInfo.isList) { - prepareValuesMethod.Invoke(fieldService, new object[] { allProductsFamilies.Select(x => x.Id).Distinct() }); + exportInfo.ListRangeFormula = GetListRangeFormula(exportInfo.FieldOptions, null); } + + result.Add(exportInfo); } + return result; + } - /// - /// Exports variants to excel - /// - private void AddProductVariantsRows(ExcelWorksheet worksheet, Dictionary> variantIdLanguageIdVariantProductDictionary, - Product mainProduct, ref int rowIndex, IEnumerable fields) + private static void PrepareCategoryValues(IEnumerable allProductsFamilies) + { + Services.ProductCategoryFieldValues.PrepareProductValues(allProductsFamilies.Select(x => x.Id).Distinct()); + } + + /// + /// Exports variants to excel + /// + private void AddProductVariantsRows(ExcelWorksheet worksheet, Dictionary> variantIdLanguageIdVariantProductDictionary, + Product mainProduct, ref int rowIndex, IEnumerable fields) + { + //Process extended variants + if (variantIdLanguageIdVariantProductDictionary.Keys.Count > 0) { - //Process extended variants - if (variantIdLanguageIdVariantProductDictionary.Keys.Count > 0) + int mainProductRowIndex = rowIndex - 1; + foreach (VariantCombination variantCombination in Services.VariantCombinations.GetVariantCombinations(mainProduct.Id)) { - int mainProductRowIndex = rowIndex - 1; - foreach (VariantCombination variantCombination in VariantCombinationService.GetVariantCombinations(mainProduct.Id)) + Product variantInDefaultLanguage = Services.Products.GetProductById(mainProduct.Id, variantCombination.VariantId, DefaultLanguage.LanguageId); + var languageIdVariantProductDictionary = new Dictionary(); + if (variantIdLanguageIdVariantProductDictionary.ContainsKey(variantCombination.VariantId)) { - Product variantInDefaultLanguage = ProductService.GetProductById(mainProduct.Id, variantCombination.VariantId, DefaultLanguage.LanguageId); - var languageIdVariantProductDictionary = new Dictionary(); - if (variantIdLanguageIdVariantProductDictionary.ContainsKey(variantCombination.VariantId)) - { - languageIdVariantProductDictionary = variantIdLanguageIdVariantProductDictionary[variantCombination.VariantId]; - } + languageIdVariantProductDictionary = variantIdLanguageIdVariantProductDictionary[variantCombination.VariantId]; + } - AddProductRow(worksheet, ref rowIndex, variantInDefaultLanguage, languageIdVariantProductDictionary, fields, mainProductRowIndex); + AddProductRow(worksheet, ref rowIndex, variantInDefaultLanguage, languageIdVariantProductDictionary, fields, mainProductRowIndex); - rowIndex++; - } + rowIndex++; } } + } - private void SetColumnsWidth(ExcelWorksheet worksheet, int languagesCount, int fieldsCount) - { - worksheet.Column(1).Width = 10; - worksheet.Column(2).Width = 16; + private void SetColumnsWidth(ExcelWorksheet worksheet, int languagesCount, int fieldsCount) + { + worksheet.Column(1).Width = 10; + worksheet.Column(2).Width = 16; - for (int j = 3; j <= LastVisibleColumnIndex; j++) - { - worksheet.Column(j).Width = 30; - } + for (int j = 3; j <= LastVisibleColumnIndex; j++) + { + worksheet.Column(j).Width = 30; } + } - #region ExcelRendering + #region ExcelRendering - private void AddHeader(ExcelWorksheet worksheet, IEnumerable fields) + private void AddHeader(ExcelWorksheet worksheet, IEnumerable fields) + { + int lastColumnIndex = 1; + int firstRow = 1; + int secondRow = 2; + foreach (string field in DefaultFields) { - int lastColumnIndex = 1; - int firstRow = 1; - int secondRow = 2; - foreach (string field in DefaultFields) - { - AddHeaderCell(worksheet, field, firstRow, lastColumnIndex++, null); - } - AddHeaderCell(worksheet, $"{DefaultLanguage.Name} ({DefaultLanguage.LanguageId})", secondRow, 3, null); - foreach (string field in fields.Where(f => !SkipFields.Contains(f))) - { - AddHeaderCell(worksheet, FieldsHelper.GetFieldTranslation(field, DefaultLanguage, DefaultLanguage), firstRow, lastColumnIndex, FieldsHelper.GetFieldSystemName(field)); - //add next row with languages like English (LANG1)/Danish (LANG2) - AddHeaderCell(worksheet, $"{DefaultLanguage.Name} ({DefaultLanguage.LanguageId})", secondRow, lastColumnIndex, DefaultLanguage.LanguageId); - lastColumnIndex++; + AddHeaderCell(worksheet, field, firstRow, lastColumnIndex++, null); + } + AddHeaderCell(worksheet, $"{DefaultLanguage.Name} ({DefaultLanguage.LanguageId})", secondRow, 3, null); + foreach (string field in fields.Where(f => !SkipFields.Contains(f))) + { + AddHeaderCell(worksheet, FieldsHelper.GetFieldTranslation(field, DefaultLanguage, DefaultLanguage), firstRow, lastColumnIndex, FieldsHelper.GetFieldSystemName(field)); + //add next row with languages like English (LANG1)/Danish (LANG2) + AddHeaderCell(worksheet, $"{DefaultLanguage.Name} ({DefaultLanguage.LanguageId})", secondRow, lastColumnIndex, DefaultLanguage.LanguageId); + lastColumnIndex++; - foreach (Language language in Languages.Where(l => !string.Equals(l.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase))) + foreach (Language language in Languages.Where(l => !string.Equals(l.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase))) + { + if (!FieldsHelper.IsFieldInheritedFromDefaultLanguage(field, language.LanguageId)) { - if (!FieldsHelper.IsFieldInheritedFromDefaultLanguage(field, language.LanguageId)) - { - AddHeaderCell(worksheet, FieldsHelper.GetFieldTranslation(field, language, DefaultLanguage), firstRow, lastColumnIndex, FieldsHelper.GetFieldSystemName(field)); - //add next row with languages like English (LANG1)/Danish (LANG2) - AddHeaderCell(worksheet, $"{language.NativeName} ({language.LanguageId})", secondRow, lastColumnIndex, language.LanguageId); - lastColumnIndex++; - } + AddHeaderCell(worksheet, FieldsHelper.GetFieldTranslation(field, language, DefaultLanguage), firstRow, lastColumnIndex, FieldsHelper.GetFieldSystemName(field)); + //add next row with languages like English (LANG1)/Danish (LANG2) + AddHeaderCell(worksheet, $"{language.NativeName} ({language.LanguageId})", secondRow, lastColumnIndex, language.LanguageId); + lastColumnIndex++; } } } + } - private void AddHeaderCell(ExcelWorksheet worksheet, string text, int row, int column, string value) + private void AddHeaderCell(ExcelWorksheet worksheet, string text, int row, int column, string value) + { + ExcelRange cell = AddCell(worksheet, text, row, column, LockedGrayStyle); + if (!string.IsNullOrEmpty(value)) { - ExcelRange cell = AddCell(worksheet, text, row, column, LockedGrayStyle); - if (!string.IsNullOrEmpty(value)) - { - cell.AddComment(value, CommentsAuthor); - } - if (column > LastVisibleColumnIndex) - { - LastVisibleColumnIndex = column; - } + cell.AddComment(value, CommentsAuthor); } - - private void AddProductRow(ExcelWorksheet worksheet, ref int rowIndex, Product product, Dictionary languageIdProductDictionary, - IEnumerable fields, int mainProductRowIndex) + if (column > LastVisibleColumnIndex) { - int lastColumnIndex = 1; - bool isVariantProduct = !string.IsNullOrEmpty(product.VariantId) || !string.IsNullOrEmpty(product.VirtualVariantId); - int maxLineCount = 1; - bool multiLine = false; + LastVisibleColumnIndex = column; + } + } - mainProductRowIndex = isVariantProduct ? mainProductRowIndex : -1; + private void AddProductRow(ExcelWorksheet worksheet, ref int rowIndex, Product product, Dictionary languageIdProductDictionary, + IEnumerable fields, int mainProductRowIndex) + { + int lastColumnIndex = 1; + bool isVariantProduct = !string.IsNullOrEmpty(product.VariantId) || !string.IsNullOrEmpty(product.VirtualVariantId); + int maxLineCount = 1; + bool multiLine = false; - AddCell(worksheet, product.Id, rowIndex, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, rowIndex, lastColumnIndex++, LockedGrayStyle); - string variantName = isVariantProduct ? VariantService.GetVariantName(string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, DefaultLanguage.LanguageId) - : string.Empty; - AddCell(worksheet, variantName, rowIndex, lastColumnIndex++, LockedGrayStyle); + mainProductRowIndex = isVariantProduct ? mainProductRowIndex : -1; - foreach (FieldExportInfo field in fields) - { - string formula = worksheet.GetColumnName(lastColumnIndex) + rowIndex; + AddCell(worksheet, product.Id, rowIndex, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, rowIndex, lastColumnIndex++, LockedGrayStyle); + string variantName = isVariantProduct ? Services.Variants.GetVariantName(string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, DefaultLanguage.LanguageId) + : string.Empty; + AddCell(worksheet, variantName, rowIndex, lastColumnIndex++, LockedGrayStyle); - bool isVariantFieldVisible = true; - bool isReadOnly = field.IsReadOnly; - if (isVariantProduct) - { - ProcessFormula(worksheet, mainProductRowIndex, lastColumnIndex, field.SystemName, product, ref isVariantFieldVisible, ref isReadOnly, ref formula); - } - bool extractFieldValue = !isVariantProduct || isVariantFieldVisible; - string fieldValue = null; - if (extractFieldValue) - { - fieldValue = GetFieldValue(product, field.SystemName, field.FieldOptions, field.MultipleSelectionList, null); - } - maxLineCount = GetMaxLineCount(maxLineCount, fieldValue); + foreach (FieldExportInfo field in fields) + { + string formula = worksheet.GetColumnName(lastColumnIndex) + rowIndex; - if (field.isList) - { - formula = field.ListRangeFormula; - } - AddCell(worksheet, fieldValue, rowIndex, lastColumnIndex++, isReadOnly, isReadOnly, multiLine, - extractFieldValue ? (field.isList ? formula : null) : formula, field.NumericFieldType, field.isList); + bool isVariantFieldVisible = true; + bool isReadOnly = field.IsReadOnly; + if (isVariantProduct) + { + ProcessFormula(worksheet, mainProductRowIndex, lastColumnIndex, field.SystemName, product, ref isVariantFieldVisible, ref isReadOnly, ref formula); + } + bool extractFieldValue = !isVariantProduct || isVariantFieldVisible; + string fieldValue = null; + if (extractFieldValue) + { + fieldValue = GetFieldValue(product, field.SystemName, field.FieldOptions, field.MultipleSelectionList, null); + } + maxLineCount = GetMaxLineCount(maxLineCount, fieldValue); + + if (field.isList) + { + formula = field.ListRangeFormula; + } + AddCell(worksheet, fieldValue, rowIndex, lastColumnIndex++, isReadOnly, isReadOnly, multiLine, + extractFieldValue ? (field.isList ? formula : null) : formula, field.NumericFieldType, field.isList); - foreach (Language language in Languages.Where(l => !string.Equals(l.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase))) + foreach (Language language in Languages.Where(l => !string.Equals(l.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase))) + { + string languageId = language.LanguageId; + if (!FieldsHelper.IsFieldInheritedFromDefaultLanguage(field.SystemName, language.LanguageId)) { - string languageId = language.LanguageId; - if (!FieldsHelper.IsFieldInheritedFromDefaultLanguage(field.SystemName, language.LanguageId)) + Product languageProduct = null; + if (languageIdProductDictionary.ContainsKey(languageId)) { - Product languageProduct = null; - if (languageIdProductDictionary.ContainsKey(languageId)) - { - languageProduct = languageIdProductDictionary[languageId]; + languageProduct = languageIdProductDictionary[languageId]; - ProcessFormula(worksheet, mainProductRowIndex, lastColumnIndex, field.SystemName, languageProduct, ref isVariantFieldVisible, ref isReadOnly, ref formula); - } - else + ProcessFormula(worksheet, mainProductRowIndex, lastColumnIndex, field.SystemName, languageProduct, ref isVariantFieldVisible, ref isReadOnly, ref formula); + } + else + { + if (isVariantProduct) { - if (isVariantProduct) - { - ProcessFormula(worksheet, mainProductRowIndex, lastColumnIndex, field.SystemName, product, ref isVariantFieldVisible, ref isReadOnly, ref formula); - } + ProcessFormula(worksheet, mainProductRowIndex, lastColumnIndex, field.SystemName, product, ref isVariantFieldVisible, ref isReadOnly, ref formula); } - - maxLineCount = AddFieldValueCell(worksheet, extractFieldValue, field.SystemName, languageId, languageIdProductDictionary, - isVariantProduct, field.isList, field.MultipleSelectionList, field.FieldOptions, formula, rowIndex, ref lastColumnIndex, - field.NumericFieldType, multiLine, maxLineCount); } + + maxLineCount = AddFieldValueCell(worksheet, extractFieldValue, field.SystemName, languageId, languageIdProductDictionary, + isVariantProduct, field.isList, field.MultipleSelectionList, field.FieldOptions, formula, rowIndex, ref lastColumnIndex, + field.NumericFieldType, multiLine, maxLineCount); } } - maxLineCount = maxLineCount > 0 ? maxLineCount : 1; - worksheet.Row(rowIndex).Height = multiLine ? (maxLineCount > 3 ? 45 : maxLineCount * 15) : 15; } + maxLineCount = maxLineCount > 0 ? maxLineCount : 1; + worksheet.Row(rowIndex).Height = multiLine ? (maxLineCount > 3 ? 45 : maxLineCount * 15) : 15; + } - private void ProcessFormula(ExcelWorksheet worksheet, int mainProductRowIndex, int lastColumnIndex, string field, Product product, ref bool isVariantFieldVisible, ref bool isReadOnly, ref string formula) + private void ProcessFormula(ExcelWorksheet worksheet, int mainProductRowIndex, int lastColumnIndex, string field, Product product, ref bool isVariantFieldVisible, ref bool isReadOnly, ref string formula) + { + isVariantFieldVisible = FieldsHelper.IsFieldVisible(field, product) && ShowField(product, field); + if (!isVariantFieldVisible) { - isVariantFieldVisible = FieldsHelper.IsFieldVisible(field, product) && ShowField(product, field); - if (!isVariantFieldVisible) + isReadOnly = true; + //build formula to main product row + if (mainProductRowIndex > 0) { - isReadOnly = true; - //build formula to main product row - if (mainProductRowIndex > 0) - { - formula = worksheet.GetColumnName(lastColumnIndex) + mainProductRowIndex; - } + formula = worksheet.GetColumnName(lastColumnIndex) + mainProductRowIndex; } } - - #endregion ExcelRendering } - internal class FieldExportInfo - { - public string SystemName { get; set; } - public string ExcelFormula { get; set; } - public bool isList { get; set; } - public Type NumericFieldType { get; internal set; } - public bool IsReadOnly { get; internal set; } - public bool IsMultiLine { get; internal set; } - public KeyValuePair> FieldOptions { get; internal set; } - public bool MultipleSelectionList { get; internal set; } - public string ListRangeFormula { get; internal set; } - } + #endregion ExcelRendering } + +internal class FieldExportInfo +{ + public string SystemName { get; set; } + public string ExcelFormula { get; set; } + public bool isList { get; set; } + public Type NumericFieldType { get; internal set; } + public bool IsReadOnly { get; internal set; } + public bool IsMultiLine { get; internal set; } + public KeyValuePair> FieldOptions { get; internal set; } + public bool MultipleSelectionList { get; internal set; } + public string ListRangeFormula { get; internal set; } +} \ No newline at end of file diff --git a/src/PIM/ExportOneProductExcelProvider.cs b/src/PIM/ExportOneProductExcelProvider.cs index b1b5f5a..6799384 100644 --- a/src/PIM/ExportOneProductExcelProvider.cs +++ b/src/PIM/ExportOneProductExcelProvider.cs @@ -1,297 +1,296 @@ -using Dynamicweb.Core; -using Dynamicweb.Ecommerce.Common; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using Dynamicweb.Ecommerce; using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; using Dynamicweb.Ecommerce.Variants; using OfficeOpenXml; using OfficeOpenXml.Style; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +internal class ExportOneProductExcelProvider : BaseExportExcelProvider { - internal class ExportOneProductExcelProvider : BaseExportExcelProvider + private readonly int DefaultProductFieldValueColumnIndex = 6; + + public ExportOneProductExcelProvider(IEnumerable fields, IEnumerable languages) : base(fields, languages) { - private readonly int DefaultProductFieldValueColumnIndex = 6; + ListFormulaCanBeRangedByColumn = false; + } - public ExportOneProductExcelProvider(IEnumerable fields, IEnumerable languages) : base(fields, languages) - { - ListFormulaCanBeRangedByColumn = false; - } + /// + /// Exports product to excel + /// + /// excel file + /// product id + /// variant id + /// exported languages ids + /// fields to export + /// export status + /// + public bool ExportProduct(string fullFileName, string productId, string productVariantId, IEnumerable languages, IEnumerable fields, out string statusMessage) + { + bool result = true; + statusMessage = string.Empty; - /// - /// Exports product to excel - /// - /// excel file - /// product id - /// variant id - /// exported languages ids - /// fields to export - /// export status - /// - public bool ExportProduct(string fullFileName, string productId, string productVariantId, IEnumerable languages, IEnumerable fields, out string statusMessage) + var numericFields = GetNumericFields(fields); + var familyProducts = Services.Products.GetByProductIDs(new[] { productId }, false, string.Empty, false, false); + var defaultLanguageId = Services.Languages.GetDefaultLanguageId(); + var mainProduct = familyProducts.FirstOrDefault(product => string.IsNullOrEmpty(product.VariantId) && product.LanguageId == defaultLanguageId); + if (mainProduct != null) { - bool result = true; - statusMessage = string.Empty; - - var numericFields = GetNumericFields(fields); - var familyProducts = ProductService.GetByProductIDs(new[] { productId }, false, string.Empty, false, false); - var mainProduct = familyProducts.FirstOrDefault(product => string.IsNullOrEmpty(product.VariantId) && product.LanguageId == Ecommerce.Services.Languages.GetDefaultLanguageId()); - if (mainProduct != null) + var languageIdProductDictionary = GetLanguageIdProductDictionary(mainProduct, familyProducts, languages); + if (languageIdProductDictionary.Keys.Count > 0) { - var languageIdProductDictionary = GetLanguageIdProductDictionary(mainProduct, familyProducts, languages); - if (languageIdProductDictionary.Keys.Count > 0) - { - using (ExcelPackage package = GetExcelPackage(fullFileName)) - { - ExcelWorksheet worksheet = GetExcelWorksheet(package, mainProduct.Id); - InitializeStyles(worksheet); + using (ExcelPackage package = GetExcelPackage(fullFileName)) + { + ExcelWorksheet worksheet = GetExcelWorksheet(package, mainProduct.Id); + InitializeStyles(worksheet); - int rowIndex = 1; - //Headers - worksheet.Row(rowIndex).Height = 30; - AddHeader(worksheet, rowIndex, null, null); - //Product in DefaultLanguage with language products - rowIndex++; - AddLanguageIdRow(worksheet, rowIndex, mainProduct); + int rowIndex = 1; + //Headers + worksheet.Row(rowIndex).Height = 30; + AddHeader(worksheet, rowIndex, null, null); + //Product in DefaultLanguage with language products + rowIndex++; + AddLanguageIdRow(worksheet, rowIndex, mainProduct); - //proudct fields rows - foreach (string field in fields.Where(f => FieldsHelper.IsFieldVisible(f, mainProduct) && !SkipFields.Contains(f))) - { - if (ShowField(mainProduct, field)) - { - rowIndex++; - AddProductFieldRow(worksheet, rowIndex, mainProduct, languageIdProductDictionary, field, - numericFields.ContainsKey(field) ? numericFields[field] : null); - } - } - if (ExportVariants) + //proudct fields rows + foreach (string field in fields.Where(f => FieldsHelper.IsFieldVisible(f, mainProduct) && !SkipFields.Contains(f))) + { + if (ShowField(mainProduct, field)) { - var variantIdLanguageIdVariantProductDictionary = GetVariantIdLanguageIdVariantProductDictionary(familyProducts, languages); - AddProductVariantsRows(worksheet, variantIdLanguageIdVariantProductDictionary, mainProduct, rowIndex, fields, numericFields); + rowIndex++; + AddProductFieldRow(worksheet, rowIndex, mainProduct, languageIdProductDictionary, field, + numericFields.ContainsKey(field) ? numericFields[field] : null); } - SetListFormulas(worksheet); - SetColumnsWidth(worksheet, languages.Count()); - package.Save(); } - } - else - { - statusMessage = "The product is not available in the selected languages"; - result = false; + if (ExportVariants) + { + var variantIdLanguageIdVariantProductDictionary = GetVariantIdLanguageIdVariantProductDictionary(familyProducts, languages); + AddProductVariantsRows(worksheet, variantIdLanguageIdVariantProductDictionary, mainProduct, rowIndex, fields, numericFields); + } + SetListFormulas(worksheet); + SetColumnsWidth(worksheet, languages.Count()); + package.Save(); } } else { - statusMessage = "The product is not available in the default language"; + statusMessage = "The product is not available in the selected languages"; result = false; } - return result; } + else + { + statusMessage = "The product is not available in the default language"; + result = false; + } + return result; + } - private void SetColumnsWidth(ExcelWorksheet worksheet, int languagesCount) + private void SetColumnsWidth(ExcelWorksheet worksheet, int languagesCount) + { + worksheet.Column(1).Width = 10; + worksheet.Column(2).Width = 16; + worksheet.Column(3).Width = 22; + worksheet.Column(4).Width = 16; + worksheet.Column(5).Width = 22; + int columnIndex = 6; + for (int i = 0; i < languagesCount; i++) { - worksheet.Column(1).Width = 10; - worksheet.Column(2).Width = 16; - worksheet.Column(3).Width = 22; - worksheet.Column(4).Width = 16; - worksheet.Column(5).Width = 22; - int columnIndex = 6; - for (int i = 0; i < languagesCount; i++) - { - worksheet.Column(columnIndex++).Width = 60; - worksheet.Column(columnIndex++).Width = 22; - } - //worksheet.Cells.AutoFitColumns(0); //commented as it overrides custom width/height + worksheet.Column(columnIndex++).Width = 60; + worksheet.Column(columnIndex++).Width = 22; } + //worksheet.Cells.AutoFitColumns(0); //commented as it overrides custom width/height + } - #region ExcelRendering + #region ExcelRendering - private void AddHeader(ExcelWorksheet worksheet, int row, Product variantProduct, Dictionary languageIdVariantProductDictionary) + private void AddHeader(ExcelWorksheet worksheet, int row, Product variantProduct, Dictionary languageIdVariantProductDictionary) + { + int lastColumnIndex = 1; + AddHeaderCell(worksheet, variantProduct != null ? variantProduct.Id : "ProductID", row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, variantProduct != null ? + string.IsNullOrEmpty(variantProduct.VariantId) ? variantProduct.VirtualVariantId : variantProduct.VariantId : + "ProductVariantID", row, lastColumnIndex++, variantProduct != null); + if (variantProduct != null) { - int lastColumnIndex = 1; - AddHeaderCell(worksheet, variantProduct != null ? variantProduct.Id : "ProductID", row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, variantProduct != null ? - string.IsNullOrEmpty(variantProduct.VariantId) ? variantProduct.VirtualVariantId : variantProduct.VariantId : - "ProductVariantID", row, lastColumnIndex++, variantProduct != null); - if (variantProduct != null) - { - AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); - string variantName = VariantService.GetVariantName(string.IsNullOrEmpty(variantProduct.VariantId) ? variantProduct.VirtualVariantId : variantProduct.VariantId, - variantProduct.LanguageId); - AddHeaderCell(worksheet, variantName, row, lastColumnIndex++, variantProduct != null); - } - else - { - AddHeaderCell(worksheet, "FieldName", row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, "FieldType", row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, DefaultLanguage.Name + " FieldName", row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, DefaultLanguage.Name, row, lastColumnIndex++, variantProduct != null); - } - - foreach (Language language in Languages) - { - if (!string.Equals(language.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase)) - { - if (variantProduct != null) - { - Product product = languageIdVariantProductDictionary != null && languageIdVariantProductDictionary.ContainsKey(language.LanguageId) - ? languageIdVariantProductDictionary[language.LanguageId] : variantProduct; - string variantName = VariantService.GetVariantName(string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, - product.LanguageId); - AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, variantName, row, lastColumnIndex++, variantProduct != null); - } - else - { - AddHeaderCell(worksheet, language.Name + " FieldName", row, lastColumnIndex++, variantProduct != null); - AddHeaderCell(worksheet, language.Name, row, lastColumnIndex++, variantProduct != null); - } - } - } + AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); + string variantName = Services.Variants.GetVariantName(string.IsNullOrEmpty(variantProduct.VariantId) ? variantProduct.VirtualVariantId : variantProduct.VariantId, + variantProduct.LanguageId); + AddHeaderCell(worksheet, variantName, row, lastColumnIndex++, variantProduct != null); } - - private void AddLanguageIdRow(ExcelWorksheet worksheet, int row, Product mainProduct, bool forVariant = false) + else { - int lastColumnIndex = 1; - AddCell(worksheet, mainProduct.Id, row, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, string.Empty, row, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, "ProductLanguageID", row, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, "System", row, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, string.Empty, row, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, DefaultLanguage.LanguageId, row, lastColumnIndex++, LockedGrayStyle); + AddHeaderCell(worksheet, "FieldName", row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, "FieldType", row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, DefaultLanguage.Name + " FieldName", row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, DefaultLanguage.Name, row, lastColumnIndex++, variantProduct != null); + } - foreach (Language language in Languages) + foreach (Language language in Languages) + { + if (!string.Equals(language.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase)) { - if (!string.Equals(language.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase)) + if (variantProduct != null) { - AddCell(worksheet, string.Empty, row, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, language.LanguageId, row, lastColumnIndex++, LockedGrayStyle); + Product product = languageIdVariantProductDictionary != null && languageIdVariantProductDictionary.ContainsKey(language.LanguageId) + ? languageIdVariantProductDictionary[language.LanguageId] : variantProduct; + string variantName = Services.Variants.GetVariantName(string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, + product.LanguageId); + AddHeaderCell(worksheet, string.Empty, row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, variantName, row, lastColumnIndex++, variantProduct != null); + } + else + { + AddHeaderCell(worksheet, language.Name + " FieldName", row, lastColumnIndex++, variantProduct != null); + AddHeaderCell(worksheet, language.Name, row, lastColumnIndex++, variantProduct != null); } } } + } - private void AddHeaderCell(ExcelWorksheet worksheet, string text, int row, int column, bool forVariant) + private void AddLanguageIdRow(ExcelWorksheet worksheet, int row, Product mainProduct, bool forVariant = false) + { + int lastColumnIndex = 1; + AddCell(worksheet, mainProduct.Id, row, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, string.Empty, row, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, "ProductLanguageID", row, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, "System", row, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, string.Empty, row, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, DefaultLanguage.LanguageId, row, lastColumnIndex++, LockedGrayStyle); + + foreach (Language language in Languages) { - ExcelRange cell = AddCell(worksheet, text, row, column, true, false); - var cellStyle = cell.Style; - cellStyle.Fill.PatternType = ExcelFillStyle.Solid; - if (forVariant) - { - cellStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(221, 235, 247)); - } - else + if (!string.Equals(language.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase)) { - cellStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(242, 242, 242)); + AddCell(worksheet, string.Empty, row, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, language.LanguageId, row, lastColumnIndex++, LockedGrayStyle); } - cellStyle.Border.Bottom.Style = ExcelBorderStyle.Thin; - cellStyle.Border.Bottom.Color.SetColor(Color.Black); } + } - private void AddProductFieldRow(ExcelWorksheet worksheet, int rowIndex, Product product, Dictionary languageIdProductDictionary, - string field, Type numericFieldType) + private void AddHeaderCell(ExcelWorksheet worksheet, string text, int row, int column, bool forVariant) + { + ExcelRange cell = AddCell(worksheet, text, row, column, true, false); + var cellStyle = cell.Style; + cellStyle.Fill.PatternType = ExcelFillStyle.Solid; + if (forVariant) { - int lastColumnIndex = 1; + cellStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(221, 235, 247)); + } + else + { + cellStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(242, 242, 242)); + } + cellStyle.Border.Bottom.Style = ExcelBorderStyle.Thin; + cellStyle.Border.Bottom.Color.SetColor(Color.Black); + } - string fieldType = FieldsHelper.GetFieldType(field); - bool multiLine = !(fieldType == "System" || fieldType == "Text" || fieldType == "Tekst"); - string formula = worksheet.GetColumnName(DefaultProductFieldValueColumnIndex) + rowIndex; - bool isReadOnly = FieldsHelper.IsFieldReadOnly(field); - KeyValuePair> options = ListFieldsHelper.GetFieldOptions(field); - bool multipleSelectionList = ListFieldsHelper.IsMultipleSelectionListBoxField(options); - string fieldValue = GetFieldValue(product, field, options, multipleSelectionList, DefaultLanguage.LanguageId); - int maxLineCount = GetLineCount(fieldValue, 60); - bool isVariantProduct = !string.IsNullOrEmpty(product.VariantId) || !string.IsNullOrEmpty(product.VirtualVariantId); - bool isList = options.Key != null && options.Value?.Count() > 0; - if (isList) - { - formula = GetListRangeFormula(options, null); - } + private void AddProductFieldRow(ExcelWorksheet worksheet, int rowIndex, Product product, Dictionary languageIdProductDictionary, + string field, Type numericFieldType) + { + int lastColumnIndex = 1; - AddCell(worksheet, product.Id, rowIndex, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, rowIndex, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, FieldsHelper.GetFieldSystemName(field), rowIndex, lastColumnIndex++, LockedGrayStyle); + string fieldType = FieldsHelper.GetFieldType(field); + bool multiLine = !(fieldType == "System" || fieldType == "Text" || fieldType == "Tekst"); + string formula = worksheet.GetColumnName(DefaultProductFieldValueColumnIndex) + rowIndex; + bool isReadOnly = FieldsHelper.IsFieldReadOnly(field); + KeyValuePair> options = ListFieldsHelper.GetFieldOptions(field); + bool multipleSelectionList = ListFieldsHelper.IsMultipleSelectionListBoxField(options); + string fieldValue = GetFieldValue(product, field, options, multipleSelectionList, DefaultLanguage.LanguageId); + int maxLineCount = GetLineCount(fieldValue, 60); + bool isVariantProduct = !string.IsNullOrEmpty(product.VariantId) || !string.IsNullOrEmpty(product.VirtualVariantId); + bool isList = options.Key != null && options.Value?.Count() > 0; + if (isList) + { + formula = GetListRangeFormula(options, null); + } - AddCell(worksheet, fieldType, rowIndex, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, FieldsHelper.GetFieldTranslation(field, DefaultLanguage, DefaultLanguage), rowIndex, lastColumnIndex++, LockedGrayStyle); - AddCell(worksheet, fieldValue, rowIndex, lastColumnIndex++, isReadOnly, isReadOnly, multiLine, isList ? formula : null, numericFieldType, isList); + AddCell(worksheet, product.Id, rowIndex, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, string.IsNullOrEmpty(product.VariantId) ? product.VirtualVariantId : product.VariantId, rowIndex, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, FieldsHelper.GetFieldSystemName(field), rowIndex, lastColumnIndex++, LockedGrayStyle); - foreach (Language language in Languages.Where(l => !string.Equals(l.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase))) - { - AddCell(worksheet, FieldsHelper.GetFieldTranslation(field, language, DefaultLanguage), rowIndex, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, fieldType, rowIndex, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, FieldsHelper.GetFieldTranslation(field, DefaultLanguage, DefaultLanguage), rowIndex, lastColumnIndex++, LockedGrayStyle); + AddCell(worksheet, fieldValue, rowIndex, lastColumnIndex++, isReadOnly, isReadOnly, multiLine, isList ? formula : null, numericFieldType, isList); - maxLineCount = AddFieldValueCell(worksheet, true, field, language.LanguageId, languageIdProductDictionary, isVariantProduct, - isList, multipleSelectionList, options, formula, rowIndex, ref lastColumnIndex, - numericFieldType, multiLine, maxLineCount); - } - if (multiLine) - { - maxLineCount = maxLineCount > 0 ? maxLineCount : 1; - worksheet.Row(rowIndex).Height = maxLineCount * 15; - } + foreach (Language language in Languages.Where(l => !string.Equals(l.LanguageId, DefaultLanguage.LanguageId, StringComparison.OrdinalIgnoreCase))) + { + AddCell(worksheet, FieldsHelper.GetFieldTranslation(field, language, DefaultLanguage), rowIndex, lastColumnIndex++, LockedGrayStyle); + + maxLineCount = AddFieldValueCell(worksheet, true, field, language.LanguageId, languageIdProductDictionary, isVariantProduct, + isList, multipleSelectionList, options, formula, rowIndex, ref lastColumnIndex, + numericFieldType, multiLine, maxLineCount); } + if (multiLine) + { + maxLineCount = maxLineCount > 0 ? maxLineCount : 1; + worksheet.Row(rowIndex).Height = maxLineCount * 15; + } + } - /// - /// Exports variants to excel - /// - private void AddProductVariantsRows(ExcelWorksheet worksheet, Dictionary> variantIdLanguageIdVariantProductDictionary, - Product mainProduct, int rowIndex, IEnumerable fields, Dictionary numericFields) + /// + /// Exports variants to excel + /// + private void AddProductVariantsRows(ExcelWorksheet worksheet, Dictionary> variantIdLanguageIdVariantProductDictionary, + Product mainProduct, int rowIndex, IEnumerable fields, Dictionary numericFields) + { + //Process extended variants + if (variantIdLanguageIdVariantProductDictionary.Keys.Count > 0) { - //Process extended variants - if (variantIdLanguageIdVariantProductDictionary.Keys.Count > 0) + List> variantInDefaultLanguageList = new List>(); + + var filteredFields = fields.Where(f => !SkipFields.Contains(f)).ToList(); + List visibleCategoryFields = new List(); + //search for CategoryFields that are visible at least for one product variant + //then they should be shown for the other variants too + foreach (VariantCombination variantCombination in Services.VariantCombinations.GetVariantCombinations(mainProduct.Id)) { - List> variantInDefaultLanguageList = new List>(); + Product variantInDefaultLanguage = Services.Products.GetProductById(mainProduct.Id, variantCombination.VariantId, DefaultLanguage.LanguageId); + variantInDefaultLanguageList.Add(new KeyValuePair(variantCombination.VariantId, variantInDefaultLanguage)); - var filteredFields = fields.Where(f => !SkipFields.Contains(f)).ToList(); - List visibleCategoryFields = new List(); - //search for CategoryFields that are visible at least for one product variant - //then they should be shown for the other variants too - foreach (VariantCombination variantCombination in VariantCombinationService.GetVariantCombinations(mainProduct.Id)) + foreach (string field in filteredFields.Where(f => f.StartsWith("ProductCategory|"))) { - Product variantInDefaultLanguage = ProductService.GetProductById(mainProduct.Id, variantCombination.VariantId, DefaultLanguage.LanguageId); - variantInDefaultLanguageList.Add(new KeyValuePair(variantCombination.VariantId, variantInDefaultLanguage)); - - foreach (string field in filteredFields.Where(f => f.StartsWith("ProductCategory|"))) + if (FieldsHelper.IsFieldVisible(field, variantInDefaultLanguage) && !visibleCategoryFields.Contains(field)) { - if (FieldsHelper.IsFieldVisible(field, variantInDefaultLanguage) && !visibleCategoryFields.Contains(field)) - { - visibleCategoryFields.Add(field); - } + visibleCategoryFields.Add(field); } } + } - int variantIndex = 1; - foreach (KeyValuePair variantInDefaultLanguage in variantInDefaultLanguageList) + int variantIndex = 1; + foreach (KeyValuePair variantInDefaultLanguage in variantInDefaultLanguageList) + { + var languageIdVariantProductDictionary = new Dictionary(); + if (variantIdLanguageIdVariantProductDictionary.ContainsKey(variantInDefaultLanguage.Key)) { - var languageIdVariantProductDictionary = new Dictionary(); - if (variantIdLanguageIdVariantProductDictionary.ContainsKey(variantInDefaultLanguage.Key)) - { - languageIdVariantProductDictionary = variantIdLanguageIdVariantProductDictionary[variantInDefaultLanguage.Key]; - } - //Add variant header - rowIndex++; - AddHeader(worksheet, rowIndex, variantInDefaultLanguage.Value, languageIdVariantProductDictionary); - //variant fields - foreach (string field in filteredFields.Where(f => FieldsHelper.IsFieldVisible(f, variantInDefaultLanguage.Value) || visibleCategoryFields.Contains(f))) + languageIdVariantProductDictionary = variantIdLanguageIdVariantProductDictionary[variantInDefaultLanguage.Key]; + } + //Add variant header + rowIndex++; + AddHeader(worksheet, rowIndex, variantInDefaultLanguage.Value, languageIdVariantProductDictionary); + //variant fields + foreach (string field in filteredFields.Where(f => FieldsHelper.IsFieldVisible(f, variantInDefaultLanguage.Value) || visibleCategoryFields.Contains(f))) + { + if (ShowField(variantInDefaultLanguage.Value, field)) { - if (ShowField(variantInDefaultLanguage.Value, field)) - { - rowIndex++; - AddProductFieldRow(worksheet, rowIndex, variantInDefaultLanguage.Value, languageIdVariantProductDictionary, field, - numericFields.ContainsKey(field) ? numericFields[field] : null); - } + rowIndex++; + AddProductFieldRow(worksheet, rowIndex, variantInDefaultLanguage.Value, languageIdVariantProductDictionary, field, + numericFields.ContainsKey(field) ? numericFields[field] : null); } - variantIndex++; } + variantIndex++; } } - - #endregion ExcelRendering } -} + + #endregion ExcelRendering +} \ No newline at end of file diff --git a/src/PIM/FieldsHelper.cs b/src/PIM/FieldsHelper.cs index b46652a..804960b 100644 --- a/src/PIM/FieldsHelper.cs +++ b/src/PIM/FieldsHelper.cs @@ -1,797 +1,796 @@ -using Dynamicweb.Configuration; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Dynamicweb.Configuration; using Dynamicweb.Content; using Dynamicweb.Core; using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; using Dynamicweb.Ecommerce.Products.Categories; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Reflection; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +internal enum FieldDifferentiationSection { - internal enum FieldDifferentiationSection - { - CommonFields, - ProductFields, - ProductCategories - } + CommonFields, + ProductFields, + ProductCategories +} + +internal enum FieldDifferentiationType +{ + Language, + Variant, + Required, + ReadOnly, + Hidden +} - internal enum FieldDifferentiationType +internal class FieldsHelper +{ + private IEnumerable StandardFields = ProductField.GetStandardProductFields(); + private IEnumerable CustomFields = ProductField.GetProductFields(); + private IEnumerable Categories = Ecommerce.Services.ProductCategories.GetCategories(); + private Lazy ProductProperties = new Lazy(() => typeof(Product).GetProperties()); + private Dictionary isReadOnlyByField = new Dictionary(); + private Dictionary isInheritedFromDefaultByFieldAndLang = new Dictionary(); + + public object GetStandardFieldValue(Product product, string field) { - Language, - Variant, - Required, - ReadOnly, - Hidden + object result = null; + switch (field) + { + case "ProductLanguageID": + case "ProductLanguageId": + result = product.LanguageId; + break; + case "ProductNumber": + result = product.Number; + break; + case "ProductName": + result = product.Name; + break; + case "ProductShortDescription": + result = product.ShortDescription; + break; + case "ProductLongDescription": + result = product.LongDescription; + break; + case "ProductMetaTitle": + result = product.Meta?.Title; + break; + case "ProductMetaKeywords": + result = product.Meta?.Keywords; + break; + case "ProductMetaDescription": + result = product.Meta?.Description; + break; + case "ProductMetaUrl": + result = product.Meta?.Url; + break; + case "ProductMetaCanonical": + result = product.Meta?.Canonical; + break; + case "ProductStock": + result = product.Stock; + break; + case "ProductCost": + result = product.Cost; + break; + case "ProductPrice": + result = product.DefaultPrice; + break; + case "ProductWeight": + result = product.Weight; + break; + case "ProductVolume": + result = product.Volume; + break; + case "ProductActive": + result = product.Active; + break; + case "ProductExcludeFromIndex": + result = product.ExcludeFromIndex; + break; + case "ProductExcludeFromCustomizedUrls": + result = product.ExcludeFromCustomizedUrls; + break; + case "ProductShowInProductList": + result = product.ShowInProductList; + break; + case "ProductWorkflowStateId": + result = product.WorkflowStateId; + break; + case "ProductEAN": + result = product.EAN; + break; + case "ProductWidth": + result = product.Width; + break; + case "ProductHeight": + result = product.Height; + break; + case "ProductDepth": + result = product.Depth; + break; + case "ProductNeverOutOfStock": + result = product.NeverOutOfStock; + break; + case "ProductPurchaseMinimumQuantity": + result = product.PurchaseMinimumQuantity; + break; + case "ProductPurchaseQuantityStep": + result = product.PurchaseQuantityStep; + break; + case "ProductManufacturerID": + result = product.ManufacturerId; + break; + default: + result = GetFieldValue(product, field); + break; + } + return result; } - internal class FieldsHelper + public bool SetStandardFieldValue(Product product, string field, string value) { - private IEnumerable StandardFields = ProductField.GetStandardProductFields(); - private IEnumerable CustomFields = ProductField.GetProductFields(); - private IEnumerable Categories = Ecommerce.Services.ProductCategories.GetCategories(); - private Lazy ProductProperties = new Lazy(() => typeof(Product).GetProperties()); - private Dictionary isReadOnlyByField = new Dictionary(); - private Dictionary isInheritedFromDefaultByFieldAndLang = new Dictionary(); + bool isChanged = false; + double doubleValue; + int intValue; + bool boolValue; - public object GetStandardFieldValue(Product product, string field) + switch (field) { - object result = null; - switch (field) - { - case "ProductLanguageID": - case "ProductLanguageId": - result = product.LanguageId; - break; - case "ProductNumber": - result = product.Number; - break; - case "ProductName": - result = product.Name; - break; - case "ProductShortDescription": - result = product.ShortDescription; - break; - case "ProductLongDescription": - result = product.LongDescription; - break; - case "ProductMetaTitle": - result = product.Meta?.Title; - break; - case "ProductMetaKeywords": - result = product.Meta?.Keywords; - break; - case "ProductMetaDescription": - result = product.Meta?.Description; - break; - case "ProductMetaUrl": - result = product.Meta?.Url; - break; - case "ProductMetaCanonical": - result = product.Meta?.Canonical; - break; - case "ProductStock": - result = product.Stock; - break; - case "ProductCost": - result = product.Cost; - break; - case "ProductPrice": - result = product.DefaultPrice; - break; - case "ProductWeight": - result = product.Weight; - break; - case "ProductVolume": - result = product.Volume; - break; - case "ProductActive": - result = product.Active; - break; - case "ProductExcludeFromIndex": - result = product.ExcludeFromIndex; - break; - case "ProductExcludeFromCustomizedUrls": - result = product.ExcludeFromCustomizedUrls; - break; - case "ProductShowInProductList": - result = product.ShowInProductList; - break; - case "ProductWorkflowStateId": - result = product.WorkflowStateId; - break; - case "ProductEAN": - result = product.EAN; - break; - case "ProductWidth": - result = product.Width; - break; - case "ProductHeight": - result = product.Height; - break; - case "ProductDepth": - result = product.Depth; - break; - case "ProductNeverOutOfStock": - result = product.NeverOutOfStock; - break; - case "ProductPurchaseMinimumQuantity": - result = product.PurchaseMinimumQuantity; - break; - case "ProductPurchaseQuantityStep": - result = product.PurchaseQuantityStep; - break; - case "ProductManufacturerID": - result = product.ManufacturerId; - break; - default: - result = GetFieldValue(product, field); - break; - } - return result; + case "ProductName": + if (!string.Equals(product.Name, value)) + { + product.Name = value; + isChanged = true; + } + break; + case "ProductNumber": + if (!string.Equals(product.Number, value)) + { + product.Number = value; + isChanged = true; + } + break; + case "ProductShortDescription": + if (!string.Equals(product.ShortDescription, value)) + { + product.ShortDescription = value; + isChanged = true; + } + break; + case "ProductLongDescription": + if (!string.Equals(product.LongDescription, value)) + { + product.LongDescription = value; + isChanged = true; + } + break; + case "ProductMetaTitle": + if (product.Meta != null && !string.Equals(product.Meta.Title, value)) + { + product.Meta.Title = value; + isChanged = true; + } + break; + case "ProductMetaKeywords": + if (product.Meta != null && !string.Equals(product.Meta.Keywords, value)) + { + product.Meta.Keywords = value; + isChanged = true; + } + break; + case "ProductMetaDescription": + if (product.Meta != null && !string.Equals(product.Meta.Description, value)) + { + product.Meta.Description = value; + isChanged = true; + } + break; + case "ProductMetaUrl": + if (product.Meta != null && !string.Equals(product.Meta.Url, value)) + { + product.Meta.Url = value; + isChanged = true; + } + break; + case "ProductMetaCanonical": + if (product.Meta != null && !string.Equals(product.Meta.Canonical, value)) + { + product.Meta.Canonical = value; + isChanged = true; + } + break; + case "ProductStock": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Stock != doubleValue) + { + product.Stock = doubleValue; + isChanged = true; + } + break; + case "ProductCost": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Cost != doubleValue) + { + product.Cost = doubleValue; + isChanged = true; + } + break; + case "ProductPrice": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.DefaultPrice != doubleValue) + { + product.DefaultPrice = doubleValue; + isChanged = true; + } + break; + case "ProductWeight": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Weight != doubleValue) + { + product.Weight = doubleValue; + isChanged = true; + } + break; + case "ProductVolume": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Volume != doubleValue) + { + product.Volume = doubleValue; + isChanged = true; + } + break; + case "ProductActive": + boolValue = Converter.ToBoolean(value); + if (!string.IsNullOrEmpty(value) && product.Active != boolValue) + { + product.Active = boolValue; + isChanged = true; + } + break; + case "ProductExcludeFromIndex": + boolValue = Converter.ToBoolean(value); + if (!string.IsNullOrEmpty(value) && product.ExcludeFromIndex != boolValue) + { + product.ExcludeFromIndex = boolValue; + isChanged = true; + } + break; + case "ProductExcludeFromCustomizedUrls": + boolValue = Converter.ToBoolean(value); + if (!string.IsNullOrEmpty(value) && product.ExcludeFromCustomizedUrls != boolValue) + { + product.ExcludeFromCustomizedUrls = boolValue; + isChanged = true; + } + break; + case "ProductShowInProductList": + boolValue = Converter.ToBoolean(value); + if (!string.IsNullOrEmpty(value) && product.ShowInProductList != boolValue) + { + product.ShowInProductList = boolValue; + isChanged = true; + } + break; + case "ProductWorkflowStateId": + if (!string.IsNullOrEmpty(value) && int.TryParse(value, out intValue) && product.WorkflowStateId != intValue) + { + product.WorkflowStateId = Converter.ToInt32(intValue); + isChanged = true; + } + break; + case "ProductEAN": + if (!string.Equals(product.EAN, value)) + { + product.EAN = value; + isChanged = true; + } + break; + case "ProductWidth": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Width != doubleValue) + { + product.Width = doubleValue; + isChanged = true; + } + break; + case "ProductHeight": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Height != doubleValue) + { + product.Height = doubleValue; + isChanged = true; + } + break; + case "ProductDepth": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Depth != doubleValue) + { + product.Depth = doubleValue; + isChanged = true; + } + break; + case "ProductNeverOutOfStock": + boolValue = Converter.ToBoolean(value); + if (!string.IsNullOrEmpty(value) && product.NeverOutOfStock != boolValue) + { + product.NeverOutOfStock = boolValue; + isChanged = true; + } + break; + case "ProductPurchaseMinimumQuantity": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.PurchaseMinimumQuantity != doubleValue) + { + product.PurchaseMinimumQuantity = doubleValue; + isChanged = true; + } + break; + case "ProductPurchaseQuantityStep": + if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.PurchaseQuantityStep != doubleValue) + { + product.PurchaseQuantityStep = doubleValue; + isChanged = true; + } + break; } + return isChanged; + } - public bool SetStandardFieldValue(Product product, string field, string value) - { - bool isChanged = false; - double doubleValue; - int intValue; - bool boolValue; + public bool IsCustomField(string systemName) + { + return CustomFields.Any(f => string.Equals(f.SystemName, GetFieldSystemName(systemName))); + } - switch (field) - { - case "ProductName": - if (!string.Equals(product.Name, value)) - { - product.Name = value; - isChanged = true; - } - break; - case "ProductNumber": - if (!string.Equals(product.Number, value)) - { - product.Number = value; - isChanged = true; - } - break; - case "ProductShortDescription": - if (!string.Equals(product.ShortDescription, value)) - { - product.ShortDescription = value; - isChanged = true; - } - break; - case "ProductLongDescription": - if (!string.Equals(product.LongDescription, value)) - { - product.LongDescription = value; - isChanged = true; - } - break; - case "ProductMetaTitle": - if (product.Meta != null && !string.Equals(product.Meta.Title, value)) - { - product.Meta.Title = value; - isChanged = true; - } - break; - case "ProductMetaKeywords": - if (product.Meta != null && !string.Equals(product.Meta.Keywords, value)) - { - product.Meta.Keywords = value; - isChanged = true; - } - break; - case "ProductMetaDescription": - if (product.Meta != null && !string.Equals(product.Meta.Description, value)) - { - product.Meta.Description = value; - isChanged = true; - } - break; - case "ProductMetaUrl": - if (product.Meta != null && !string.Equals(product.Meta.Url, value)) - { - product.Meta.Url = value; - isChanged = true; - } - break; - case "ProductMetaCanonical": - if (product.Meta != null && !string.Equals(product.Meta.Canonical, value)) - { - product.Meta.Canonical = value; - isChanged = true; - } - break; - case "ProductStock": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Stock != doubleValue) - { - product.Stock = doubleValue; - isChanged = true; - } - break; - case "ProductCost": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Cost != doubleValue) - { - product.Cost = doubleValue; - isChanged = true; - } - break; - case "ProductPrice": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.DefaultPrice != doubleValue) - { - product.DefaultPrice = doubleValue; - isChanged = true; - } - break; - case "ProductWeight": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Weight != doubleValue) - { - product.Weight = doubleValue; - isChanged = true; - } - break; - case "ProductVolume": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Volume != doubleValue) - { - product.Volume = doubleValue; - isChanged = true; - } - break; - case "ProductActive": - boolValue = Converter.ToBoolean(value); - if (!string.IsNullOrEmpty(value) && product.Active != boolValue) - { - product.Active = boolValue; - isChanged = true; - } - break; - case "ProductExcludeFromIndex": - boolValue = Converter.ToBoolean(value); - if (!string.IsNullOrEmpty(value) && product.ExcludeFromIndex != boolValue) - { - product.ExcludeFromIndex = boolValue; - isChanged = true; - } - break; - case "ProductExcludeFromCustomizedUrls": - boolValue = Converter.ToBoolean(value); - if (!string.IsNullOrEmpty(value) && product.ExcludeFromCustomizedUrls != boolValue) - { - product.ExcludeFromCustomizedUrls = boolValue; - isChanged = true; - } - break; - case "ProductShowInProductList": - boolValue = Converter.ToBoolean(value); - if (!string.IsNullOrEmpty(value) && product.ShowInProductList != boolValue) - { - product.ShowInProductList = boolValue; - isChanged = true; - } - break; - case "ProductWorkflowStateId": - if (!string.IsNullOrEmpty(value) && int.TryParse(value, out intValue) && product.WorkflowStateId != intValue) - { - product.WorkflowStateId = Converter.ToInt32(intValue); - isChanged = true; - } - break; - case "ProductEAN": - if (!string.Equals(product.EAN, value)) - { - product.EAN = value; - isChanged = true; - } - break; - case "ProductWidth": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Width != doubleValue) - { - product.Width = doubleValue; - isChanged = true; - } - break; - case "ProductHeight": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Height != doubleValue) - { - product.Height = doubleValue; - isChanged = true; - } - break; - case "ProductDepth": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.Depth != doubleValue) - { - product.Depth = doubleValue; - isChanged = true; - } - break; - case "ProductNeverOutOfStock": - boolValue = Converter.ToBoolean(value); - if (!string.IsNullOrEmpty(value) && product.NeverOutOfStock != boolValue) - { - product.NeverOutOfStock = boolValue; - isChanged = true; - } - break; - case "ProductPurchaseMinimumQuantity": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.PurchaseMinimumQuantity != doubleValue) - { - product.PurchaseMinimumQuantity = doubleValue; - isChanged = true; - } - break; - case "ProductPurchaseQuantityStep": - if (!string.IsNullOrEmpty(value) && double.TryParse(value, out doubleValue) && product.PurchaseQuantityStep != doubleValue) - { - product.PurchaseQuantityStep = doubleValue; - isChanged = true; - } - break; - } - return isChanged; - } + public ProductField GetCustomField(string systemName) + { + return CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, GetFieldSystemName(systemName))); + } - public bool IsCustomField(string systemName) + public Field GetCategoryField(string fieldSystemName, string languageId = null) + { + if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) { - return CustomFields.Any(f => string.Equals(f.SystemName, GetFieldSystemName(systemName))); + return Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryId, fieldId); } + return null; + } + + public string GetFieldSystemName(string fieldSystemName) + { + return fieldSystemName.StartsWith("CustomField_") + ? fieldSystemName.Substring("CustomField_".Length) + : fieldSystemName; + } - public ProductField GetCustomField(string systemName) + public string GetGlobalSettingsFieldSystemName(string fieldSystemName) + { + if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) { - return CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, GetFieldSystemName(systemName))); + return $"{categoryId}.{fieldId}"; } + return GetFieldSystemName(fieldSystemName); + } - public Field GetCategoryField(string fieldSystemName, string languageId = null) + public string GetProductFieldValue(Product product, string fieldSystemName) + { + string result = string.Empty; + ProductField field = null; + if (fieldSystemName.StartsWith("CustomField_")) { - if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + fieldSystemName = GetFieldSystemName(fieldSystemName); + field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); + if (field != null) { - return Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryId, fieldId); + result = Converter.ToString(product.ProductFieldValues?.GetProductFieldValue(fieldSystemName)?.Value); } - return null; } - - public string GetFieldSystemName(string fieldSystemName) + else if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) { - return fieldSystemName.StartsWith("CustomField_") - ? fieldSystemName.Substring("CustomField_".Length) - : fieldSystemName; + result = Converter.ToString(product.GetCategoryValue(categoryId, fieldId, true)); } - - public string GetGlobalSettingsFieldSystemName(string fieldSystemName) + else { - if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + field = StandardFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); + if (field != null) { - return $"{categoryId}.{fieldId}"; + result = Converter.ToString(GetStandardFieldValue(product, fieldSystemName)); } - return GetFieldSystemName(fieldSystemName); } + return result; + } - public string GetProductFieldValue(Product product, string fieldSystemName) + public string GetFieldTranslation(string fieldSystemName, Language language, Language defaultLanguage) + { + string result = fieldSystemName; + ProductField field = null; + if (fieldSystemName.StartsWith("CustomField_")) { - string result = string.Empty; - ProductField field = null; - if (fieldSystemName.StartsWith("CustomField_")) + fieldSystemName = GetFieldSystemName(fieldSystemName); + field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); + if (field != null) { - fieldSystemName = GetFieldSystemName(fieldSystemName); - field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); - if (field != null) - { - result = Converter.ToString(product.ProductFieldValues?.GetProductFieldValue(fieldSystemName)?.Value); - } + result = ProductFieldTranslation.GetTranslatedFieldName(field, language.LanguageId); } - else if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + if (string.IsNullOrEmpty(result)) { - result = Converter.ToString(product.GetCategoryValue(categoryId, fieldId, true)); + result = field != null ? field.Name : fieldSystemName; } - else + } + else if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + { + var categoryField = Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryId, fieldId); + if (categoryField != null) { - field = StandardFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); - if (field != null) - { - result = Converter.ToString(GetStandardFieldValue(product, fieldSystemName)); - } + result = categoryField.GetLabel(language.LanguageId); + } + if (string.IsNullOrEmpty(result)) + { + result = fieldSystemName; } - return result; } - - public string GetFieldTranslation(string fieldSystemName, Language language, Language defaultLanguage) + else { - string result = fieldSystemName; - ProductField field = null; - if (fieldSystemName.StartsWith("CustomField_")) + result = null; + string fieldName = fieldSystemName; + field = StandardFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); + if (field != null) { - fieldSystemName = GetFieldSystemName(fieldSystemName); - field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); - if (field != null) - { - result = ProductFieldTranslation.GetTranslatedFieldName(field, language.LanguageId); - } - if (string.IsNullOrEmpty(result)) - { - result = field != null ? field.Name : fieldSystemName; - } + fieldName = field.Name; } - else if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + result = GetTranslation(language, fieldName); + if (string.IsNullOrEmpty(result) && !string.Equals(language.LanguageId, defaultLanguage.LanguageId)) { - var categoryField = Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryId, fieldId); - if (categoryField != null) - { - result = categoryField.GetLabel(language.LanguageId); - } - if (string.IsNullOrEmpty(result)) - { - result = fieldSystemName; - } + result = GetTranslation(defaultLanguage, fieldName); } - else + if (string.IsNullOrEmpty(result)) { - result = null; - string fieldName = fieldSystemName; - field = StandardFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); - if (field != null) - { - fieldName = field.Name; - } - result = GetTranslation(language, fieldName); - if (string.IsNullOrEmpty(result) && !string.Equals(language.LanguageId, defaultLanguage.LanguageId)) - { - result = GetTranslation(defaultLanguage, fieldName); - } - if (string.IsNullOrEmpty(result)) - { - result = field != null ? field.Name : fieldSystemName; - } + result = field != null ? field.Name : fieldSystemName; } - return result; } + return result; + } - private string GetTranslation(Language language, string key) + private string GetTranslation(Language language, string key) + { + string result = null; + Country country = Ecommerce.Services.Countries.GetCountry(language.CountryCode); + CultureInfo culture = GetCulture(country?.CultureInfo); + if (culture != null) { - string result = null; - Country country = Ecommerce.Services.Countries.GetCountry(language.CountryCode); - CultureInfo culture = GetCulture(country?.CultureInfo); - if (culture != null) + foreach (Area area in Services.Areas.GetAreas()) { - foreach (Area area in Services.Areas.GetAreas()) + Rendering.Designer.Design design = area?.Layout?.Design; + if (design != null) { - Rendering.Designer.Design design = area?.Layout?.Design; - if (design != null) + string translation = Rendering.Translation.Translation.GetTranslation(key, culture, Rendering.Translation.KeyScope.DesignsLocal, design); + if (!string.IsNullOrEmpty(translation) && !string.Equals(translation, key)) { - string translation = Rendering.Translation.Translation.GetTranslation(key, culture, Rendering.Translation.KeyScope.DesignsLocal, design); - if (!string.IsNullOrEmpty(translation) && !string.Equals(translation, key)) - { - result = translation; - break; - } + result = translation; + break; } } } - return result; } + return result; + } - private CultureInfo GetCulture(string name) + private CultureInfo GetCulture(string name) + { + CultureInfo culture = null; + if (!string.IsNullOrEmpty(name)) { - CultureInfo culture = null; - if (!string.IsNullOrEmpty(name)) + try + { + culture = new CultureInfo(name); + } + catch (CultureNotFoundException) { - try - { - culture = new CultureInfo(name); - } - catch (CultureNotFoundException) - { - } } - return culture; } + return culture; + } - public string GetFieldType(string fieldSystemName) + public string GetFieldType(string fieldSystemName) + { + string result = string.Empty; + if (fieldSystemName.StartsWith("CustomField_")) { - string result = string.Empty; - if (fieldSystemName.StartsWith("CustomField_")) + fieldSystemName = fieldSystemName.Substring("CustomField_".Length); + ProductField field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); + if (field != null) { - fieldSystemName = fieldSystemName.Substring("CustomField_".Length); - ProductField field = CustomFields.FirstOrDefault(f => string.Equals(f.SystemName, fieldSystemName)); - if (field != null) - { - result = field.TypeName; - } + result = field.TypeName; } - else if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) - { - result = Ecommerce.Services.ProductCategories.GetFieldsByCategoryId(Categories.FirstOrDefault(c => string.Equals(c.Id, categoryId))?.Id).FirstOrDefault(f => string.Equals(f.Id, fieldId))?.Type; - var fieldType = Ecommerce.Services.FieldType.GetFieldTypes(true).FirstOrDefault(t => t.Id == Converter.ToInt32(result)); - result = fieldType != null ? fieldType.DynamicwebAlias : result; - } - else - { - result = GetStandardFieldType(fieldSystemName); - } - return result; } + else if (Field.TryParseUniqueId(fieldSystemName, out var categoryId, out var fieldId)) + { + result = Ecommerce.Services.ProductCategories.GetFieldsByCategoryId(Categories.FirstOrDefault(c => string.Equals(c.Id, categoryId))?.Id).FirstOrDefault(f => string.Equals(f.Id, fieldId))?.Type; + var fieldType = Ecommerce.Services.FieldType.GetFieldTypes(true).FirstOrDefault(t => t.Id == Converter.ToInt32(result)); + result = fieldType != null ? fieldType.DynamicwebAlias : result; + } + else + { + result = GetStandardFieldType(fieldSystemName); + } + return result; + } - public string GetStandardFieldType(string field) + public string GetStandardFieldType(string field) + { + switch (field) { - switch (field) - { - case "ProductLongDescription": - case "ProductShortDescription": - return "EditorText"; - - case "ProductStock": - case "ProductWorkflowStateId": - return "Integer"; - - case "ProductCost": - case "ProductPrice": - case "ProductWeight": - case "ProductVolume": - case "ProductWidth": - case "ProductHeight": - case "ProductDepth": - case "ProductPurchaseMinimumQuantity": - case "ProductPurchaseQuantityStep": - return "Double"; - - case "ProductActive": - case "ProductExcludeFromIndex": - case "ProductExcludeFromCustomizedUrls": - case "ProductExcludeFromAllProducts": - case "ProductShowInProductList": - case "ProductNeverOutOfStock": - return "Bool"; - - default: - return "Text"; - } + case "ProductLongDescription": + case "ProductShortDescription": + return "EditorText"; + + case "ProductStock": + case "ProductWorkflowStateId": + return "Integer"; + + case "ProductCost": + case "ProductPrice": + case "ProductWeight": + case "ProductVolume": + case "ProductWidth": + case "ProductHeight": + case "ProductDepth": + case "ProductPurchaseMinimumQuantity": + case "ProductPurchaseQuantityStep": + return "Double"; + + case "ProductActive": + case "ProductExcludeFromIndex": + case "ProductExcludeFromCustomizedUrls": + case "ProductExcludeFromAllProducts": + case "ProductShowInProductList": + case "ProductNeverOutOfStock": + return "Bool"; + + default: + return "Text"; } + } - public bool IsFieldVisible(string fieldName) + public bool IsFieldVisible(string fieldName) + { + FieldDifferentiationSection section = GetFieldSection(fieldName); + if (section == FieldDifferentiationSection.ProductCategories) { - FieldDifferentiationSection section = GetFieldSection(fieldName); - if (section == FieldDifferentiationSection.ProductCategories) - { - Field field = GetCategoryField(fieldName); - return field != null ? !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(field.Category.Id + "." + field.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.Hidden))) : false; - } - else - { - fieldName = GetFieldSystemName(fieldName); - return !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Hidden))); - } + Field field = GetCategoryField(fieldName); + return field != null ? !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(field.Category.Id + "." + field.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.Hidden))) : false; + } + else + { + fieldName = GetFieldSystemName(fieldName); + return !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Hidden))); } + } - internal bool IsFieldVisible(string fieldName, Product product) + internal bool IsFieldVisible(string fieldName, Product product) + { + if (IsFieldVisible(fieldName)) { - if (IsFieldVisible(fieldName)) + if (fieldName.StartsWith("ProductCategory|")) { - if (fieldName.StartsWith("ProductCategory|")) - { - Field field = GetCategoryField(fieldName); + Field field = GetCategoryField(fieldName); - return Ecommerce.Services.ProductCategories.ShowField(field, product); - } - return true; + return Ecommerce.Services.ProductCategories.ShowField(field, product); } + return true; + } - return false; + return false; + } + + public bool IsFieldInherited(string fieldName, bool variantProduct, string langId) + { + bool ret = false; + FieldDifferentiationSection section = GetFieldSection(fieldName); + fieldName = GetGlobalSettingsFieldSystemName(fieldName); + if (variantProduct && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Variant)))) + { + ret = true; + } + else if (!string.IsNullOrEmpty(langId) && langId != Ecommerce.Services.Languages.GetDefaultLanguageId() && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Language)))) + { + ret = true; } + return ret; + } - public bool IsFieldInherited(string fieldName, bool variantProduct, string langId) + public bool IsFieldInheritedFromDefaultLanguage(string fieldName, string langId) + { + bool isInheritedFromDefault = false; + var key = $"{langId}-|-{fieldName}"; + if (!isInheritedFromDefaultByFieldAndLang.TryGetValue(key, out isInheritedFromDefault)) { - bool ret = false; FieldDifferentiationSection section = GetFieldSection(fieldName); fieldName = GetGlobalSettingsFieldSystemName(fieldName); - if (variantProduct && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Variant)))) + if (!string.IsNullOrEmpty(langId) && langId != Ecommerce.Services.Languages.GetDefaultLanguageId() && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Language)))) { - ret = true; + isInheritedFromDefault = true; } - else if (!string.IsNullOrEmpty(langId) && langId != Ecommerce.Services.Languages.GetDefaultLanguageId() && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Language)))) - { - ret = true; - } - return ret; + isInheritedFromDefaultByFieldAndLang.Add(key, isInheritedFromDefault); } + return isInheritedFromDefault; + } - public bool IsFieldInheritedFromDefaultLanguage(string fieldName, string langId) + public bool IsVariantEditingAllowed(string fieldName) + { + return Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(GetGlobalSettingsFieldSystemName(fieldName), GetFieldSection(fieldName), FieldDifferentiationType.Variant))); + } + public bool IsCategoryFieldVariantEditingAllowed(Field field) + { + return Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(field.Category.Id + "." + field.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.Variant))); + } + + public bool IsFieldReadOnly(string fieldName) + { + bool isReadOnly = false; + var sysFieldName = fieldName; + if (!isReadOnlyByField.TryGetValue(sysFieldName, out isReadOnly)) { - bool isInheritedFromDefault = false; - var key = $"{langId}-|-{fieldName}"; - if (!isInheritedFromDefaultByFieldAndLang.TryGetValue(key, out isInheritedFromDefault)) + FieldDifferentiationSection section = GetFieldSection(fieldName); + if (section == FieldDifferentiationSection.ProductCategories) { - FieldDifferentiationSection section = GetFieldSection(fieldName); - fieldName = GetGlobalSettingsFieldSystemName(fieldName); - if (!string.IsNullOrEmpty(langId) && langId != Ecommerce.Services.Languages.GetDefaultLanguageId() && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.Language)))) - { - isInheritedFromDefault = true; - } - isInheritedFromDefaultByFieldAndLang.Add(key, isInheritedFromDefault); + Field categoryField = GetCategoryField(fieldName); + isReadOnly = categoryField != null ? Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(categoryField.Category.Id + "." + categoryField.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.ReadOnly))) : true; + } + else + { + fieldName = GetFieldSystemName(fieldName); + isReadOnly = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.ReadOnly))); ; } - return isInheritedFromDefault; + isReadOnlyByField.Add(sysFieldName, isReadOnly); } + return isReadOnly; + } + - public bool IsVariantEditingAllowed(string fieldName) + public bool IsCategoryFieldInherited(Field field, bool entryIsProductVariant, string entryLangId) + { + bool ret = false; + if (entryIsProductVariant && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(string.Format("/Globalsettings/Ecom/ProductCategoriesLanguageControl/Variant/{0}", field.Category.Id + "." + field.Id)))) { - return Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(GetGlobalSettingsFieldSystemName(fieldName), GetFieldSection(fieldName), FieldDifferentiationType.Variant))); + ret = true; } - public bool IsCategoryFieldVariantEditingAllowed(Field field) + else if (entryLangId != Ecommerce.Services.Languages.GetDefaultLanguageId() && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(string.Format("/Globalsettings/Ecom/ProductCategoriesLanguageControl/Language/{0}", field.Category.Id + "." + field.Id)))) { - return Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(field.Category.Id + "." + field.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.Variant))); + ret = true; } + return ret; + } + + public bool IsCategoryFieldReadOnly(Field field) + { + bool ret = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(field.Category.Id + "." + field.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.ReadOnly))); + return ret; + } - public bool IsFieldReadOnly(string fieldName) + public object GetCategoryFieldValue(Product product, Field field) + { + object fieldValue = product.GetCategoryValue(field.Category.Id, field.Id, false); + if (fieldValue == null) { - bool isReadOnly = false; - var sysFieldName = fieldName; - if (!isReadOnlyByField.TryGetValue(sysFieldName, out isReadOnly)) - { - FieldDifferentiationSection section = GetFieldSection(fieldName); - if (section == FieldDifferentiationSection.ProductCategories) - { - Field categoryField = GetCategoryField(fieldName); - isReadOnly = categoryField != null ? Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(categoryField.Category.Id + "." + categoryField.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.ReadOnly))) : true; - } - else - { - fieldName = GetFieldSystemName(fieldName); - isReadOnly = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(fieldName, section, FieldDifferentiationType.ReadOnly))); ; - } - isReadOnlyByField.Add(sysFieldName, isReadOnly); - } - return isReadOnly; + //default value + fieldValue = Ecommerce.Services.ProductCategories.GetProductCategoryFieldValue(product, field); } + return fieldValue; + } - - public bool IsCategoryFieldInherited(Field field, bool entryIsProductVariant, string entryLangId) + public FieldDifferentiationSection GetFieldSection(string fieldSystemName) + { + if (fieldSystemName.StartsWith("CustomField_")) { - bool ret = false; - if (entryIsProductVariant && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(string.Format("/Globalsettings/Ecom/ProductCategoriesLanguageControl/Variant/{0}", field.Category.Id + "." + field.Id)))) - { - ret = true; - } - else if (entryLangId != Ecommerce.Services.Languages.GetDefaultLanguageId() && !Converter.ToBoolean(SystemConfiguration.Instance.GetValue(string.Format("/Globalsettings/Ecom/ProductCategoriesLanguageControl/Language/{0}", field.Category.Id + "." + field.Id)))) - { - ret = true; - } - return ret; + return FieldDifferentiationSection.ProductFields; } - - public bool IsCategoryFieldReadOnly(Field field) + else if (fieldSystemName.StartsWith("ProductCategory|")) { - bool ret = Converter.ToBoolean(SystemConfiguration.Instance.GetValue(GetFieldCheckSettingKeyFor(field.Category.Id + "." + field.Id, FieldDifferentiationSection.ProductCategories, FieldDifferentiationType.ReadOnly))); - return ret; + return FieldDifferentiationSection.ProductCategories; } + else + { + return FieldDifferentiationSection.CommonFields; + } + } - public object GetCategoryFieldValue(Product product, Field field) + public string GetFieldCheckSettingKeyFor(string fieldName, FieldDifferentiationSection diffType, FieldDifferentiationType fieldType) + { + string keyPart1 = string.Empty; + string keyPart2 = string.Empty; + if (fieldType == FieldDifferentiationType.Language || fieldType == FieldDifferentiationType.Variant) { - object fieldValue = product.GetCategoryValue(field.Category.Id, field.Id, false); - if (fieldValue == null) - { - //default value - fieldValue = Ecommerce.Services.ProductCategories.GetProductCategoryFieldValue(product, field); - } - return fieldValue; + keyPart1 = diffType == FieldDifferentiationSection.ProductCategories ? "ProductCategoriesLanguageControl/" : "ProductLanguageControl/"; + keyPart2 = fieldType == FieldDifferentiationType.Language ? "Language/" : "Variant/"; + } + else + { + keyPart1 = fieldType.ToString() + "/"; + keyPart2 = diffType.ToString() + "/"; } + return string.Format("/Globalsettings/Ecom/{0}{1}{2}", keyPart1, keyPart2, fieldName); + } - public FieldDifferentiationSection GetFieldSection(string fieldSystemName) + public Type GetNumericFieldType(string field) + { + Type fieldType = null; + ProductField customField = GetCustomField(field); + if (customField != null) { - if (fieldSystemName.StartsWith("CustomField_")) + if (customField.TypeId == 6) { - return FieldDifferentiationSection.ProductFields; + fieldType = typeof(int); } - else if (fieldSystemName.StartsWith("ProductCategory|")) + else if (customField.TypeId == 7) { - return FieldDifferentiationSection.ProductCategories; - } - else - { - return FieldDifferentiationSection.CommonFields; + fieldType = typeof(double); } } - - public string GetFieldCheckSettingKeyFor(string fieldName, FieldDifferentiationSection diffType, FieldDifferentiationType fieldType) + else { - string keyPart1 = string.Empty; - string keyPart2 = string.Empty; - if (fieldType == FieldDifferentiationType.Language || fieldType == FieldDifferentiationType.Variant) + string type = null; + var categoryField = GetCategoryField(field); + if (categoryField != null) { - keyPart1 = diffType == FieldDifferentiationSection.ProductCategories ? "ProductCategoriesLanguageControl/" : "ProductLanguageControl/"; - keyPart2 = fieldType == FieldDifferentiationType.Language ? "Language/" : "Variant/"; + type = categoryField.Type; } else { - keyPart1 = fieldType.ToString() + "/"; - keyPart2 = diffType.ToString() + "/"; + type = GetStandardFieldType(field); } - return string.Format("/Globalsettings/Ecom/{0}{1}{2}", keyPart1, keyPart2, fieldName); - } - - public Type GetNumericFieldType(string field) - { - Type fieldType = null; - ProductField customField = GetCustomField(field); - if (customField != null) + if (!string.IsNullOrEmpty(type)) { - if (customField.TypeId == 6) + if (string.Equals(type, "Integer") || string.Equals(type, "6")) { fieldType = typeof(int); } - else if (customField.TypeId == 7) + else if (string.Equals(type, "Double") || string.Equals(type, "7")) { fieldType = typeof(double); } - } - else - { - string type = null; - var categoryField = GetCategoryField(field); - if (categoryField != null) - { - type = categoryField.Type; - } - else - { - type = GetStandardFieldType(field); - } - if (!string.IsNullOrEmpty(type)) + else if (string.Equals(type, "Decimal")) { - if (string.Equals(type, "Integer") || string.Equals(type, "6")) - { - fieldType = typeof(int); - } - else if (string.Equals(type, "Double") || string.Equals(type, "7")) - { - fieldType = typeof(double); - } - else if (string.Equals(type, "Decimal")) - { - fieldType = typeof(decimal); - } + fieldType = typeof(decimal); } } - return fieldType; } + return fieldType; + } - public bool IsNumericValueValid(string value, Type numericType) + public bool IsNumericValueValid(string value, Type numericType) + { + bool isValid = true; + if (!string.IsNullOrEmpty(value)) { - bool isValid = true; - if (!string.IsNullOrEmpty(value)) + if (numericType == typeof(int)) { - if (numericType == typeof(int)) - { - int i; - isValid = int.TryParse(value, out i); - } - else if (numericType == typeof(double)) - { - double i; - isValid = double.TryParse(value, out i); - } - else if (numericType == typeof(decimal)) - { - decimal i; - isValid = decimal.TryParse(value, out i); - } + int i; + isValid = int.TryParse(value, out i); + } + else if (numericType == typeof(double)) + { + double i; + isValid = double.TryParse(value, out i); + } + else if (numericType == typeof(decimal)) + { + decimal i; + isValid = decimal.TryParse(value, out i); } - return isValid; } + return isValid; + } - private object GetFieldValue(Product product, string fieldName) + private object GetFieldValue(Product product, string fieldName) + { + object result = null; + if (!string.IsNullOrEmpty(fieldName) && ProductProperties.Value != null) { - object result = null; - if (!string.IsNullOrEmpty(fieldName) && ProductProperties.Value != null) + string shortName = fieldName.StartsWith("Product") ? fieldName.Substring("Product".Length) : fieldName; + var property = ProductProperties.Value.FirstOrDefault(p => p != null && string.Equals(p.Name, shortName, StringComparison.OrdinalIgnoreCase)); + if (property != null) { - string shortName = fieldName.StartsWith("Product") ? fieldName.Substring("Product".Length) : fieldName; - var property = ProductProperties.Value.FirstOrDefault(p => p != null && string.Equals(p.Name, shortName, StringComparison.OrdinalIgnoreCase)); - if (property != null) - { - result = property.GetValue(product); - } + result = property.GetValue(product); } - return result; } + return result; } -} +} \ No newline at end of file diff --git a/src/PIM/IExportExcelProvider.cs b/src/PIM/IExportExcelProvider.cs index 6ae4f59..1008bae 100644 --- a/src/PIM/IExportExcelProvider.cs +++ b/src/PIM/IExportExcelProvider.cs @@ -1,23 +1,22 @@ using System.Collections.Generic; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +/// +/// Export to excel provider +/// +public interface IExportExcelProvider { /// - /// Export to excel provider + /// Export product to excel /// - public interface IExportExcelProvider - { - /// - /// Export product to excel - /// - /// excel file - /// product id - /// variant id - /// exported languages ids - /// fields to export - /// export status - /// - bool ExportProduct(string file, string productId, string productVariantId, IEnumerable languages, IEnumerable fields, out string status); - bool ExportProducts(string file, IEnumerable productIds, IEnumerable languages, IEnumerable fields, out string status); - } -} + /// excel file + /// product id + /// variant id + /// exported languages ids + /// fields to export + /// export status + /// + bool ExportProduct(string file, string productId, string productVariantId, IEnumerable languages, IEnumerable fields, out string status); + bool ExportProducts(string file, IEnumerable productIds, IEnumerable languages, IEnumerable fields, out string status); +} \ No newline at end of file diff --git a/src/PIM/IImportExcelProvider.cs b/src/PIM/IImportExcelProvider.cs index 31dd63f..e5b04fc 100644 --- a/src/PIM/IImportExcelProvider.cs +++ b/src/PIM/IImportExcelProvider.cs @@ -1,59 +1,58 @@ -using Dynamicweb.Ecommerce.Variants; -using System.Collections.Generic; +using System.Collections.Generic; +using Dynamicweb.Ecommerce.Variants; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +/// +/// Import product from excel provider +/// +public interface IImportExcelProvider { /// - /// Import product from excel provider + /// Gets product id from excel file + /// + /// + string GetProductId(); + + /// + /// Gets product languages ids from excel file + /// + /// + IEnumerable GetLanguages(); + + /// + /// Gets product fields from excel file + /// + /// + IEnumerable GetFields(); + + /// + /// Gets product not valid fields + /// + /// language id to get not valid fields from + /// + IEnumerable GetInvalidFields(string languageId); + + /// + /// Gets product simple variants that need to be extended for successful import + /// + /// language id to get not valid variants from + /// + Dictionary> GetSimpleVariants(IEnumerable languages); + + /// + /// Import product from excel + /// + /// languages to import product to + /// create extended variants automatically + /// import status message + /// + bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status); + + /// + /// Load excel file data /// - public interface IImportExcelProvider - { - /// - /// Gets product id from excel file - /// - /// - string GetProductId(); - - /// - /// Gets product languages ids from excel file - /// - /// - IEnumerable GetLanguages(); - - /// - /// Gets product fields from excel file - /// - /// - IEnumerable GetFields(); - - /// - /// Gets product not valid fields - /// - /// language id to get not valid fields from - /// - IEnumerable GetInvalidFields(string languageId); - - /// - /// Gets product simple variants that need to be extended for successful import - /// - /// language id to get not valid variants from - /// - Dictionary> GetSimpleVariants(IEnumerable languages); - - /// - /// Import product from excel - /// - /// languages to import product to - /// create extended variants automatically - /// import status message - /// - bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status); - - /// - /// Load excel file data - /// - /// excel file content - /// - bool LoadExcel(byte[] excelData); - } -} + /// excel file content + /// + bool LoadExcel(byte[] excelData); +} \ No newline at end of file diff --git a/src/PIM/ImportExcelProvider.cs b/src/PIM/ImportExcelProvider.cs index 608012c..160a9e1 100644 --- a/src/PIM/ImportExcelProvider.cs +++ b/src/PIM/ImportExcelProvider.cs @@ -1,99 +1,98 @@ -using Dynamicweb.Ecommerce.Variants; -using System; +using System; using System.Collections.Generic; +using Dynamicweb.Ecommerce.Variants; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +/// +/// Import from Excel provider +/// +public class ImportExcelProvider : IImportExcelProvider, IDisposable { - /// - /// Import from Excel provider - /// - public class ImportExcelProvider : IImportExcelProvider, IDisposable - { - private BaseImportExcelProvider BaseImportExcelProvider = null; + private BaseImportExcelProvider BaseImportExcelProvider = null; - public ImportExcelProvider() - { - } + public ImportExcelProvider() + { + } - public void Dispose() - { - BaseImportExcelProvider.Dispose(); - } + public void Dispose() + { + BaseImportExcelProvider.Dispose(); + } - /// - /// Gets product fields from excel file - /// - /// - public IEnumerable GetFields() - { - return BaseImportExcelProvider.GetFields(); - } + /// + /// Gets product fields from excel file + /// + /// + public IEnumerable GetFields() + { + return BaseImportExcelProvider.GetFields(); + } - /// - /// Gets product languages ids from excel file - /// - /// - public IEnumerable GetLanguages() - { - return BaseImportExcelProvider.GetLanguages(); - } + /// + /// Gets product languages ids from excel file + /// + /// + public IEnumerable GetLanguages() + { + return BaseImportExcelProvider.GetLanguages(); + } - /// - /// Gets product ids from excel file - /// - /// - public string GetProductId() - { - return BaseImportExcelProvider.GetProductId(); - } + /// + /// Gets product ids from excel file + /// + /// + public string GetProductId() + { + return BaseImportExcelProvider.GetProductId(); + } - /// - /// Gets product simple variants that need to be extended for successful import - /// - /// language id to get not valid variants from - /// - public Dictionary> GetSimpleVariants(IEnumerable languages) - { - return BaseImportExcelProvider.GetSimpleVariants(languages); - } + /// + /// Gets product simple variants that need to be extended for successful import + /// + /// language id to get not valid variants from + /// + public Dictionary> GetSimpleVariants(IEnumerable languages) + { + return BaseImportExcelProvider.GetSimpleVariants(languages); + } - /// - /// Import product from excel - /// - /// languages to import product to - /// create extended variants automatically - /// import status message - /// - public bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status) - { - return BaseImportExcelProvider.Import(languages, autoCreateExtendedVariants, out status); - } + /// + /// Import product from excel + /// + /// languages to import product to + /// create extended variants automatically + /// import status message + /// + public bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status) + { + return BaseImportExcelProvider.Import(languages, autoCreateExtendedVariants, out status); + } - /// - /// Load excel file data - /// - /// excel file content - /// - public bool LoadExcel(byte[] excelData) + /// + /// Load excel file data + /// + /// excel file content + /// + public bool LoadExcel(byte[] excelData) + { + BaseImportExcelProvider = new ImportMultipleProductsExcelProvider(); + bool isLoaded = BaseImportExcelProvider.LoadExcel(excelData); + if (!isLoaded) { - BaseImportExcelProvider = new ImportMultipleProductsExcelProvider(); - bool isLoaded = BaseImportExcelProvider.LoadExcel(excelData); - if (!isLoaded) - { - BaseImportExcelProvider = new ImportOneProductExcelProvider(); - isLoaded = BaseImportExcelProvider.LoadExcel(excelData); - } - return isLoaded; + BaseImportExcelProvider = new ImportOneProductExcelProvider(); + isLoaded = BaseImportExcelProvider.LoadExcel(excelData); } - - /// - /// Gets product not valid fields - /// - /// language id to get not valid fields from - /// - public IEnumerable GetInvalidFields(string languageId) - { - return BaseImportExcelProvider.GetInvalidFields(languageId); - } + return isLoaded; } -} + + /// + /// Gets product not valid fields + /// + /// language id to get not valid fields from + /// + public IEnumerable GetInvalidFields(string languageId) + { + return BaseImportExcelProvider.GetInvalidFields(languageId); + } +} \ No newline at end of file diff --git a/src/PIM/ImportMultipleProductsExcelProvider.cs b/src/PIM/ImportMultipleProductsExcelProvider.cs index ff29040..735db68 100644 --- a/src/PIM/ImportMultipleProductsExcelProvider.cs +++ b/src/PIM/ImportMultipleProductsExcelProvider.cs @@ -1,107 +1,106 @@ -using Dynamicweb.Ecommerce.International; -using Dynamicweb.Ecommerce.Products; -using Dynamicweb.Ecommerce.Variants; -using OfficeOpenXml; -using System; +using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; +using Dynamicweb.Ecommerce; +using Dynamicweb.Ecommerce.International; +using Dynamicweb.Ecommerce.Products; +using Dynamicweb.Ecommerce.Variants; +using OfficeOpenXml; +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +internal class ImportMultipleProductsExcelProvider : BaseImportExcelProvider { - internal class ImportMultipleProductsExcelProvider : BaseImportExcelProvider + private List ProductIds = null; + private Dictionary> _fieldLanguageIdColumnIndexDictionary = null; + private List _fields = null; + private Dictionary> _languageIdInvalidFieldDictionary = null; + + /// + /// Gets product fields from excel file + /// + /// + public override IEnumerable GetFields() { - private List ProductIds = null; - private Dictionary> _fieldLanguageIdColumnIndexDictionary = null; - private List _fields = null; - private Dictionary> _languageIdInvalidFieldDictionary = null; - - /// - /// Gets product fields from excel file - /// - /// - public override IEnumerable GetFields() + if (_fields == null) { - if (_fields == null) - { - _fields = FieldLanguageIdColumnIndexDictionary.Keys.ToList(); - _fields = _fields.Distinct().ToList(); - } - return _fields; + _fields = FieldLanguageIdColumnIndexDictionary.Keys.ToList(); + _fields = _fields.Distinct().ToList(); } + return _fields; + } - /// - /// Gets product languages ids from excel file - /// - /// - public override IEnumerable GetLanguages() + /// + /// Gets product languages ids from excel file + /// + /// + public override IEnumerable GetLanguages() + { + List result = new List(); + if (Worksheet != null) { - List result = new List(); - if (Worksheet != null) + var end = Worksheet.Dimension.End; + for (int col = 3; col <= end.Column; col++) { - var end = Worksheet.Dimension.End; - for (int col = 3; col <= end.Column; col++) + string languageId = Worksheet.Cells[2, col].Comment?.Text; + if (!string.IsNullOrEmpty(languageId) && !result.Contains(languageId)) { - string languageId = Worksheet.Cells[2, col].Comment?.Text; - if (!string.IsNullOrEmpty(languageId) && !result.Contains(languageId)) - { - result.Add(languageId); - } + result.Add(languageId); } } - return result; } + return result; + } - /// - /// Gets product ids from excel file - /// - /// - public override string GetProductId() - { - return string.Join(",", GetProductIds()); - } + /// + /// Gets product ids from excel file + /// + /// + public override string GetProductId() + { + return string.Join(",", GetProductIds()); + } - /// - /// Gets product simple variants that need to be extended for successful import - /// - /// language id to get not valid variants from - /// - public override Dictionary> GetSimpleVariants(IEnumerable languages) - { - var failedVariants = new Dictionary>(); - IEnumerable languagesToImport = LanguageService.GetLanguages().Where(l => languages.Contains(l.LanguageId)); + /// + /// Gets product simple variants that need to be extended for successful import + /// + /// language id to get not valid variants from + /// + public override Dictionary> GetSimpleVariants(IEnumerable languages) + { + var failedVariants = new Dictionary>(); + IEnumerable languagesToImport = Services.Languages.GetLanguages().Where(l => languages.Contains(l.LanguageId)); - foreach (string productId in ProductIds) + foreach (string productId in ProductIds) + { + int row = Worksheet.GetProductRow(productId); + if (row > 0) { - int row = Worksheet.GetProductRow(productId); - if (row > 0) + var fieldLanguageIdValues = GetFieldLanguageIdValues(row); + if (fieldLanguageIdValues.Keys.Count > 0) { - var fieldLanguageIdValues = GetFieldLanguageIdValues(row); - if (fieldLanguageIdValues.Keys.Count > 0) - { - failedVariants = GetInvalidVariantsFromProduct(productId, null, languagesToImport, fieldLanguageIdValues); - } + failedVariants = GetInvalidVariantsFromProduct(productId, null, languagesToImport, fieldLanguageIdValues); + } - foreach (KeyValuePair variantIdRowIndexPair in GetVariantProductRows(productId)) + foreach (KeyValuePair variantIdRowIndexPair in GetVariantProductRows(productId)) + { + fieldLanguageIdValues = GetFieldLanguageIdValues(variantIdRowIndexPair.Value); + if (fieldLanguageIdValues.Keys.Count > 0) { - fieldLanguageIdValues = GetFieldLanguageIdValues(variantIdRowIndexPair.Value); - if (fieldLanguageIdValues.Keys.Count > 0) + foreach (var kvp in GetInvalidVariantsFromProduct(productId, variantIdRowIndexPair.Key, languagesToImport, fieldLanguageIdValues)) { - foreach (var kvp in GetInvalidVariantsFromProduct(productId, variantIdRowIndexPair.Key, languagesToImport, fieldLanguageIdValues)) + if (!failedVariants.ContainsKey(kvp.Key)) { - if (!failedVariants.ContainsKey(kvp.Key)) - { - failedVariants.Add(kvp.Key, kvp.Value); - } - else + failedVariants.Add(kvp.Key, kvp.Value); + } + else + { + foreach (var combination in kvp.Value) { - foreach (var combination in kvp.Value) + if (!failedVariants[kvp.Key].Any(vc => string.Equals(vc.VariantId, variantIdRowIndexPair.Key, StringComparison.InvariantCultureIgnoreCase))) { - if (!failedVariants[kvp.Key].Any(vc => string.Equals(vc.VariantId, variantIdRowIndexPair.Key, StringComparison.InvariantCultureIgnoreCase))) - { - failedVariants[kvp.Key].Add(combination); - } + failedVariants[kvp.Key].Add(combination); } } } @@ -109,286 +108,286 @@ public override Dictionary> GetSimpleVariants( } } } - return failedVariants; } + return failedVariants; + } - /// - /// Import product from excel - /// - /// languages to import product to - /// create extended variants automatically - /// import status message - /// - public override bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status) - { - bool result = true; - status = null; + /// + /// Import product from excel + /// + /// languages to import product to + /// create extended variants automatically + /// import status message + /// + public override bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status) + { + bool result = true; + status = null; - if (Worksheet != null) + if (Worksheet != null) + { + try { - try - { - IEnumerable languagesToImport = LanguageService.GetLanguages().Where(l => languages.Contains(l.LanguageId)); - Dictionary> failedVariants = GetSimpleVariants(languages); + IEnumerable languagesToImport = Services.Languages.GetLanguages().Where(l => languages.Contains(l.LanguageId)); + Dictionary> failedVariants = GetSimpleVariants(languages); - foreach (string productId in ProductIds) + foreach (string productId in ProductIds) + { + int row = Worksheet.GetProductRow(productId); + if (row > 0) { - int row = Worksheet.GetProductRow(productId); - if (row > 0) + var fieldLanguageIdValues = GetFieldLanguageIdValues(row); + if (fieldLanguageIdValues.Keys.Count > 0) { - var fieldLanguageIdValues = GetFieldLanguageIdValues(row); - if (fieldLanguageIdValues.Keys.Count > 0) - { - UpdateProduct(productId, null, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, failedVariants); - } + UpdateProduct(productId, null, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, failedVariants); + } - var variantProductRows = GetVariantProductRows(productId); - foreach (string variantId in variantProductRows.Keys) + var variantProductRows = GetVariantProductRows(productId); + foreach (string variantId in variantProductRows.Keys) + { + fieldLanguageIdValues = GetFieldLanguageIdValues(variantProductRows[variantId]); + if (fieldLanguageIdValues.Keys.Count > 0) { - fieldLanguageIdValues = GetFieldLanguageIdValues(variantProductRows[variantId]); - if (fieldLanguageIdValues.Keys.Count > 0) - { - UpdateProduct(productId, variantId, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, - failedVariants); - } + UpdateProduct(productId, variantId, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, + failedVariants); } } } } - catch (Exception ex) - { - status += $"Error occured: {ex.Message}. "; - status += !string.IsNullOrEmpty(ex.StackTrace) ? $"Stack: {ex.StackTrace}. " : string.Empty; - result = false; - } } - else + catch (Exception ex) { - status = "Worksheet is not found."; + status += $"Error occured: {ex.Message}. "; + status += !string.IsNullOrEmpty(ex.StackTrace) ? $"Stack: {ex.StackTrace}. " : string.Empty; + result = false; } - - return result; } + else + { + status = "Worksheet is not found."; + } + + return result; + } - /// - /// Load excel file data - /// - /// excel file content - /// - public override bool LoadExcel(byte[] excelData) + /// + /// Load excel file data + /// + /// excel file content + /// + public override bool LoadExcel(byte[] excelData) + { + bool isLoaded = base.LoadExcel(excelData); + if(isLoaded) { - bool isLoaded = base.LoadExcel(excelData); - if(isLoaded) + bool isMultipleProductsExcelFormat = false; + if (Worksheet != null) { - bool isMultipleProductsExcelFormat = false; - if (Worksheet != null) - { - isMultipleProductsExcelFormat = string.IsNullOrEmpty(Worksheet.Cells[2, 1].Text) && string.IsNullOrEmpty(Worksheet.Cells[2, 2].Text); - } - if (isMultipleProductsExcelFormat) - { - ProductIds = GetProductIds(); - } - isLoaded = isMultipleProductsExcelFormat; + isMultipleProductsExcelFormat = string.IsNullOrEmpty(Worksheet.Cells[2, 1].Text) && string.IsNullOrEmpty(Worksheet.Cells[2, 2].Text); } - return isLoaded; + if (isMultipleProductsExcelFormat) + { + ProductIds = GetProductIds(); + } + isLoaded = isMultipleProductsExcelFormat; } + return isLoaded; + } - /// - /// Gets product not valid fields - /// - /// language id to get not valid fields from - /// - public override IEnumerable GetInvalidFields(string languageId) + /// + /// Gets product not valid fields + /// + /// language id to get not valid fields from + /// + public override IEnumerable GetInvalidFields(string languageId) + { + if (_languageIdInvalidFieldDictionary == null) { - if (_languageIdInvalidFieldDictionary == null) - { - _languageIdInvalidFieldDictionary = new Dictionary>(); + _languageIdInvalidFieldDictionary = new Dictionary>(); - foreach (KeyValuePair> kvp in GetInvalidNumericFieldLanguages()) + foreach (KeyValuePair> kvp in GetInvalidNumericFieldLanguages()) + { + foreach (string language in kvp.Value) { - foreach (string language in kvp.Value) + List fields = null; + if (!_languageIdInvalidFieldDictionary.TryGetValue(language, out fields)) { - List fields = null; - if (!_languageIdInvalidFieldDictionary.TryGetValue(language, out fields)) - { - fields = new List(); - } - if (!fields.Contains(kvp.Key)) - { - fields.Add(kvp.Key); - } - _languageIdInvalidFieldDictionary[language] = fields; + fields = new List(); } + if (!fields.Contains(kvp.Key)) + { + fields.Add(kvp.Key); + } + _languageIdInvalidFieldDictionary[language] = fields; } } - if (_languageIdInvalidFieldDictionary.ContainsKey(languageId)) - { - return _languageIdInvalidFieldDictionary[languageId]; - } - else - { - return new List(); - } - } + } + if (_languageIdInvalidFieldDictionary.ContainsKey(languageId)) + { + return _languageIdInvalidFieldDictionary[languageId]; + } + else + { + return new List(); + } + } - private Dictionary> FieldLanguageIdColumnIndexDictionary + private Dictionary> FieldLanguageIdColumnIndexDictionary + { + get { - get + if (_fieldLanguageIdColumnIndexDictionary == null) { - if (_fieldLanguageIdColumnIndexDictionary == null) + _fieldLanguageIdColumnIndexDictionary = new Dictionary>(); + if (Worksheet != null) { - _fieldLanguageIdColumnIndexDictionary = new Dictionary>(); - if (Worksheet != null) + var end = Worksheet.Dimension.End; + for (int col = 3; col <= end.Column; col++) { - var end = Worksheet.Dimension.End; - for (int col = 3; col <= end.Column; col++) + string fieldId = Worksheet.Cells[1, col].Comment?.Text; + if (!string.IsNullOrEmpty(fieldId)) { - string fieldId = Worksheet.Cells[1, col].Comment?.Text; - if (!string.IsNullOrEmpty(fieldId)) + if (!_fieldLanguageIdColumnIndexDictionary.ContainsKey(fieldId)) { - if (!_fieldLanguageIdColumnIndexDictionary.ContainsKey(fieldId)) - { - _fieldLanguageIdColumnIndexDictionary.Add(fieldId, new Dictionary()); - } - string languageId = Worksheet.Cells[2, col].Comment?.Text; - if (!string.IsNullOrEmpty(languageId)) - { - if (!_fieldLanguageIdColumnIndexDictionary[fieldId].ContainsKey(languageId)) - { - _fieldLanguageIdColumnIndexDictionary[fieldId].Add(languageId, col); - } - } - else + _fieldLanguageIdColumnIndexDictionary.Add(fieldId, new Dictionary()); + } + string languageId = Worksheet.Cells[2, col].Comment?.Text; + if (!string.IsNullOrEmpty(languageId)) + { + if (!_fieldLanguageIdColumnIndexDictionary[fieldId].ContainsKey(languageId)) { - //to do when column if doesn't have a language id - so it has same values for all languages + _fieldLanguageIdColumnIndexDictionary[fieldId].Add(languageId, col); } } + else + { + //to do when column if doesn't have a language id - so it has same values for all languages + } } } } - return _fieldLanguageIdColumnIndexDictionary; } + return _fieldLanguageIdColumnIndexDictionary; } + } - private Dictionary GetVariantProductRows(string productId) + private Dictionary GetVariantProductRows(string productId) + { + Dictionary variantIdRows = new Dictionary(); + for (int row = 3; row <= Worksheet.Dimension.End.Row; row++) { - Dictionary variantIdRows = new Dictionary(); - for (int row = 3; row <= Worksheet.Dimension.End.Row; row++) + string text = Worksheet.Cells[row, 1].Text; + if (!string.IsNullOrEmpty(text) && string.Equals(text, productId, StringComparison.OrdinalIgnoreCase)) { - string text = Worksheet.Cells[row, 1].Text; - if (!string.IsNullOrEmpty(text) && string.Equals(text, productId, StringComparison.OrdinalIgnoreCase)) + string variantId = Worksheet.Cells[row, 2].Text; + if (!string.IsNullOrEmpty(variantId) && !variantIdRows.ContainsKey(variantId)) { - string variantId = Worksheet.Cells[row, 2].Text; - if (!string.IsNullOrEmpty(variantId) && !variantIdRows.ContainsKey(variantId)) - { - variantIdRows.Add(variantId, row); - } + variantIdRows.Add(variantId, row); } } - return variantIdRows; } + return variantIdRows; + } - protected override VariantCombination GetSimpleVariantFromExcel(Product mainProduct, string variantId, bool isNewVariantLanguageProduct) + protected override VariantCombination GetSimpleVariantFromExcel(Product mainProduct, string variantId, bool isNewVariantLanguageProduct) + { + VariantCombination result = null; + var variantProductRows = GetVariantProductRows(mainProduct.Id); + if (variantProductRows.ContainsKey(variantId)) { - VariantCombination result = null; - var variantProductRows = GetVariantProductRows(mainProduct.Id); - if (variantProductRows.ContainsKey(variantId)) + if (isNewVariantLanguageProduct) { - if (isNewVariantLanguageProduct) - { - result = VariantCombinationService.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); - } - else - { - result = VariantCombinationService.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => !vc.HasRowInProductTable && string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); - } - + result = Services.VariantCombinations.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); + } + else + { + result = Services.VariantCombinations.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => !vc.HasRowInProductTable && string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); } - return result; - } - protected override IEnumerable GetSimpleVariantsFromExcel(Product mainProduct) - { - var variantProductRows = GetVariantProductRows(mainProduct.Id); - return VariantCombinationService.GetVariantCombinations(mainProduct.Id).Where(vc => !vc.HasRowInProductTable && variantProductRows.Keys.Contains(vc.VariantId)); } + return result; + } - private Dictionary> GetFieldLanguageIdValues(int row) + protected override IEnumerable GetSimpleVariantsFromExcel(Product mainProduct) + { + var variantProductRows = GetVariantProductRows(mainProduct.Id); + return Services.VariantCombinations.GetVariantCombinations(mainProduct.Id).Where(vc => !vc.HasRowInProductTable && variantProductRows.Keys.Contains(vc.VariantId)); + } + + private Dictionary> GetFieldLanguageIdValues(int row) + { + Dictionary> fieldLanguageIdValues = new Dictionary>(); + var end = Worksheet.Dimension.End; + + foreach (string fieldId in FieldLanguageIdColumnIndexDictionary.Keys) { - Dictionary> fieldLanguageIdValues = new Dictionary>(); - var end = Worksheet.Dimension.End; + Dictionary languageIdValues = new Dictionary(); - foreach (string fieldId in FieldLanguageIdColumnIndexDictionary.Keys) + foreach (KeyValuePair kvp in FieldLanguageIdColumnIndexDictionary[fieldId]) { - Dictionary languageIdValues = new Dictionary(); + string languageId = kvp.Key; + int languageColumnIndex = kvp.Value; - foreach (KeyValuePair kvp in FieldLanguageIdColumnIndexDictionary[fieldId]) + dynamic obj = new ExpandoObject(); + string formula = Worksheet.Cells[row, languageColumnIndex].Formula; + obj.IsFormula = !string.IsNullOrEmpty(formula); + if (obj.IsFormula) { - string languageId = kvp.Key; - int languageColumnIndex = kvp.Value; - - dynamic obj = new ExpandoObject(); - string formula = Worksheet.Cells[row, languageColumnIndex].Formula; - obj.IsFormula = !string.IsNullOrEmpty(formula); - if (obj.IsFormula) - { - obj.Text = Worksheet.Cells[formula].Text; - } - else - { - obj.Text = Worksheet.Cells[row, languageColumnIndex].Text; - } - languageIdValues.Add(languageId, obj); + obj.Text = Worksheet.Cells[formula].Text; } - - fieldLanguageIdValues.Add(fieldId, languageIdValues); + else + { + obj.Text = Worksheet.Cells[row, languageColumnIndex].Text; + } + languageIdValues.Add(languageId, obj); } - return fieldLanguageIdValues; + fieldLanguageIdValues.Add(fieldId, languageIdValues); } - private Dictionary> GetInvalidNumericFieldLanguages() - { - Dictionary> invalidNumericFieldLanguages = new Dictionary>(); + return fieldLanguageIdValues; + } - var end = Worksheet.Dimension.End; + private Dictionary> GetInvalidNumericFieldLanguages() + { + Dictionary> invalidNumericFieldLanguages = new Dictionary>(); + + var end = Worksheet.Dimension.End; - foreach (string field in FieldLanguageIdColumnIndexDictionary.Keys) + foreach (string field in FieldLanguageIdColumnIndexDictionary.Keys) + { + if (NumericFields.ContainsKey(field)) { - if (NumericFields.ContainsKey(field)) - { - bool resultContainsField = invalidNumericFieldLanguages.ContainsKey(field); - List invalidLanguages = new List(); + bool resultContainsField = invalidNumericFieldLanguages.ContainsKey(field); + List invalidLanguages = new List(); - for (int row = 3; row <= end.Row; row++) + for (int row = 3; row <= end.Row; row++) + { + if (string.IsNullOrEmpty(Worksheet.Cells[row, 1].Text)) { - if (string.IsNullOrEmpty(Worksheet.Cells[row, 1].Text)) + foreach (KeyValuePair languageIdColumnIndexPair in FieldLanguageIdColumnIndexDictionary[field]) { - foreach (KeyValuePair languageIdColumnIndexPair in FieldLanguageIdColumnIndexDictionary[field]) + if (!resultContainsField || !invalidNumericFieldLanguages[field].Contains(languageIdColumnIndexPair.Key)) { - if (!resultContainsField || !invalidNumericFieldLanguages[field].Contains(languageIdColumnIndexPair.Key)) + string value = null; + string formula = Worksheet.Cells[row, languageIdColumnIndexPair.Value].Formula; + if (!string.IsNullOrEmpty(formula)) { - string value = null; - string formula = Worksheet.Cells[row, languageIdColumnIndexPair.Value].Formula; - if (!string.IsNullOrEmpty(formula)) - { - value = Worksheet.Cells[formula].Text; - } - else + value = Worksheet.Cells[formula].Text; + } + else + { + value = Worksheet.Cells[row, languageIdColumnIndexPair.Value].Text; + } + if (!string.IsNullOrEmpty(value) && !FieldsHelper.IsNumericValueValid(value, NumericFields[field])) + { + if (!resultContainsField) { - value = Worksheet.Cells[row, languageIdColumnIndexPair.Value].Text; + invalidNumericFieldLanguages.Add(field, new List()); } - if (!string.IsNullOrEmpty(value) && !FieldsHelper.IsNumericValueValid(value, NumericFields[field])) + if (!invalidNumericFieldLanguages[field].Contains(languageIdColumnIndexPair.Key)) { - if (!resultContainsField) - { - invalidNumericFieldLanguages.Add(field, new List()); - } - if (!invalidNumericFieldLanguages[field].Contains(languageIdColumnIndexPair.Key)) - { - invalidNumericFieldLanguages[field].Add(languageIdColumnIndexPair.Key); - } + invalidNumericFieldLanguages[field].Add(languageIdColumnIndexPair.Key); } } } @@ -396,26 +395,26 @@ private Dictionary> GetInvalidNumericFieldLanguages() } } } - - return invalidNumericFieldLanguages; } + + return invalidNumericFieldLanguages; + } - public List GetProductIds() + public List GetProductIds() + { + List result = new List(); + if (Worksheet != null) { - List result = new List(); - if (Worksheet != null) + ExcelRange cell = null; + for (int i = 3; i <= Worksheet.Dimension.End.Row; i++) { - ExcelRange cell = null; - for (int i = 3; i <= Worksheet.Dimension.End.Row; i++) + cell = Worksheet.Cells[i, 1]; + if (cell != null && !string.IsNullOrEmpty(cell.Text)) { - cell = Worksheet.Cells[i, 1]; - if (cell != null && !string.IsNullOrEmpty(cell.Text)) - { - result.Add(cell.Text); - } + result.Add(cell.Text); } } - return result.Distinct().ToList(); - } - } -} + } + return result.Distinct().ToList(); + } +} \ No newline at end of file diff --git a/src/PIM/ImportOneProductExcelProvider.cs.cs b/src/PIM/ImportOneProductExcelProvider.cs.cs index 3f13712..9ae880a 100644 --- a/src/PIM/ImportOneProductExcelProvider.cs.cs +++ b/src/PIM/ImportOneProductExcelProvider.cs.cs @@ -1,414 +1,414 @@ using System; using System.Collections.Generic; +using System.Dynamic; using System.Linq; +using Dynamicweb.Ecommerce; +using Dynamicweb.Ecommerce.International; using Dynamicweb.Ecommerce.Products; using Dynamicweb.Ecommerce.Variants; using OfficeOpenXml; -using Dynamicweb.Ecommerce.International; -using System.Dynamic; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM -{ - internal class ImportOneProductExcelProvider : BaseImportExcelProvider - { - private Dictionary _languageIdColumnIndexDictionary = null; - private Dictionary> _variantProductRows = null; - private List _fields = null; - private Dictionary> _languageIdInvalidFieldDictionary = null; +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; + +internal class ImportOneProductExcelProvider : BaseImportExcelProvider +{ + private Dictionary _languageIdColumnIndexDictionary = null; + private Dictionary> _variantProductRows = null; + private List _fields = null; + private Dictionary> _languageIdInvalidFieldDictionary = null; - #region Interfaces + #region Interfaces - /// - /// Gets product fields from excel file - /// - /// - public override IEnumerable GetFields() + /// + /// Gets product fields from excel file + /// + /// + public override IEnumerable GetFields() + { + if (_fields == null) { - if (_fields == null) + _fields = new List(); + if (Worksheet != null) { - _fields = new List(); - if (Worksheet != null) + var end = Worksheet.Dimension.End; + for (int row = 2; row <= end.Row; row++) { - var end = Worksheet.Dimension.End; - for (int row = 2; row <= end.Row; row++) + if (!string.IsNullOrEmpty(Worksheet.Cells[row, 3].Text)) { - if (!string.IsNullOrEmpty(Worksheet.Cells[row, 3].Text)) - { - _fields.Add(Worksheet.Cells[row, 3].Text); - } + _fields.Add(Worksheet.Cells[row, 3].Text); } } - _fields.Remove("ProductLanguageID"); - _fields.Remove("ProductNumber"); - _fields = _fields.Distinct().ToList(); } - return _fields; + _fields.Remove("ProductLanguageID"); + _fields.Remove("ProductNumber"); + _fields = _fields.Distinct().ToList(); } + return _fields; + } - /// - /// Gets product languages ids from excel file - /// - /// - public override IEnumerable GetLanguages() + /// + /// Gets product languages ids from excel file + /// + /// + public override IEnumerable GetLanguages() + { + List result = new List(); + if (Worksheet != null) { - List result = new List(); - if (Worksheet != null) + var end = Worksheet.Dimension.End; + for (int col = 5; col <= end.Column; col++) { - var end = Worksheet.Dimension.End; - for (int col = 5; col <= end.Column; col++) + if (!string.IsNullOrEmpty(Worksheet.Cells[2, col].Text)) { - if (!string.IsNullOrEmpty(Worksheet.Cells[2, col].Text)) - { - result.Add(Worksheet.Cells[2, col].Text); - } + result.Add(Worksheet.Cells[2, col].Text); } } - return result; } + return result; + } - /// - /// Gets product id from excel file - /// - /// - public override string GetProductId() + /// + /// Gets product id from excel file + /// + /// + public override string GetProductId() + { + string result = null; + if (Worksheet != null) { - string result = null; - if (Worksheet != null) + ExcelRange cell = Worksheet.Cells[2, 1]; + if (cell != null) { - ExcelRange cell = Worksheet.Cells[2, 1]; - if (cell != null) - { - result = cell.Text; - } + result = cell.Text; } - return result; } + return result; + } - /// - /// Gets product simple variants that need to be extended for successful import - /// - /// language id to get not valid variants from - /// - public override Dictionary> GetSimpleVariants(IEnumerable languages) - { - var failedVariants = new Dictionary>(); + /// + /// Gets product simple variants that need to be extended for successful import + /// + /// language id to get not valid variants from + /// + public override Dictionary> GetSimpleVariants(IEnumerable languages) + { + var failedVariants = new Dictionary>(); - string productId = GetProductId(); - IEnumerable languagesToImport = LanguageService.GetLanguages().Where(l => languages.Contains(l.LanguageId)); + string productId = GetProductId(); + IEnumerable languagesToImport = Services.Languages.GetLanguages().Where(l => languages.Contains(l.LanguageId)); - var fieldLanguageIdValues = GetFieldLanguageIdValues(GetProductRows()); - if (fieldLanguageIdValues.Keys.Count > 0) - { - failedVariants = GetInvalidVariantsFromProduct(productId, null, languagesToImport, fieldLanguageIdValues); - } + var fieldLanguageIdValues = GetFieldLanguageIdValues(GetProductRows()); + if (fieldLanguageIdValues.Keys.Count > 0) + { + failedVariants = GetInvalidVariantsFromProduct(productId, null, languagesToImport, fieldLanguageIdValues); + } - foreach (string variantId in VariantProductRows.Keys) + foreach (string variantId in VariantProductRows.Keys) + { + fieldLanguageIdValues = GetFieldLanguageIdValues(VariantProductRows[variantId]); + if (fieldLanguageIdValues.Keys.Count > 0) { - fieldLanguageIdValues = GetFieldLanguageIdValues(VariantProductRows[variantId]); - if (fieldLanguageIdValues.Keys.Count > 0) + foreach (var kvp in GetInvalidVariantsFromProduct(productId, variantId, languagesToImport, fieldLanguageIdValues)) { - foreach (var kvp in GetInvalidVariantsFromProduct(productId, variantId, languagesToImport, fieldLanguageIdValues)) + if (!failedVariants.ContainsKey(kvp.Key)) { - if (!failedVariants.ContainsKey(kvp.Key)) - { - failedVariants.Add(kvp.Key, kvp.Value); - } - else + failedVariants.Add(kvp.Key, kvp.Value); + } + else + { + foreach (var combination in kvp.Value) { - foreach (var combination in kvp.Value) + if (!failedVariants[kvp.Key].Any(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase))) { - if (!failedVariants[kvp.Key].Any(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase))) - { - failedVariants[kvp.Key].Add(combination); - } + failedVariants[kvp.Key].Add(combination); } } } } } - return failedVariants; } + return failedVariants; + } - /// - /// Import product from excel - /// - /// languages to import product to - /// create extended variants automatically - /// import status message - /// - public override bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status) - { - bool result = true; - status = null; + /// + /// Import product from excel + /// + /// languages to import product to + /// create extended variants automatically + /// import status message + /// + public override bool Import(IEnumerable languages, bool autoCreateExtendedVariants, out string status) + { + bool result = true; + status = null; - if (Worksheet != null) + if (Worksheet != null) + { + try { - try + string productId = GetProductId(); + IEnumerable languagesToImport = Services.Languages.GetLanguages().Where(l => languages.Contains(l.LanguageId)); + Dictionary> failedVariants = GetSimpleVariants(languages); + + var fieldLanguageIdValues = GetFieldLanguageIdValues(GetProductRows()); + if (fieldLanguageIdValues.Keys.Count > 0) { - string productId = GetProductId(); - IEnumerable languagesToImport = LanguageService.GetLanguages().Where(l => languages.Contains(l.LanguageId)); - Dictionary> failedVariants = GetSimpleVariants(languages); + UpdateProduct(productId, null, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, failedVariants); + } - var fieldLanguageIdValues = GetFieldLanguageIdValues(GetProductRows()); + foreach (string variantId in VariantProductRows.Keys) + { + fieldLanguageIdValues = GetFieldLanguageIdValues(VariantProductRows[variantId]); if (fieldLanguageIdValues.Keys.Count > 0) { - UpdateProduct(productId, null, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, failedVariants); - } - - foreach (string variantId in VariantProductRows.Keys) - { - fieldLanguageIdValues = GetFieldLanguageIdValues(VariantProductRows[variantId]); - if (fieldLanguageIdValues.Keys.Count > 0) - { - UpdateProduct(productId, variantId, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, - failedVariants); - } + UpdateProduct(productId, variantId, languagesToImport, fieldLanguageIdValues, autoCreateExtendedVariants, + failedVariants); } } - catch (Exception ex) - { - status += $"Error occured: {ex.Message}. "; - status += !string.IsNullOrEmpty(ex.StackTrace) ? $"Stack: {ex.StackTrace}. " : string.Empty; - result = false; - } } - else + catch (Exception ex) { - status = "Worksheet is not found."; + status += $"Error occured: {ex.Message}. "; + status += !string.IsNullOrEmpty(ex.StackTrace) ? $"Stack: {ex.StackTrace}. " : string.Empty; + result = false; } + } + else + { + status = "Worksheet is not found."; + } - return result; - } + return result; + } - /// - /// Gets product not valid fields - /// - /// language id to get not valid fields from - /// - public override IEnumerable GetInvalidFields(string languageId) + /// + /// Gets product not valid fields + /// + /// language id to get not valid fields from + /// + public override IEnumerable GetInvalidFields(string languageId) + { + if (_languageIdInvalidFieldDictionary == null) { - if (_languageIdInvalidFieldDictionary == null) - { - _languageIdInvalidFieldDictionary = new Dictionary>(); + _languageIdInvalidFieldDictionary = new Dictionary>(); - foreach (KeyValuePair> kvp in GetIvalidNumericFieldLanguages()) + foreach (KeyValuePair> kvp in GetIvalidNumericFieldLanguages()) + { + foreach (string language in kvp.Value) { - foreach (string language in kvp.Value) + List fields = null; + if (!_languageIdInvalidFieldDictionary.TryGetValue(language, out fields)) { - List fields = null; - if (!_languageIdInvalidFieldDictionary.TryGetValue(language, out fields)) - { - fields = new List(); - } - if (!fields.Contains(kvp.Key)) - { - fields.Add(kvp.Key); - } - _languageIdInvalidFieldDictionary[language] = fields; + fields = new List(); + } + if (!fields.Contains(kvp.Key)) + { + fields.Add(kvp.Key); } + _languageIdInvalidFieldDictionary[language] = fields; } } - if (_languageIdInvalidFieldDictionary.ContainsKey(languageId)) + } + if (_languageIdInvalidFieldDictionary.ContainsKey(languageId)) + { + return _languageIdInvalidFieldDictionary[languageId]; + } + else + { + return new List(); + } + } + + protected override VariantCombination GetSimpleVariantFromExcel(Product mainProduct, string variantId, bool isNewVariantLanguageProduct) + { + VariantCombination result = null; + if (VariantProductRows.ContainsKey(variantId)) + { + if (isNewVariantLanguageProduct) { - return _languageIdInvalidFieldDictionary[languageId]; + result = Services.VariantCombinations.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); } else { - return new List(); + result = Services.VariantCombinations.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => !vc.HasRowInProductTable && string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); } } + return result; + } - protected override VariantCombination GetSimpleVariantFromExcel(Product mainProduct, string variantId, bool isNewVariantLanguageProduct) - { - VariantCombination result = null; - if (VariantProductRows.ContainsKey(variantId)) - { - if (isNewVariantLanguageProduct) - { - result = VariantCombinationService.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); - } - else - { - result = VariantCombinationService.GetVariantCombinations(mainProduct.Id).FirstOrDefault(vc => !vc.HasRowInProductTable && string.Equals(vc.VariantId, variantId, StringComparison.InvariantCultureIgnoreCase)); - } - } - return result; - } - - protected override IEnumerable GetSimpleVariantsFromExcel(Product mainProduct) - { - return VariantCombinationService.GetVariantCombinations(mainProduct.Id).Where(vc => !vc.HasRowInProductTable && VariantProductRows.Keys.Contains(vc.VariantId)); - } + protected override IEnumerable GetSimpleVariantsFromExcel(Product mainProduct) + { + return Services.VariantCombinations.GetVariantCombinations(mainProduct.Id).Where(vc => !vc.HasRowInProductTable && VariantProductRows.Keys.Contains(vc.VariantId)); + } - #endregion Interfaces + #endregion Interfaces - private Dictionary LanguageIdColumnIndexDictionary + private Dictionary LanguageIdColumnIndexDictionary + { + get { - get + if (_languageIdColumnIndexDictionary == null) { - if (_languageIdColumnIndexDictionary == null) + _languageIdColumnIndexDictionary = new Dictionary(); + if (Worksheet != null) { - _languageIdColumnIndexDictionary = new Dictionary(); - if (Worksheet != null) + var end = Worksheet.Dimension.End; + for (int col = 5; col <= end.Column; col++) { - var end = Worksheet.Dimension.End; - for (int col = 5; col <= end.Column; col++) + string languageId = Worksheet.Cells[2, col].Text; + if (!string.IsNullOrEmpty(languageId)) { - string languageId = Worksheet.Cells[2, col].Text; - if (!string.IsNullOrEmpty(languageId)) + if (!_languageIdColumnIndexDictionary.ContainsKey(languageId)) { - if (!_languageIdColumnIndexDictionary.ContainsKey(languageId)) - { - _languageIdColumnIndexDictionary.Add(languageId, col); - } + _languageIdColumnIndexDictionary.Add(languageId, col); } - else - { - //skip reading next cells as it indicates wrong format/last language was read + } + else + { + //skip reading next cells as it indicates wrong format/last language was read - } } } } - return _languageIdColumnIndexDictionary; } + return _languageIdColumnIndexDictionary; } + } - private Dictionary> VariantProductRows + private Dictionary> VariantProductRows + { + get { - get + if (_variantProductRows == null) { - if (_variantProductRows == null) - { - _variantProductRows = GetVariantProductRows(); - } - return _variantProductRows; + _variantProductRows = GetVariantProductRows(); } + return _variantProductRows; } + } - private Dictionary> GetVariantProductRows() + private Dictionary> GetVariantProductRows() + { + Dictionary> variantIdRows = new Dictionary>(); + for (int row = 2; row <= Worksheet.Dimension.End.Row; row++) { - Dictionary> variantIdRows = new Dictionary>(); - for (int row = 2; row <= Worksheet.Dimension.End.Row; row++) + if (IsVariantRow(row)) { - if (IsVariantRow(row)) + string variantId = Worksheet.Cells[row, 2].Text; + if (!variantIdRows.ContainsKey(variantId)) { - string variantId = Worksheet.Cells[row, 2].Text; - if (!variantIdRows.ContainsKey(variantId)) - { - variantIdRows.Add(variantId, new List()); - } - variantIdRows[variantId].Add(row); + variantIdRows.Add(variantId, new List()); } + variantIdRows[variantId].Add(row); } - return variantIdRows; } + return variantIdRows; + } - private IEnumerable GetProductRows() + private IEnumerable GetProductRows() + { + List result = new List(); + var end = Worksheet.Dimension.End; + for (int row = 2; row <= end.Row; row++) { - List result = new List(); - var end = Worksheet.Dimension.End; - for (int row = 2; row <= end.Row; row++) + if (IsVariantHeaderRow(row)) { - if (IsVariantHeaderRow(row)) - { - break; - } - else - { - result.Add(row); - } + break; + } + else + { + result.Add(row); } - return result; } + return result; + } - private bool IsVariantHeaderRow(int row) - { - return !string.IsNullOrEmpty(Worksheet.Cells[row, 2].Text) && string.IsNullOrEmpty(Worksheet.Cells[row, 3].Text) && string.IsNullOrEmpty(Worksheet.Cells[row, 4].Text); - } + private bool IsVariantHeaderRow(int row) + { + return !string.IsNullOrEmpty(Worksheet.Cells[row, 2].Text) && string.IsNullOrEmpty(Worksheet.Cells[row, 3].Text) && string.IsNullOrEmpty(Worksheet.Cells[row, 4].Text); + } - private bool IsVariantRow(int row) - { - return !string.IsNullOrEmpty(Worksheet.Cells[row, 1].Text) && !string.IsNullOrEmpty(Worksheet.Cells[row, 2].Text); - } + private bool IsVariantRow(int row) + { + return !string.IsNullOrEmpty(Worksheet.Cells[row, 1].Text) && !string.IsNullOrEmpty(Worksheet.Cells[row, 2].Text); + } - private Dictionary> GetFieldLanguageIdValues(IEnumerable rows) + private Dictionary> GetFieldLanguageIdValues(IEnumerable rows) + { + Dictionary> fieldLanguageIdValues = new Dictionary>(); + var end = Worksheet.Dimension.End; + foreach (int row in rows) { - Dictionary> fieldLanguageIdValues = new Dictionary>(); - var end = Worksheet.Dimension.End; - foreach (int row in rows) + string field = Worksheet.Cells[row, 3].Text; + if (!string.IsNullOrEmpty(field) && !fieldLanguageIdValues.Keys.Contains(field)) { - string field = Worksheet.Cells[row, 3].Text; - if (!string.IsNullOrEmpty(field) && !fieldLanguageIdValues.Keys.Contains(field)) + Dictionary languageIdValues = new Dictionary(); + fieldLanguageIdValues.Add(field, languageIdValues); + for (int col = 5; col <= end.Column; col++) { - Dictionary languageIdValues = new Dictionary(); - fieldLanguageIdValues.Add(field, languageIdValues); - for (int col = 5; col <= end.Column; col++) + string language = LanguageIdColumnIndexDictionary.FirstOrDefault(kvp => kvp.Value == col).Key; + if (!string.IsNullOrEmpty(language)) { - string language = LanguageIdColumnIndexDictionary.FirstOrDefault(kvp => kvp.Value == col).Key; - if (!string.IsNullOrEmpty(language)) + dynamic obj = new ExpandoObject(); + obj.IsFormula = !string.IsNullOrEmpty(Worksheet.Cells[row, col].Formula); + if (!string.IsNullOrEmpty(Worksheet.Cells[row, col].Formula)) { - dynamic obj = new ExpandoObject(); - obj.IsFormula = !string.IsNullOrEmpty(Worksheet.Cells[row, col].Formula); - if (!string.IsNullOrEmpty(Worksheet.Cells[row, col].Formula)) - { - obj.Text = Worksheet.Cells[Worksheet.Cells[row, col].Formula].Text; - } - else - { - obj.Text = Worksheet.Cells[row, col].Text; - } - languageIdValues.Add(language, obj); + obj.Text = Worksheet.Cells[Worksheet.Cells[row, col].Formula].Text; } + else + { + obj.Text = Worksheet.Cells[row, col].Text; + } + languageIdValues.Add(language, obj); } } } - return fieldLanguageIdValues; } + return fieldLanguageIdValues; + } - private Dictionary> GetIvalidNumericFieldLanguages() - { - Dictionary> ivalidNumericFieldLanguages = new Dictionary>(); + private Dictionary> GetIvalidNumericFieldLanguages() + { + Dictionary> ivalidNumericFieldLanguages = new Dictionary>(); - var end = Worksheet.Dimension.End; - //start from rows after ProductName - for (int row = 4; row <= end.Row; row++) + var end = Worksheet.Dimension.End; + //start from rows after ProductName + for (int row = 4; row <= end.Row; row++) + { + string field = Worksheet.Cells[row, 3].Text; + if (!string.IsNullOrEmpty(field) && NumericFields.ContainsKey(field)) { - string field = Worksheet.Cells[row, 3].Text; - if (!string.IsNullOrEmpty(field) && NumericFields.ContainsKey(field)) + bool resultContainsField = ivalidNumericFieldLanguages.ContainsKey(field); + List invalidLanguages = new List(); + for (int col = 5; col <= end.Column; col++) { - bool resultContainsField = ivalidNumericFieldLanguages.ContainsKey(field); - List invalidLanguages = new List(); - for (int col = 5; col <= end.Column; col++) + string language = LanguageIdColumnIndexDictionary.FirstOrDefault(kvp => kvp.Value == col).Key; + if (!string.IsNullOrEmpty(language) && (!resultContainsField || !ivalidNumericFieldLanguages[field].Contains(language))) { - string language = LanguageIdColumnIndexDictionary.FirstOrDefault(kvp => kvp.Value == col).Key; - if (!string.IsNullOrEmpty(language) && (!resultContainsField || !ivalidNumericFieldLanguages[field].Contains(language))) + string value = null; + if (!string.IsNullOrEmpty(Worksheet.Cells[row, col].Formula)) { - string value = null; - if (!string.IsNullOrEmpty(Worksheet.Cells[row, col].Formula)) - { - value = Worksheet.Cells[Worksheet.Cells[row, col].Formula].Text; - } - else + value = Worksheet.Cells[Worksheet.Cells[row, col].Formula].Text; + } + else + { + value = Worksheet.Cells[row, col].Text; + } + if (!string.IsNullOrEmpty(value) && !FieldsHelper.IsNumericValueValid(value, NumericFields[field])) + { + if (!resultContainsField) { - value = Worksheet.Cells[row, col].Text; + ivalidNumericFieldLanguages.Add(field, new List()); } - if (!string.IsNullOrEmpty(value) && !FieldsHelper.IsNumericValueValid(value, NumericFields[field])) + if (!ivalidNumericFieldLanguages[field].Contains(language)) { - if (!resultContainsField) - { - ivalidNumericFieldLanguages.Add(field, new List()); - } - if (!ivalidNumericFieldLanguages[field].Contains(language)) - { - ivalidNumericFieldLanguages[field].Add(language); - } + ivalidNumericFieldLanguages[field].Add(language); } } } } } - return ivalidNumericFieldLanguages; } + return ivalidNumericFieldLanguages; } -} +} \ No newline at end of file diff --git a/src/PIM/ListFieldsHelper.cs b/src/PIM/ListFieldsHelper.cs index 86a23ec..d3a28b9 100644 --- a/src/PIM/ListFieldsHelper.cs +++ b/src/PIM/ListFieldsHelper.cs @@ -1,77 +1,95 @@ -using Dynamicweb.Ecommerce.Products; -using Dynamicweb.Ecommerce.Products.Categories; -using System; +using System; using System.Collections.Generic; using System.Linq; +using Dynamicweb.Ecommerce.Products; +using Dynamicweb.Ecommerce.Products.Categories; + +namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM; -namespace Dynamicweb.DataIntegration.Providers.ExcelProvider.PIM +internal class ListFieldsHelper { - internal class ListFieldsHelper + private FieldsHelper FieldsHelper = new FieldsHelper(); + private Dictionary CustomListBoxFields = null; + private Dictionary CategoryListBoxFields = null; + private Dictionary> FieldOptions = null; + private Dictionary> FieldOptionTranslations = null; + private readonly int ListTypeId = 15; + + public ListFieldsHelper(IEnumerable fields) + { + CustomListBoxFields = GetCustomListBoxFields(fields); + CategoryListBoxFields = GetCategoryListBoxFields(fields); + FieldOptions = new Dictionary>(); + FieldOptionTranslations = new Dictionary>(); + } + + /// + /// Gets the custom listbox fields + /// + public Dictionary GetCustomListBoxFields(IEnumerable fields) { - private FieldsHelper FieldsHelper = new FieldsHelper(); - private Dictionary CustomListBoxFields = null; - private Dictionary CategoryListBoxFields = null; - private Dictionary> FieldOptions = null; - private Dictionary> FieldOptionTranslations = null; - private readonly int ListTypeId = 15; - - public ListFieldsHelper(IEnumerable fields) + Dictionary result = new Dictionary(); + foreach (string field in fields) { - CustomListBoxFields = GetCustomListBoxFields(fields); - CategoryListBoxFields = GetCategoryListBoxFields(fields); - FieldOptions = new Dictionary>(); - FieldOptionTranslations = new Dictionary>(); + if (!result.ContainsKey(field)) + { + ProductField productField = FieldsHelper.GetCustomField(FieldsHelper.GetFieldSystemName(field)); + if (productField != null && productField.TypeId == ListTypeId) + { + result.Add(field, productField); + } + } } + return result; + } - /// - /// Gets the custom listbox fields - /// - public Dictionary GetCustomListBoxFields(IEnumerable fields) + /// + /// Gets the category listbox fields + /// + public Dictionary GetCategoryListBoxFields(IEnumerable fields) + { + Dictionary result = new Dictionary(); + foreach (string field in fields) { - Dictionary result = new Dictionary(); - foreach (string field in fields) + if (!result.ContainsKey(field)) { - if (!result.ContainsKey(field)) + Field categoryField = FieldsHelper.GetCategoryField(FieldsHelper.GetFieldSystemName(field)); + if (categoryField != null && categoryField.Type == ListTypeId.ToString()) { - ProductField productField = FieldsHelper.GetCustomField(FieldsHelper.GetFieldSystemName(field)); - if (productField != null && productField.TypeId == ListTypeId) - { - result.Add(field, productField); - } + result.Add(field, categoryField); } } - return result; } + return result; + } - /// - /// Gets the category listbox fields - /// - public Dictionary GetCategoryListBoxFields(IEnumerable fields) + public KeyValuePair> GetFieldOptions(string field) + { + KeyValuePair> result = new KeyValuePair>(null, null); + ProductField customListBoxField = null; + if (CustomListBoxFields.TryGetValue(field, out customListBoxField)) { - Dictionary result = new Dictionary(); - foreach (string field in fields) + if (!FieldOptions.TryGetValue(field, out Dictionary lookupCollection)) { - if (!result.ContainsKey(field)) + var fieldOptionCollection = Ecommerce.Services.FieldOptions.GetOptionsByFieldId(customListBoxField.Id); + lookupCollection = new Dictionary(); + foreach (var fieldOption in fieldOptionCollection) { - Field categoryField = FieldsHelper.GetCategoryField(FieldsHelper.GetFieldSystemName(field)); - if (categoryField != null && categoryField.Type == ListTypeId.ToString()) - { - result.Add(field, categoryField); - } + lookupCollection[fieldOption.Value] = fieldOption; } + FieldOptions.Add(field, lookupCollection); } - return result; - } - public KeyValuePair> GetFieldOptions(string field) + result = new KeyValuePair>(customListBoxField, lookupCollection); + } + else { - KeyValuePair> result = new KeyValuePair>(null, null); - ProductField customListBoxField = null; - if (CustomListBoxFields.TryGetValue(field, out customListBoxField)) + Field categoryListBoxField = null; + if (CategoryListBoxFields.TryGetValue(field, out categoryListBoxField)) { if (!FieldOptions.TryGetValue(field, out Dictionary lookupCollection)) { - var fieldOptionCollection = Ecommerce.Services.FieldOptions.GetOptionsByFieldId(customListBoxField.Id); + var fieldOptionCollection = Ecommerce.Services.FieldOptions.GetOptionsByFieldId(categoryListBoxField.Id); lookupCollection = new Dictionary(); foreach (var fieldOption in fieldOptionCollection) { @@ -80,167 +98,148 @@ public KeyValuePair> GetFieldOptions(str FieldOptions.Add(field, lookupCollection); } - result = new KeyValuePair>(customListBoxField, lookupCollection); + result = new KeyValuePair>(categoryListBoxField, lookupCollection); } - else - { - Field categoryListBoxField = null; - if (CategoryListBoxFields.TryGetValue(field, out categoryListBoxField)) - { - if (!FieldOptions.TryGetValue(field, out Dictionary lookupCollection)) - { - var fieldOptionCollection = Ecommerce.Services.FieldOptions.GetOptionsByFieldId(categoryListBoxField.Id); - lookupCollection = new Dictionary(); - foreach (var fieldOption in fieldOptionCollection) - { - lookupCollection[fieldOption.Value] = fieldOption; - } - FieldOptions.Add(field, lookupCollection); - } - - result = new KeyValuePair>(categoryListBoxField, lookupCollection); - } - } - return result; } + return result; + } - public bool IsMultipleSelectionListBoxField(KeyValuePair> options) + public bool IsMultipleSelectionListBoxField(KeyValuePair> options) + { + bool multipleSelectionList = false; + if (options.Key != null && options.Value != null) { - bool multipleSelectionList = false; - if (options.Key != null && options.Value != null) + if (options.Key is ProductField) { - if (options.Key is ProductField) - { - ProductField customListBoxField = (ProductField)options.Key; - if (customListBoxField.ListPresentationType == FieldListPresentationType.CheckBoxList || + ProductField customListBoxField = (ProductField)options.Key; + if (customListBoxField.ListPresentationType == FieldListPresentationType.CheckBoxList || customListBoxField.ListPresentationType == FieldListPresentationType.MultiSelectList) - { - multipleSelectionList = true; - } - } - else if (options.Key is Field) { - Field categoryListBoxField = (Field)options.Key; - if (categoryListBoxField.PresentationType == FieldListPresentationType.CheckBoxList || + multipleSelectionList = true; + } + } + else if (options.Key is Field) + { + Field categoryListBoxField = (Field)options.Key; + if (categoryListBoxField.PresentationType == FieldListPresentationType.CheckBoxList || categoryListBoxField.PresentationType == FieldListPresentationType.MultiSelectList) - { - multipleSelectionList = true; - } + { + multipleSelectionList = true; } } - return multipleSelectionList; } + return multipleSelectionList; + } - public string GetFieldOptionValue(string fieldValue, KeyValuePair> options, bool multipleSelectionList, string languageId) + public string GetFieldOptionValue(string fieldValue, KeyValuePair> options, bool multipleSelectionList, string languageId) + { + if (options.Key != null && options.Value != null) { - if (options.Key != null && options.Value != null) + if (multipleSelectionList && fieldValue.Contains(",")) { - if (multipleSelectionList && fieldValue.Contains(",")) + var selectedOptionIds = fieldValue.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); + var selectedOptions = new List(); + foreach (var selectedOptionId in selectedOptionIds) { - var selectedOptionIds = fieldValue.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); - var selectedOptions = new List(); - foreach (var selectedOptionId in selectedOptionIds) + if (options.Value.TryGetValue(selectedOptionId, out FieldOption selectedOption)) { - if (options.Value.TryGetValue(selectedOptionId, out FieldOption selectedOption)) - { - selectedOptions.Add(selectedOption); - } + selectedOptions.Add(selectedOption); } + } - if (selectedOptions != null && selectedOptions.Any()) - { - fieldValue = string.Join(",", selectedOptions.Select(o => GetTranslatedOptionName(options.Key, o, languageId))); - } + if (selectedOptions != null && selectedOptions.Any()) + { + fieldValue = string.Join(",", selectedOptions.Select(o => GetTranslatedOptionName(options.Key, o, languageId))); } - else + } + else + { + if (options.Value.TryGetValue(fieldValue, out FieldOption option)) { - if (options.Value.TryGetValue(fieldValue, out FieldOption option)) - { - string optionName = GetTranslatedOptionName(options.Key, option, languageId); - fieldValue = $"{optionName}"; - } + string optionName = GetTranslatedOptionName(options.Key, option, languageId); + fieldValue = $"{optionName}"; } } - return fieldValue; } + return fieldValue; + } - public string GetTranslatedOptionName(object field, FieldOption option, string languageId) + public string GetTranslatedOptionName(object field, FieldOption option, string languageId) + { + string optionName = option.GetName(languageId); + if (!string.IsNullOrEmpty(languageId)) { - string optionName = option.GetName(languageId); - if (!string.IsNullOrEmpty(languageId)) + Dictionary optionTranslations = null; + if (FieldOptionTranslations.TryGetValue(option.Id, out optionTranslations)) { - Dictionary optionTranslations = null; - if (FieldOptionTranslations.TryGetValue(option.Id, out optionTranslations)) + if (optionTranslations.TryGetValue(languageId, out optionName)) { - if (optionTranslations.TryGetValue(languageId, out optionName)) - { - return optionName; - } + return optionName; } + } - if (field is ProductField) + if (field is ProductField) + { + string translatedName = option.GetName(languageId); + if (!string.IsNullOrEmpty(translatedName)) { - string translatedName = option.GetName(languageId); - if (!string.IsNullOrEmpty(translatedName)) - { - optionName = translatedName; - SetOptionTranslationsCache(option.Id, languageId, translatedName); - } + optionName = translatedName; + SetOptionTranslationsCache(option.Id, languageId, translatedName); } - else if (field is Field) + } + else if (field is Field) + { + //category field option + Field categoryListBoxField = (Field)field; + if (categoryListBoxField != null && categoryListBoxField.Category != null) { - //category field option - Field categoryListBoxField = (Field)field; - if (categoryListBoxField != null && categoryListBoxField.Category != null) + var categoryField = Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryListBoxField.Category.Id, categoryListBoxField.Id); + if (categoryField != null) { - var categoryField = Ecommerce.Services.ProductCategoryFields.GetFieldById(categoryListBoxField.Category.Id, categoryListBoxField.Id); - if (categoryField != null) + var categoryFieldOption = Ecommerce.Services.FieldOptions.GetOptionById(option.Id); + if (categoryFieldOption != null && !string.IsNullOrEmpty(categoryFieldOption.GetName(languageId))) { - var categoryFieldOption = Ecommerce.Services.FieldOptions.GetOptionById(option.Id); - if (categoryFieldOption != null && !string.IsNullOrEmpty(categoryFieldOption.GetName(languageId))) - { - optionName = categoryFieldOption.GetName(languageId); - SetOptionTranslationsCache(option.Id, languageId, categoryFieldOption.GetName(languageId)); - } + optionName = categoryFieldOption.GetName(languageId); + SetOptionTranslationsCache(option.Id, languageId, categoryFieldOption.GetName(languageId)); } - } + } } - return optionName; } + return optionName; + } - private void SetOptionTranslationsCache(string optionId, string languageId, string value) + private void SetOptionTranslationsCache(string optionId, string languageId, string value) + { + Dictionary optionTranslations = null; + if (!FieldOptionTranslations.TryGetValue(optionId, out optionTranslations)) { - Dictionary optionTranslations = null; - if (!FieldOptionTranslations.TryGetValue(optionId, out optionTranslations)) - { - optionTranslations = new Dictionary(); - FieldOptionTranslations.Add(optionId, optionTranslations); - } - - optionTranslations[languageId] = value; + optionTranslations = new Dictionary(); + FieldOptionTranslations.Add(optionId, optionTranslations); } - public ICollection GetTranslatedOptions(string languageId, KeyValuePair> options) - { - IList result = new List(); + optionTranslations[languageId] = value; + } + + public ICollection GetTranslatedOptions(string languageId, KeyValuePair> options) + { + IList result = new List(); - if (options.Key != null && options.Value != null) + if (options.Key != null && options.Value != null) + { + foreach (var option in options.Value.Values) { - foreach (var option in options.Value.Values) + string optionName = option.GetName(languageId); + if (!string.IsNullOrEmpty(languageId)) { - string optionName = option.GetName(languageId); - if (!string.IsNullOrEmpty(languageId)) - { - optionName = GetTranslatedOptionName(options.Key, option, languageId); - } - - result.Add(optionName); + optionName = GetTranslatedOptionName(options.Key, option, languageId); } - } - return result; + result.Add(optionName); + } } + + return result; } -} +} \ No newline at end of file