private void ImportCoreInner(DataImporterContext ctx, string filePath) { if (ctx.ExecuteContext.Abort == DataExchangeAbortion.Hard) return; { var logHead = new StringBuilder(); logHead.AppendLine(); logHead.AppendLine(new string('-', 40)); logHead.AppendLine("SmartStore.NET:\t\tv." + SmartStoreVersion.CurrentFullVersion); logHead.Append("Import profile:\t\t" + ctx.Request.Profile.Name); logHead.AppendLine(ctx.Request.Profile.Id == 0 ? " (volatile)" : " (Id {0})".FormatInvariant(ctx.Request.Profile.Id)); logHead.AppendLine("Entity:\t\t\t" + ctx.Request.Profile.EntityType.ToString()); logHead.AppendLine("File:\t\t\t" + Path.GetFileName(filePath)); var customer = _services.WorkContext.CurrentCustomer; logHead.Append("Executed by:\t\t" + (customer.Email.HasValue() ? customer.Email : customer.SystemName)); ctx.Log.Information(logHead.ToString()); } if (!File.Exists(filePath)) { throw new SmartException("File does not exist {0}.".FormatInvariant(filePath)); } CsvConfiguration csvConfiguration = null; var extension = Path.GetExtension(filePath); if ((new string[] { ".csv", ".txt", ".tab" }).Contains(extension, StringComparer.OrdinalIgnoreCase)) { var converter = new CsvConfigurationConverter(); csvConfiguration = converter.ConvertFrom<CsvConfiguration>(ctx.Request.Profile.FileTypeConfiguration); } if (csvConfiguration == null) { csvConfiguration = CsvConfiguration.ExcelFriendlyConfiguration; } using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { ctx.ExecuteContext.DataTable = LightweightDataTable.FromFile( Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, ctx.Request.Profile.Skip, ctx.Request.Profile.Take > 0 ? ctx.Request.Profile.Take : int.MaxValue ); try { ctx.Importer.Execute(ctx.ExecuteContext); } catch (Exception exception) { ctx.ExecuteContext.Abort = DataExchangeAbortion.Hard; ctx.ExecuteContext.Result.AddError(exception, "The importer failed: {0}.".FormatInvariant(exception.ToAllMessages())); } if (ctx.ExecuteContext.IsMaxFailures) ctx.ExecuteContext.Result.AddWarning("Import aborted. The maximum number of failures has been reached."); if (ctx.CancellationToken.IsCancellationRequested) ctx.ExecuteContext.Result.AddWarning("Import aborted. A cancellation has been requested."); } }
private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit, ColumnMap invalidMap = null) { model.Id = profile.Id; model.Name = profile.Name; model.EntityType = profile.EntityType; model.Enabled = profile.Enabled; model.Skip = (profile.Skip == 0 ? (int?)null : profile.Skip); model.Take = (profile.Take == 0 ? (int?)null : profile.Take); model.UpdateOnly = profile.UpdateOnly; model.KeyFieldNames = profile.KeyFieldNames.SplitSafe(",").Distinct().ToArray(); model.ScheduleTaskId = profile.SchedulingTaskId; model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); model.IsTaskRunning = profile.ScheduleTask.IsRunning; model.IsTaskEnabled = profile.ScheduleTask.Enabled; model.LogFileExists = System.IO.File.Exists(profile.GetImportLogPath()); model.EntityTypeName = profile.EntityType.GetLocalizedEnum(Services.Localization, Services.WorkContext); model.ExistingFileNames = profile.GetImportFiles() .Select(x => Path.GetFileName(x)) .ToList(); if (profile.ResultInfo.HasValue()) { model.ImportResult = XmlHelper.Deserialize <SerializableImportResult>(profile.ResultInfo); } if (!forEdit) { return; } CsvConfiguration csvConfiguration = null; if (profile.FileType == ImportFileType.CSV) { var csvConverter = new CsvConfigurationConverter(); csvConfiguration = csvConverter.ConvertFrom <CsvConfiguration>(profile.FileTypeConfiguration) ?? CsvConfiguration.ExcelFriendlyConfiguration; model.CsvConfiguration = new CsvConfigurationModel(csvConfiguration); } else { csvConfiguration = CsvConfiguration.ExcelFriendlyConfiguration; } // common configuration var extraData = XmlHelper.Deserialize <ImportExtraData>(profile.ExtraData); model.ExtraData.NumberOfPictures = extraData.NumberOfPictures; // column mapping model.AvailableSourceColumns = new List <ColumnMappingItemModel>(); model.AvailableEntityProperties = new List <ColumnMappingItemModel>(); model.AvailableKeyFieldNames = new List <SelectListItem>(); model.ColumnMappings = new List <ColumnMappingItemModel>(); try { string[] availableKeyFieldNames = null; string[] disabledDefaultFieldNames = GetDisabledDefaultFieldNames(profile); var mapConverter = new ColumnMapConverter(); var storedMap = mapConverter.ConvertFrom <ColumnMap>(profile.ColumnMapping); var map = (invalidMap ?? storedMap) ?? new ColumnMap(); // property name to localized property name var allProperties = _importProfileService.GetImportableEntityProperties(profile.EntityType); switch (profile.EntityType) { case ImportEntityType.Product: availableKeyFieldNames = ProductImporter.SupportedKeyFields; break; case ImportEntityType.Category: availableKeyFieldNames = CategoryImporter.SupportedKeyFields; break; case ImportEntityType.Customer: availableKeyFieldNames = CustomerImporter.SupportedKeyFields; break; case ImportEntityType.NewsLetterSubscription: availableKeyFieldNames = NewsLetterSubscriptionImporter.SupportedKeyFields; break; } model.AvailableEntityProperties = allProperties .Select(x => { var mapping = new ColumnMappingItemModel { Property = x.Key, PropertyDescription = x.Value, IsDefaultDisabled = IsDefaultValueDisabled(x.Key, x.Key, disabledDefaultFieldNames) }; return(mapping); }) .ToList(); model.AvailableKeyFieldNames = availableKeyFieldNames .Select(x => { var item = new SelectListItem { Value = x, Text = x }; if (x == "Id") { item.Text = T("Admin.Common.Entity.Fields.Id"); } else if (allProperties.ContainsKey(x)) { item.Text = allProperties[x]; } return(item); }) .ToList(); model.ColumnMappings = map.Mappings .Select(x => { var mapping = new ColumnMappingItemModel { Column = x.Value.MappedName, Property = x.Key, Default = x.Value.Default }; if (x.Value.IgnoreProperty) { // explicitly ignore the property mapping.Column = null; mapping.Default = null; } mapping.PropertyDescription = GetPropertyDescription(allProperties, mapping.Property); mapping.IsDefaultDisabled = IsDefaultValueDisabled(mapping.Column, mapping.Property, disabledDefaultFieldNames); return(mapping); }) .ToList(); var files = profile.GetImportFiles(); if (!files.Any()) { return; } var filePath = files.First(); using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 1); foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) { string columnWithoutIndex, columnIndex; ColumnMap.ParseSourceName(column.Name, out columnWithoutIndex, out columnIndex); model.AvailableSourceColumns.Add(new ColumnMappingItemModel { Index = dataTable.Columns.IndexOf(column), Column = column.Name, ColumnWithoutIndex = columnWithoutIndex, ColumnIndex = columnIndex, PropertyDescription = GetPropertyDescription(allProperties, column.Name) }); // auto map where field equals property name if (!model.ColumnMappings.Any(x => x.Column == column.Name)) { var kvp = allProperties.FirstOrDefault(x => x.Key.IsCaseInsensitiveEqual(column.Name)); if (kvp.Key.IsEmpty()) { var alternativeName = LightweightDataTable.GetAlternativeColumnNameFor(column.Name); kvp = allProperties.FirstOrDefault(x => x.Key.IsCaseInsensitiveEqual(alternativeName)); } if (kvp.Key.HasValue() && !model.ColumnMappings.Any(x => x.Property == kvp.Key)) { model.ColumnMappings.Add(new ColumnMappingItemModel { Column = column.Name, Property = kvp.Key, PropertyDescription = kvp.Value, IsDefaultDisabled = IsDefaultValueDisabled(column.Name, kvp.Key, disabledDefaultFieldNames) }); } } } // sorting model.AvailableSourceColumns = model.AvailableSourceColumns .OrderBy(x => x.PropertyDescription) .ToList(); model.AvailableEntityProperties = model.AvailableEntityProperties .OrderBy(x => x.PropertyDescription) .ToList(); model.ColumnMappings = model.ColumnMappings .OrderBy(x => x.PropertyDescription) .ToList(); } } catch (Exception exception) { NotifyError(exception, true, false); } }
public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCollection form) { if (!Services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) { return(AccessDeniedView()); } var profile = _importProfileService.GetImportProfileById(model.Id); if (profile == null) { return(RedirectToAction("List")); } var map = new ColumnMap(); var hasErrors = false; var resetMappings = false; try { var propertyKeyPrefix = "ColumnMapping.Property."; var allPropertyKeys = form.AllKeys.Where(x => x.HasValue() && x.StartsWith(propertyKeyPrefix)); if (allPropertyKeys.Any()) { var entityProperties = _importProfileService.GetImportableEntityProperties(profile.EntityType); foreach (var key in allPropertyKeys) { var index = key.Substring(propertyKeyPrefix.Length); var property = form[key]; var column = form["ColumnMapping.Column." + index]; var defaultValue = form["ColumnMapping.Default." + index]; if (column.IsEmpty()) { // tell mapper to explicitly ignore the property map.AddMapping(property, null, property, "[IGNOREPROPERTY]"); } else if (!column.IsCaseInsensitiveEqual(property) || defaultValue.HasValue()) { if (defaultValue.HasValue() && GetDisabledDefaultFieldNames(profile).Contains(property)) { defaultValue = null; } map.AddMapping(property, null, column, defaultValue); } } } } catch (Exception exception) { hasErrors = true; NotifyError(exception, true, false); } if (!ModelState.IsValid || hasErrors) { PrepareProfileModel(model, profile, true, map); return(View(model)); } profile.Name = model.Name; profile.EntityType = model.EntityType; profile.Enabled = model.Enabled; profile.Skip = model.Skip ?? 0; profile.Take = model.Take ?? 0; profile.UpdateOnly = model.UpdateOnly; profile.KeyFieldNames = (model.KeyFieldNames == null ? null : string.Join(",", model.KeyFieldNames)); try { if (profile.FileType == ImportFileType.CSV && model.CsvConfiguration != null) { var csvConverter = new CsvConfigurationConverter(); var oldCsvConfig = csvConverter.ConvertFrom <CsvConfiguration>(profile.FileTypeConfiguration); var oldDelimiter = (oldCsvConfig != null ? oldCsvConfig.Delimiter.ToString() : null); // auto reset mappings cause they are invalid. note: delimiter can be whitespaced, so no oldDelimter.HasValue() etc. resetMappings = (oldDelimiter != model.CsvConfiguration.Delimiter && profile.ColumnMapping.HasValue()); profile.FileTypeConfiguration = csvConverter.ConvertTo(model.CsvConfiguration.Clone()); } else { profile.FileTypeConfiguration = null; } if (resetMappings) { profile.ColumnMapping = null; } else { var mapConverter = new ColumnMapConverter(); profile.ColumnMapping = mapConverter.ConvertTo(map); } if (model.ExtraData != null) { var extraData = new ImportExtraData { NumberOfPictures = model.ExtraData.NumberOfPictures }; profile.ExtraData = XmlHelper.Serialize(extraData); } } catch (Exception exception) { hasErrors = true; NotifyError(exception, true, false); } if (!hasErrors) { _importProfileService.UpdateImportProfile(profile); NotifySuccess(T("Admin.Common.DataSuccessfullySaved")); if (resetMappings) { NotifyWarning(T("Admin.DataExchange.ColumnMapping.Validate.MappingsReset")); } } return(continueEditing ? RedirectToAction("Edit", new { id = profile.Id }) : RedirectToAction("List")); }
private void ImportCoreInner(DataImporterContext ctx, string filePath) { if (ctx.ExecuteContext.Abort == DataExchangeAbortion.Hard) { return; } { var logHead = new StringBuilder(); logHead.AppendLine(); logHead.AppendLine(new string('-', 40)); logHead.AppendLine("SmartStore.NET:\t\tv." + SmartStoreVersion.CurrentFullVersion); logHead.Append("Import profile:\t\t" + ctx.Request.Profile.Name); logHead.AppendLine(ctx.Request.Profile.Id == 0 ? " (volatile)" : " (Id {0})".FormatInvariant(ctx.Request.Profile.Id)); logHead.AppendLine("Entity:\t\t\t" + ctx.Request.Profile.EntityType.ToString()); logHead.AppendLine("File:\t\t\t" + Path.GetFileName(filePath)); var customer = _services.WorkContext.CurrentCustomer; logHead.Append("Executed by:\t\t" + (customer.Email.HasValue() ? customer.Email : customer.SystemName)); ctx.Log.Information(logHead.ToString()); } if (!File.Exists(filePath)) { throw new SmartException("File does not exist {0}.".FormatInvariant(filePath)); } CsvConfiguration csvConfiguration = null; var extension = Path.GetExtension(filePath); if ((new string[] { ".csv", ".txt", ".tab" }).Contains(extension, StringComparer.OrdinalIgnoreCase)) { var converter = new CsvConfigurationConverter(); csvConfiguration = converter.ConvertFrom <CsvConfiguration>(ctx.Request.Profile.FileTypeConfiguration); } if (csvConfiguration == null) { csvConfiguration = CsvConfiguration.ExcelFriendlyConfiguration; } using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { ctx.ExecuteContext.DataTable = LightweightDataTable.FromFile( Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, ctx.Request.Profile.Skip, ctx.Request.Profile.Take > 0 ? ctx.Request.Profile.Take : int.MaxValue ); try { ctx.Importer.Execute(ctx.ExecuteContext); } catch (Exception exception) { ctx.ExecuteContext.Abort = DataExchangeAbortion.Hard; ctx.ExecuteContext.Result.AddError(exception, "The importer failed: {0}.".FormatInvariant(exception.ToAllMessages())); } if (ctx.ExecuteContext.IsMaxFailures) { ctx.ExecuteContext.Result.AddWarning("Import aborted. The maximum number of failures has been reached."); } if (ctx.CancellationToken.IsCancellationRequested) { ctx.ExecuteContext.Result.AddWarning("Import aborted. A cancellation has been requested."); } } }
private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit, ColumnMap invalidMap = null) { model.Id = profile.Id; model.Name = profile.Name; model.EntityType = profile.EntityType; model.Enabled = profile.Enabled; model.Skip = (profile.Skip == 0 ? (int?)null : profile.Skip); model.Take = (profile.Take == 0 ? (int?)null : profile.Take); model.UpdateOnly = profile.UpdateOnly; model.KeyFieldNames = profile.KeyFieldNames.SplitSafe(",").Distinct().ToArray(); model.ScheduleTaskId = profile.SchedulingTaskId; model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); model.IsTaskRunning = profile.ScheduleTask.IsRunning; model.IsTaskEnabled = profile.ScheduleTask.Enabled; model.LogFileExists = System.IO.File.Exists(profile.GetImportLogPath()); model.EntityTypeName = profile.EntityType.GetLocalizedEnum(Services.Localization, Services.WorkContext); model.ExistingFileNames = profile.GetImportFiles() .Select(x => Path.GetFileName(x)) .ToList(); if (profile.ResultInfo.HasValue()) model.ImportResult = XmlHelper.Deserialize<SerializableImportResult>(profile.ResultInfo); if (!forEdit) return; CsvConfiguration csvConfiguration = null; if (profile.FileType == ImportFileType.CSV) { var csvConverter = new CsvConfigurationConverter(); csvConfiguration = csvConverter.ConvertFrom<CsvConfiguration>(profile.FileTypeConfiguration) ?? CsvConfiguration.ExcelFriendlyConfiguration; model.CsvConfiguration = new CsvConfigurationModel(csvConfiguration); } else { csvConfiguration = CsvConfiguration.ExcelFriendlyConfiguration; } // common configuration var extraData = XmlHelper.Deserialize<ImportExtraData>(profile.ExtraData); model.ExtraData.NumberOfPictures = extraData.NumberOfPictures; // column mapping model.AvailableSourceColumns = new List<ColumnMappingItemModel>(); model.AvailableEntityProperties = new List<ColumnMappingItemModel>(); model.AvailableKeyFieldNames = new List<SelectListItem>(); model.ColumnMappings = new List<ColumnMappingItemModel>(); try { string[] availableKeyFieldNames = null; string[] disabledDefaultFieldNames = GetDisabledDefaultFieldNames(profile); var mapConverter = new ColumnMapConverter(); var storedMap = mapConverter.ConvertFrom<ColumnMap>(profile.ColumnMapping); var map = (invalidMap ?? storedMap) ?? new ColumnMap(); // property name to localized property name var allProperties = _importProfileService.GetImportableEntityProperties(profile.EntityType); switch (profile.EntityType) { case ImportEntityType.Product: availableKeyFieldNames = ProductImporter.SupportedKeyFields; break; case ImportEntityType.Category: availableKeyFieldNames = CategoryImporter.SupportedKeyFields; break; case ImportEntityType.Customer: availableKeyFieldNames = CustomerImporter.SupportedKeyFields; break; case ImportEntityType.NewsLetterSubscription: availableKeyFieldNames = NewsLetterSubscriptionImporter.SupportedKeyFields; break; } model.AvailableEntityProperties = allProperties .Select(x => { var mapping = new ColumnMappingItemModel { Property = x.Key, PropertyDescription = x.Value, IsDefaultDisabled = IsDefaultValueDisabled(x.Key, x.Key, disabledDefaultFieldNames) }; return mapping; }) .ToList(); model.AvailableKeyFieldNames = availableKeyFieldNames .Select(x => { var item = new SelectListItem { Value = x, Text = x }; if (x == "Id") item.Text = T("Admin.Common.Entity.Fields.Id"); else if (allProperties.ContainsKey(x)) item.Text = allProperties[x]; return item; }) .ToList(); model.ColumnMappings = map.Mappings .Select(x => { var mapping = new ColumnMappingItemModel { Column = x.Value.MappedName, Property = x.Key, Default = x.Value.Default }; if (x.Value.IgnoreProperty) { // explicitly ignore the property mapping.Column = null; mapping.Default = null; } mapping.PropertyDescription = GetPropertyDescription(allProperties, mapping.Property); mapping.IsDefaultDisabled = IsDefaultValueDisabled(mapping.Column, mapping.Property, disabledDefaultFieldNames); return mapping; }) .ToList(); var files = profile.GetImportFiles(); if (!files.Any()) return; var filePath = files.First(); using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 1); foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) { string columnWithoutIndex, columnIndex; ColumnMap.ParseSourceName(column.Name, out columnWithoutIndex, out columnIndex); model.AvailableSourceColumns.Add(new ColumnMappingItemModel { Index = dataTable.Columns.IndexOf(column), Column = column.Name, ColumnWithoutIndex = columnWithoutIndex, ColumnIndex = columnIndex, PropertyDescription = GetPropertyDescription(allProperties, column.Name) }); // auto map where field equals property name if (!model.ColumnMappings.Any(x => x.Column == column.Name)) { var kvp = allProperties.FirstOrDefault(x => x.Key.IsCaseInsensitiveEqual(column.Name)); if (kvp.Key.IsEmpty()) { var alternativeName = LightweightDataTable.GetAlternativeColumnNameFor(column.Name); kvp = allProperties.FirstOrDefault(x => x.Key.IsCaseInsensitiveEqual(alternativeName)); } if (kvp.Key.HasValue() && !model.ColumnMappings.Any(x => x.Property == kvp.Key)) { model.ColumnMappings.Add(new ColumnMappingItemModel { Column = column.Name, Property = kvp.Key, PropertyDescription = kvp.Value, IsDefaultDisabled = IsDefaultValueDisabled(column.Name, kvp.Key, disabledDefaultFieldNames) }); } } } // sorting model.AvailableSourceColumns = model.AvailableSourceColumns .OrderBy(x => x.PropertyDescription) .ToList(); model.AvailableEntityProperties = model.AvailableEntityProperties .OrderBy(x => x.PropertyDescription) .ToList(); model.ColumnMappings = model.ColumnMappings .OrderBy(x => x.PropertyDescription) .ToList(); } } catch (Exception exception) { NotifyError(exception, true, false); } }
public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCollection form) { if (!Services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) return AccessDeniedView(); var profile = _importProfileService.GetImportProfileById(model.Id); if (profile == null) return RedirectToAction("List"); var map = new ColumnMap(); var hasErrors = false; var resetMappings = false; try { var propertyKeyPrefix = "ColumnMapping.Property."; var allPropertyKeys = form.AllKeys.Where(x => x.HasValue() && x.StartsWith(propertyKeyPrefix)); if (allPropertyKeys.Any()) { var entityProperties = _importProfileService.GetImportableEntityProperties(profile.EntityType); foreach (var key in allPropertyKeys) { var index = key.Substring(propertyKeyPrefix.Length); var property = form[key]; var column = form["ColumnMapping.Column." + index]; var defaultValue = form["ColumnMapping.Default." + index]; if (column.IsEmpty()) { // tell mapper to explicitly ignore the property map.AddMapping(property, null, property, "[IGNOREPROPERTY]"); } else if (!column.IsCaseInsensitiveEqual(property) || defaultValue.HasValue()) { if (defaultValue.HasValue() && GetDisabledDefaultFieldNames(profile).Contains(property)) defaultValue = null; map.AddMapping(property, null, column, defaultValue); } } } } catch (Exception exception) { hasErrors = true; NotifyError(exception, true, false); } if (!ModelState.IsValid || hasErrors) { PrepareProfileModel(model, profile, true, map); return View(model); } profile.Name = model.Name; profile.EntityType = model.EntityType; profile.Enabled = model.Enabled; profile.Skip = model.Skip ?? 0; profile.Take = model.Take ?? 0; profile.UpdateOnly = model.UpdateOnly; profile.KeyFieldNames = (model.KeyFieldNames == null ? null : string.Join(",", model.KeyFieldNames)); try { if (profile.FileType == ImportFileType.CSV && model.CsvConfiguration != null) { var csvConverter = new CsvConfigurationConverter(); var oldCsvConfig = csvConverter.ConvertFrom<CsvConfiguration>(profile.FileTypeConfiguration); var oldDelimiter = (oldCsvConfig != null ? oldCsvConfig.Delimiter.ToString() : null); // auto reset mappings cause they are invalid. note: delimiter can be whitespaced, so no oldDelimter.HasValue() etc. resetMappings = (oldDelimiter != model.CsvConfiguration.Delimiter && profile.ColumnMapping.HasValue()); profile.FileTypeConfiguration = csvConverter.ConvertTo(model.CsvConfiguration.Clone()); } else { profile.FileTypeConfiguration = null; } if (resetMappings) { profile.ColumnMapping = null; } else { var mapConverter = new ColumnMapConverter(); profile.ColumnMapping = mapConverter.ConvertTo(map); } if (model.ExtraData != null) { var extraData = new ImportExtraData { NumberOfPictures = model.ExtraData.NumberOfPictures }; profile.ExtraData = XmlHelper.Serialize(extraData); } } catch (Exception exception) { hasErrors = true; NotifyError(exception, true, false); } if (!hasErrors) { _importProfileService.UpdateImportProfile(profile); NotifySuccess(T("Admin.Common.DataSuccessfullySaved")); if (resetMappings) { NotifyWarning(T("Admin.DataExchange.ColumnMapping.Validate.MappingsReset")); } } return (continueEditing ? RedirectToAction("Edit", new { id = profile.Id }) : RedirectToAction("List")); }
private void PrepareProfileModel(ImportProfileModel model, ImportProfile profile, bool forEdit, ColumnMap invalidMap = null) { if (profile == null) { if (model.Name.IsEmpty()) { var defaultNames = T("Admin.DataExchange.Import.DefaultProfileNames").Text.SplitSafe(";"); model.Name = defaultNames.SafeGet((int)model.EntityType); } model.ExistingFileNames = new List <string>(); return; } model.Id = profile.Id; model.Name = profile.Name; model.EntityType = profile.EntityType; model.Enabled = profile.Enabled; model.Skip = profile.Skip; model.Take = profile.Take; model.UpdateOnly = profile.UpdateOnly; model.KeyFieldNames = profile.KeyFieldNames.SplitSafe(",").Distinct().ToArray(); model.ScheduleTaskId = profile.SchedulingTaskId; model.ScheduleTaskName = profile.ScheduleTask.Name.NaIfEmpty(); model.IsTaskRunning = profile.ScheduleTask.IsRunning; model.IsTaskEnabled = profile.ScheduleTask.Enabled; model.LogFileExists = System.IO.File.Exists(profile.GetImportLogPath()); model.EntityTypeName = profile.EntityType.GetLocalizedEnum(_services.Localization, _services.WorkContext); model.UnspecifiedString = T("Common.Unspecified"); model.AddNewString = T("Common.AddNew"); model.DeleteString = T("Common.Delete"); model.IgnoreString = T("Admin.Common.Ignore"); model.ExistingFileNames = profile.GetImportFiles() .Select(x => Path.GetFileName(x)) .ToList(); if (profile.ResultInfo.HasValue()) { model.ImportResult = XmlHelper.Deserialize <SerializableImportResult>(profile.ResultInfo); } if (!forEdit) { return; } CsvConfiguration csvConfiguration = null; if (profile.FileType == ImportFileType.CSV) { var csvConverter = new CsvConfigurationConverter(); csvConfiguration = csvConverter.ConvertFrom <CsvConfiguration>(profile.FileTypeConfiguration) ?? CsvConfiguration.ExcelFriendlyConfiguration; model.CsvConfiguration = new CsvConfigurationModel(csvConfiguration); } else { csvConfiguration = CsvConfiguration.ExcelFriendlyConfiguration; } // column mapping model.AvailableSourceColumns = new List <ColumnMappingItemModel>(); model.AvailableEntityProperties = new List <SelectListItem>(); model.AvailableKeyFieldNames = new List <SelectListItem>(); model.ColumnMappings = new List <ColumnMappingItemModel>(); try { string[] availableKeyFieldNames = null; var mapConverter = new ColumnMapConverter(); var storedMap = mapConverter.ConvertFrom <ColumnMap>(profile.ColumnMapping); var hasStoredMappings = (storedMap != null && storedMap.Mappings.Any()); var map = (invalidMap ?? storedMap) ?? new ColumnMap(); // property name to localized property name var allProperties = _importService.GetImportableEntityProperties(profile.EntityType); switch (profile.EntityType) { case ImportEntityType.Product: availableKeyFieldNames = ProductImporter.SupportedKeyFields; break; case ImportEntityType.Category: availableKeyFieldNames = CategoryImporter.SupportedKeyFields; break; case ImportEntityType.Customer: availableKeyFieldNames = CustomerImporter.SupportedKeyFields; break; case ImportEntityType.NewsLetterSubscription: availableKeyFieldNames = NewsLetterSubscriptionImporter.SupportedKeyFields; break; } model.AvailableEntityProperties = allProperties .Select(x => new SelectListItem { Value = x.Key, Text = x.Value }) .OrderBy(x => x.Text) .ToList(); model.AvailableKeyFieldNames = availableKeyFieldNames .Select(x => { var item = new SelectListItem { Value = x, Text = x }; if (x == "Id") { item.Text = T("Admin.Common.Entity.Fields.Id"); } else if (allProperties.ContainsKey(x)) { item.Text = allProperties[x]; } return(item); }) .ToList(); model.ColumnMappings = map.Mappings .Select(x => { var mapping = new ColumnMappingItemModel { Column = (x.Value.Property.IsEmpty() ? null : x.Key), Property = (x.Value.Property.IsEmpty() ? x.Key : x.Value.Property), Default = x.Value.Default }; // add localized to make mappings sortable if (allProperties.ContainsKey(mapping.Property)) { mapping.ColumnLocalized = allProperties[mapping.Property]; } return(mapping); }) .ToList(); var files = profile.GetImportFiles(); if (!files.Any()) { return; } var filePath = files.First(); using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var dataTable = LightweightDataTable.FromFile(Path.GetFileName(filePath), stream, stream.Length, csvConfiguration, 0, 1); foreach (var column in dataTable.Columns.Where(x => x.Name.HasValue())) { string columnWithoutIndex, columnIndex; ColumnMap.ParseSourceColumn(column.Name, out columnWithoutIndex, out columnIndex); var mapModel = new ColumnMappingItemModel { Index = dataTable.Columns.IndexOf(column), Column = column.Name, ColumnWithoutIndex = columnWithoutIndex, ColumnIndex = columnIndex, ColumnLocalized = (allProperties.ContainsKey(column.Name) ? allProperties[column.Name] : column.Name) }; model.AvailableSourceColumns.Add(mapModel); // auto map where field equals property name if (!hasStoredMappings && !model.ColumnMappings.Any(x => x.Column == column.Name)) { var kvp = allProperties.FirstOrDefault(x => x.Key.IsCaseInsensitiveEqual(column.Name)); if (kvp.Key.HasValue()) { model.ColumnMappings.Add(new ColumnMappingItemModel { Column = column.Name, Property = kvp.Key, ColumnLocalized = kvp.Value }); } else { var alternativeName = LightweightDataTable.GetAlternativeColumnNameFor(column.Name); kvp = allProperties.FirstOrDefault(x => x.Key.IsCaseInsensitiveEqual(alternativeName)); if (kvp.Key.HasValue()) { model.ColumnMappings.Add(new ColumnMappingItemModel { Column = column.Name, Property = kvp.Key, ColumnLocalized = kvp.Value }); } } } } // sorting model.AvailableSourceColumns = model.AvailableSourceColumns .OrderBy(x => x.ColumnLocalized) .ToList(); model.ColumnMappings = model.ColumnMappings .OrderBy(x => x.ColumnLocalized) .ToList(); } } catch (Exception exception) { NotifyError(exception, true, false); } }
public ActionResult Edit(ImportProfileModel model, bool continueEditing, FormCollection form) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageImports)) { return(AccessDeniedView()); } var profile = _importService.GetImportProfileById(model.Id); if (profile == null) { return(RedirectToAction("List")); } var multipleMapped = new List <string>(); var map = new ColumnMap(); var hasErrors = false; var resetMappings = false; try { var propertyKeyPrefix = "ColumnMapping.Property."; var allPropertyKeys = form.AllKeys.Where(x => x.HasValue() && x.StartsWith(propertyKeyPrefix)); if (allPropertyKeys.Any()) { var entityProperties = _importService.GetImportableEntityProperties(profile.EntityType); foreach (var key in allPropertyKeys) { var index = key.Substring(propertyKeyPrefix.Length); var property = form[key]; var column = form["ColumnMapping.Column." + index]; var defaultValue = form["ColumnMapping.Default." + index]; var result = true; // ignored properties: column is empty means swap column and property (otherwise mapping impossible) if (column.IsEmpty()) { result = map.AddMapping(property, null, null); } else { result = map.AddMapping(column, null, property, defaultValue); } if (!result) { // add warning for ignored, multiple mapped properties multipleMapped.Add("{0} ({1})".FormatInvariant(entityProperties.ContainsKey(property) ? entityProperties[property] : "".NaIfEmpty(), property)); } } } } catch (Exception exception) { hasErrors = true; NotifyError(exception, true, false); } if (!ModelState.IsValid || hasErrors) { PrepareProfileModel(model, profile, true, map); return(View(model)); } profile.Name = model.Name; profile.EntityType = model.EntityType; profile.Enabled = model.Enabled; profile.Skip = model.Skip; profile.Take = model.Take; profile.UpdateOnly = model.UpdateOnly; profile.KeyFieldNames = (model.KeyFieldNames == null ? null : string.Join(",", model.KeyFieldNames)); try { if (profile.FileType == ImportFileType.CSV && model.CsvConfiguration != null) { var csvConverter = new CsvConfigurationConverter(); var oldCsvConfig = csvConverter.ConvertFrom <CsvConfiguration>(profile.FileTypeConfiguration); var oldDelimiter = (oldCsvConfig != null ? oldCsvConfig.Delimiter.ToString() : null); // auto reset mappings cause they are invalid. note: delimiter can be whitespaced, so no oldDelimter.HasValue() etc. resetMappings = (oldDelimiter != model.CsvConfiguration.Delimiter && profile.ColumnMapping.HasValue()); profile.FileTypeConfiguration = csvConverter.ConvertTo(model.CsvConfiguration.Clone()); } else { profile.FileTypeConfiguration = null; } if (resetMappings) { profile.ColumnMapping = null; } else { var mapConverter = new ColumnMapConverter(); profile.ColumnMapping = mapConverter.ConvertTo(map); } } catch (Exception exception) { hasErrors = true; NotifyError(exception, true, false); } if (!hasErrors) { _importService.UpdateImportProfile(profile); NotifySuccess(T("Admin.Common.DataSuccessfullySaved")); if (resetMappings) { NotifyWarning(T("Admin.DataExchange.ColumnMapping.Validate.MappingsReset")); } else if (multipleMapped.Any()) { NotifyWarning(T("Admin.DataExchange.ColumnMapping.Validate.MultipleMappedIgnored", "<p>" + string.Join("<br />", multipleMapped) + "</p>")); } } return(continueEditing ? RedirectToAction("Edit", new { id = profile.Id }) : RedirectToAction("List")); }