public ImportJobMappingStepViewModel(IRepositoryFactory<IImportRepository> repositoryFactory, IRepositoryFactory<ICatalogRepository> catalogRepositoryFactory, 
			ImportJob item, WizardViewModelBare parentVM,
			IImportJobEntityFactory importFactory,
			IViewModelsFactory<IPickAssetViewModel> assetVmFactory,
			IViewModelsFactory<IColumnMappingViewModel> mappingVmFactory,
			IImportService importService,
			ImportEntityType[] entityImporters,
			IAuthenticationContext authContext)
			: base(repositoryFactory, catalogRepositoryFactory, importFactory, item, parentVM, assetVmFactory, mappingVmFactory, importService, entityImporters, authContext)
		{
		}
		public CreateImportJobViewModel(
			IViewModelsFactory<IImportJobOverviewStepViewModel> overviewVmFactory,
			IViewModelsFactory<IImportJobMappingStepViewModel> mappingVmFactory,
			ImportJob item, 
			ImportEntityType[] entityImporters)
		{
			var itemParameter = new KeyValuePair<string, object>("item", item);
			var parentVM = new KeyValuePair<string, object>("parentVM", this);
			var _entityImporters = new KeyValuePair<string, object>("entityImporters", entityImporters);
			RegisterStep(overviewVmFactory.GetViewModelInstance(itemParameter, parentVM, _entityImporters));
			RegisterStep(mappingVmFactory.GetViewModelInstance(itemParameter, parentVM));
		}
        public virtual Dictionary<string, string> GetImportableEntityProperties(ImportEntityType entityType)
        {
            if (_entityProperties == null)
            {
                lock (_lock)
                {
                    if (_entityProperties == null)
                    {
                        _entityProperties = new Dictionary<ImportEntityType, Dictionary<string, string>>();

                        var context = ((IObjectContextAdapter)_importProfileRepository.Context).ObjectContext;
                        var container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);

                        var allLanguages = _languageService.GetAllLanguages(true);
                        var allLanguageNames = allLanguages.ToDictionarySafe(x => x.UniqueSeoCode, x => LocalizationHelper.GetLanguageNativeName(x.LanguageCulture) ?? x.Name);

                        var localizableProperties = new Dictionary<ImportEntityType, string[]>
                        {
                            { ImportEntityType.Product, new string[] { "Name", "ShortDescription", "FullDescription", "MetaKeywords", "MetaDescription", "MetaTitle", "SeName" } },
                            { ImportEntityType.Category, new string[] { "Name", "FullName", "Description", "BottomDescription", "MetaKeywords", "MetaDescription", "MetaTitle", "SeName" } },
                            { ImportEntityType.Customer, new string[] {  } },
                            { ImportEntityType.NewsLetterSubscription, new string[] {  } }
                        };

                        var addressSet = container.GetEntitySetByName("Addresses", true);

                        var addressProperties = addressSet.ElementType.Members
                            .Where(x => !x.Name.IsCaseInsensitiveEqual("Id") && x.BuiltInTypeKind.HasFlag(BuiltInTypeKind.EdmProperty))
                            .Select(x => x.Name)
                            .ToList();

                        foreach (ImportEntityType type in Enum.GetValues(typeof(ImportEntityType)))
                        {
                            EntitySet entitySet = null;

                            try
                            {
                                if (type == ImportEntityType.Category)
                                    entitySet = container.GetEntitySetByName("Categories", true);
                                else
                                    entitySet = container.GetEntitySetByName(type.ToString() + "s", true);
                            }
                            catch (Exception)
                            {
                                throw new SmartException("There is no entity set for ImportEntityType {0}. Note, the enum value must equal the entity name.".FormatInvariant(type.ToString()));
                            }

                            var dic = entitySet.ElementType.Members
                                .Where(x => !x.Name.IsCaseInsensitiveEqual("Id") && x.BuiltInTypeKind.HasFlag(BuiltInTypeKind.EdmProperty))
                                .Select(x => x.Name)
                                .ToDictionary(x => x, x => "", StringComparer.OrdinalIgnoreCase);

                            // lack of abstractness?
                            if ((type == ImportEntityType.Product || type == ImportEntityType.Category) && !dic.ContainsKey("SeName"))
                            {
                                dic.Add("SeName", "");
                            }

                            // shipping and billing address
                            if (type == ImportEntityType.Customer)
                            {
                                foreach (var property in addressProperties)
                                {
                                    dic.Add("BillingAddress." + property, "");
                                    dic.Add("ShippingAddress." + property, "");
                                }
                            }

                            // add localized property names
                            foreach (var key in dic.Keys.ToList())
                            {
                                var localizedValue = GetLocalizedPropertyName(type, key);

                                dic[key] = localizedValue.NaIfEmpty();

                                if (localizableProperties[type].Contains(key))
                                {
                                    foreach (var language in allLanguages)
                                    {
                                        dic.Add(
                                            "{0}[{1}]".FormatInvariant(key, language.UniqueSeoCode.EmptyNull().ToLower()),
                                            "{0} {1}".FormatInvariant(localizedValue.NaIfEmpty(), allLanguageNames[language.UniqueSeoCode])
                                        );
                                    }
                                }
                            }

                            _entityProperties.Add(type, dic);
                        }
                    }
                }
            }

            return (_entityProperties.ContainsKey(entityType) ? _entityProperties[entityType] : null);
        }
        private string GetLocalizedPropertyName(ImportEntityType type, string property)
        {
            if (property.IsEmpty())
                return "";

            string key = null;
            string prefixKey = null;

            if (property.StartsWith("BillingAddress."))
                prefixKey = "Admin.Orders.Fields.BillingAddress";
            else if (property.StartsWith("ShippingAddress."))
                prefixKey = "Admin.Orders.Fields.ShippingAddress";

            #region Get resource key

            switch (property)
            {
                case "Id":
                    key = "Admin.Common.Entity.Fields.Id";
                    break;
                case "LimitedToStores":
                    key = "Admin.Common.Store.LimitedTo";
                    break;
                case "DisplayOrder":
                    key = "Common.DisplayOrder";
                    break;
                case "Deleted":
                    key = "Admin.Common.Deleted";
                    break;
                case "CreatedOnUtc":
                case "BillingAddress.CreatedOnUtc":
                case "ShippingAddress.CreatedOnUtc":
                    key = "Common.CreatedOn";
                    break;
                case "UpdatedOnUtc":
                    key = "Common.UpdatedOn";
                    break;
                case "HasDiscountsApplied":
                    key = "Admin.Catalog.Products.Fields.HasDiscountsApplied";
                    break;
                case "DefaultViewMode":
                    key = "Admin.Configuration.Settings.Catalog.DefaultViewMode";
                    break;
                case "StoreId":
                    key = "Admin.Common.Store";
                    break;
                case "ParentGroupedProductId":
                    key = "Admin.Catalog.Products.Fields.AssociatedToProductName";
                    break;
                case "PasswordFormatId":
                    key = "Admin.Configuration.Settings.CustomerUser.DefaultPasswordFormat";
                    break;
                case "LastIpAddress":
                    key = "Admin.Customers.Customers.Fields.IPAddress";
                    break;
                default:
                    switch (type)
                    {
                        case ImportEntityType.Product:
                            key = "Admin.Catalog.Products.Fields." + property;
                            break;
                        case ImportEntityType.Category:
                            key = "Admin.Catalog.Categories.Fields." + property;
                            break;
                        case ImportEntityType.Customer:
                            if (property.StartsWith("BillingAddress.") || property.StartsWith("ShippingAddress."))
                                key = "Admin.Address.Fields." + property.Substring(property.IndexOf('.') + 1);
                            else
                                key = "Admin.Customers.Customers.Fields." + property;
                            break;
                        case ImportEntityType.NewsLetterSubscription:
                            key = "Admin.Promotions.NewsLetterSubscriptions.Fields." + property;
                            break;
                    }
                    break;
            }

            #endregion

            if (key.IsEmpty())
                return "";

            var result = _localizationService.GetResource(key, 0, false, "", true);

            if (result.IsEmpty())
            {
                if (key.EndsWith("Id"))
                    result = _localizationService.GetResource(key.Substring(0, key.Length - 2), 0, false, "", true);
                else if (key.EndsWith("Utc"))
                    result = _localizationService.GetResource(key.Substring(0, key.Length - 3), 0, false, "", true);
            }

            if (result.IsEmpty())
            {
                Debug.WriteLine("Missing string resource mapping for {0} - {1}".FormatInvariant(type.ToString(), property));
                result = property.SplitPascalCase();
            }

            if (prefixKey.HasValue())
            {
                result = string.Concat(_localizationService.GetResource(prefixKey, 0, false, "", true), " - ", result);
            }

            return result;
        }
        public virtual ImportProfile InsertImportProfile(string fileName, string name, ImportEntityType entityType)
        {
            Guard.ArgumentNotEmpty(() => fileName);

            if (name.IsEmpty())
                name = GetNewProfileName(entityType);

            var task = new ScheduleTask
            {
                CronExpression = "0 */24 * * *",
                Type = typeof(DataImportTask).AssemblyQualifiedNameWithoutVersion(),
                Enabled = false,
                StopOnError = false,
                IsHidden = true
            };

            task.Name = string.Concat(name, " Task");

            _scheduleTaskService.InsertTask(task);

            var profile = new ImportProfile
            {
                Name = name,
                EntityType = entityType,
                Enabled = true,
                SchedulingTaskId = task.Id
            };

            if (Path.GetExtension(fileName).IsCaseInsensitiveEqual(".xlsx"))
                profile.FileType = ImportFileType.XLSX;
            else
                profile.FileType = ImportFileType.CSV;

            string[] keyFieldNames = null;

            switch (entityType)
            {
                case ImportEntityType.Product:
                    keyFieldNames = ProductImporter.DefaultKeyFields;
                    break;
                case ImportEntityType.Category:
                    keyFieldNames = CategoryImporter.DefaultKeyFields;
                    break;
                case ImportEntityType.Customer:
                    keyFieldNames = CustomerImporter.DefaultKeyFields;
                    break;
                case ImportEntityType.NewsLetterSubscription:
                    keyFieldNames = NewsLetterSubscriptionImporter.DefaultKeyFields;
                    break;
            }

            profile.KeyFieldNames = string.Join(",", keyFieldNames);

            profile.FolderName = SeoHelper.GetSeName(name, true, false)
                .ToValidPath()
                .Truncate(_dataExchangeSettings.MaxFileNameLength);

            profile.FolderName = FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/App_Data/ImportProfiles"), profile.FolderName);

            _importProfileRepository.Insert(profile);

            task.Alias = profile.Id.ToString();
            _scheduleTaskService.UpdateTask(task);

            _eventPublisher.EntityInserted(profile);

            return profile;
        }
        public string GetNewProfileName(ImportEntityType entityType)
        {
            var defaultNames = _localizationService.GetResource("Admin.DataExchange.Import.DefaultProfileNames").SplitSafe(";");

            var result = defaultNames.SafeGet((int)entityType);

            if (result.IsEmpty())
                result = entityType.ToString();

            var profileCount = _importProfileRepository.Table.Count(x => x.EntityTypeId == (int)entityType);

            result = string.Concat(result, " ", profileCount + 1);

            return result;
        }