public bool IsProductsRegionIntersectionsExists(ArticleService articleService, string productsName, int[] productsIds, string regionsName) { int productTypesContentId = GetSettingValue(SettingsTitles.PRODUCT_TYPES_CONTENT_ID); CheckSiteId(productTypesContentId); int contentId = GetSettingValue(SettingsTitles.PRODUCTS_CONTENT_ID); Dictionary <int, int[]> productToRegions = articleService.List(contentId, productsIds, true) .ToDictionary(x => x.Id, x => x.FieldValues.Single(a => a.Field.Name == regionsName).RelatedItems.ToArray()); Dictionary <int, HashSet <int> > regionsToProducts = new Dictionary <int, HashSet <int> >(); foreach (var item in productToRegions) { foreach (var regionId in item.Value) { if (!regionsToProducts.ContainsKey(regionId)) { regionsToProducts.Add(regionId, new HashSet <int>()); } if (!regionsToProducts[regionId].Contains(item.Key)) { regionsToProducts[regionId].Add(item.Key); } } } var resultIds = productToRegions .Where(m => !m.Value.Select(n => regionsToProducts[n].Any(p => p != m.Key)) .Any(n => n)) .Select(m => m.Key). ToArray(); if (!resultIds.Any()) { return(true); } var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.Products_Different_Regions), Parameters = new object[] { string.Join(", ", resultIds) } }; Result.AddModelError(GetPropertyName(productsName), ToString(result)); return(false); }
public RemoteValidationResult Validate(RemoteValidationContext model, RemoteValidationResult result) { var helper = new ValidationHelper(model, result, _provider, _service); var productTypeName = _service.GetSetting(SettingsTitles.PRODUCT_TYPES_FIELD_NAME); using (new QPConnectionScope(helper.Customer.ConnectionString, (DatabaseType)helper.Customer.DatabaseType)) { var articleSerivce = new ArticleService(helper.Customer.ConnectionString, 1); var emptyArticle = articleSerivce.New(model.ContentId); var productsName = helper.GetRelatedFieldName(emptyArticle, helper.GetSettingValue(SettingsTitles.PRODUCTS_CONTENT_ID)); var marketingProductTypeId = helper.GetValue <int>(helper.GetClassifierFieldName(emptyArticle)); var productIds = helper.GetValue <ListOfInt>(productsName); if (productIds != null && AreTypesIncompatible(helper, articleSerivce, marketingProductTypeId, productIds, productTypeName)) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.SameTypeMarketingProductProducts), }; result.AddModelError(helper.GetPropertyName(productsName), helper.ToString(message)); return(result); } if (!GetUniqueAliasExclusions(helper).Contains(marketingProductTypeId)) { var ids = CheckAliasUniqueness(helper, marketingProductTypeId, articleSerivce, productTypeName); if (!String.IsNullOrEmpty(ids)) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.MarketingProduct_Duplicate_Alias), Parameters = new object[] { ids } }; result.AddModelError( helper.GetPropertyName(Constants.FieldAlias), helper.ToString(message) ); } } } return(result); }
public void CheckSiteId(int contentId) { var siteId = new ContentService(Customer.ConnectionString, 1).Read(contentId).SiteId; if (Model.SiteId != siteId) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.SiteIdInvalid), Parameters = new object[] { siteId, Model.SiteId } }; throw new ValidationException(result); } }
public T GetValue <T>(string alias) { var def = GetDefinition(alias); if (def == null) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.DefinitionNotFound), Parameters = new object[] { alias } }; throw new ValidationException(result); } return(Model.ProvideValueExact <T>(def)); }
public string GetSettingStringValue(SettingsTitles key) { var valueStr = _settingsService.GetSetting(key); if (string.IsNullOrEmpty(valueStr)) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.Settings_Missing), Parameters = new object[] { key } }; throw new ValidationException(result); } return(valueStr); }
public RemotePropertyDefinition GetDefinition(string alias, bool addError = true) { var def = Model.Definitions.FirstOrDefault(x => x.Alias == alias); if (def == null && addError) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.MissingParam), Parameters = new object[] { alias } }; Result.AddErrorMessage( ToString(result)); } return(def); }
public void CheckArchivedRelatedEntity(ArticleService articleService, IEnumerable <string> relIdsList, int productId, string idFieldName, int contentId) { var ids = relIdsList.Where(n => !string.IsNullOrEmpty(n)).Select(int.Parse).Distinct().ToArray(); var articles = articleService.List(contentId, ids); var relIds = articles.Where(w => w.Archived).Select(s => s.Id).ToList(); if (relIds.Any()) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.RelatedEntityIsArchived), Parameters = new object[] { string.Join(",", relIds.Distinct()) } }; Result.AddModelError(GetPropertyName(idFieldName), ToString(result)); } }
public void CheckRelationProductsDuplicate(ArticleService articleService, string idFieldName, int contentProductsId, int[] relationsIds) { var servicesFieldName = GetSettingStringValue(SettingsTitles.SERVICE_FIELD_NAME); var relatedProductsIds = articleService.List(contentProductsId, relationsIds, true).Select(x => x.FieldValues.Single(a => a.Field.Name == servicesFieldName)) .Select(s => int.Parse(s.Value)).ToArray(); var duplicateServices = relatedProductsIds.Where(relId => relatedProductsIds.Count(r => r == relId) > 1).Distinct().ToArray(); if (duplicateServices.Any()) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.DuplicateRelationsProducts), Parameters = new object[] { string.Join(",", duplicateServices) } }; Result.AddModelError(GetPropertyName(idFieldName), ToString(result)); } }
public RemoteValidationResult Validate(RemoteValidationContext context, RemoteValidationResult result) { var filterDefinition = context.Definitions.FirstOrDefault(x => x.Alias == FieldFilter); if (filterDefinition == null) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.MissingParam), Parameters = new object[] { FieldFilter } }; result.AddErrorMessage(ValidationHelper.ToString(context, message)); } else { var filter = context.ProvideValueExact <string>(filterDefinition); if (string.IsNullOrEmpty(filter)) { return(result); } var normalizedFilter = DPathProcessor.NormalizeExpression(filter); if (!DPathProcessor.IsExpressionValid(normalizedFilter)) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.InvalidFilter), Parameters = new object[] { normalizedFilter } }; result.AddModelError(filterDefinition.PropertyName, ValidationHelper.ToString(context, message)); } } return(result); }
public void IsProductsRegionsWithModifierIntersectionsExist(ArticleService articleService, int productId, int[] regionsIds, int[] productsIds, string regionsName, string modifiersName, int dataOptionId) { int contentId = GetSettingValue(SettingsTitles.PRODUCTS_CONTENT_ID); var productsList = articleService.List(contentId, productsIds, true).Where(w => !w.Archived).ToArray(); Lookup <int, int[]> productToRegions = (Lookup <int, int[]>)productsList .ToLookup(x => x.Id, x => x.FieldValues.Single(a => a.Field.Name == regionsName).RelatedItems.ToArray()); Lookup <int, int[]> modifiersToProducts = (Lookup <int, int[]>)productsList .ToLookup(x => x.Id, x => x.FieldValues.Single(a => a.Field.Name == modifiersName).RelatedItems.ToArray()); var resultIds = new List <int>(); foreach (var item in productToRegions) { if (item.Key != productId) { if (!modifiersToProducts[item.Key].Any() || !modifiersToProducts[item.Key].Contains(new[] { dataOptionId })) { if (regionsIds.Intersect(item.SelectMany(s => s)).Any()) { resultIds.Add(item.Key); } } } } if (resultIds.Any()) { var message = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = nameof(RemoteValidationMessages.ProductsRepeatingRegions), Parameters = new object[] { String.Join(", ", resultIds) } }; Result.AddModelError(GetPropertyName(regionsName), ToString(message)); } }
public void CheckTariffAreaDuplicateExist(IEnumerable <Article> parameters, string parametersFieldName, bool isMatrix = false) { var resultIds = new List <int>(); var names = new HashSet <string>(GetListOfParametersNames()); var tariffDirections = parameters.ToDictionary( k => k.Id, s => string.Join(",", GetParameterTariffDirectionIds(s, names)) ); var checkedDirections = new Dictionary <string, int>(); foreach (var tariffDirection in tariffDirections) { if (!checkedDirections.ContainsKey(tariffDirection.Value)) { checkedDirections.Add(tariffDirection.Value, tariffDirection.Key); } else { resultIds.Add(tariffDirection.Key); resultIds.Add(checkedDirections[tariffDirection.Value]); } } if (resultIds.Any()) { var result = new ActionTaskResultMessage() { ResourceClass = ResourceClass, ResourceName = isMatrix ? nameof(RemoteValidationMessages.DuplicateTariffsAreasMatrix) : nameof(RemoteValidationMessages.DuplicateTariffsAreas), Parameters = new object[] { string.Join(", ", resultIds.Distinct()) } }; Result.AddModelError(GetPropertyName(parametersFieldName), ToString(result)); } }
public ValidationException(ActionTaskResultMessage message, Exception innerException) : base(message.ResourceName, innerException) { ResultMessage = message; }
public ValidationException(ActionTaskResultMessage message) : base(message.ResourceName) { ResultMessage = message; }
public RemoteValidationResult Validate(RemoteValidationContext model, RemoteValidationResult result) { var helper = new ValidationHelper(model, result, _provider, _service); int productTypesContentId = helper.GetSettingValue(SettingsTitles.PRODUCT_TYPES_CONTENT_ID); var marketingContentId = helper.GetSettingValue(SettingsTitles.MARKETING_PRODUCT_CONTENT_ID); var parametersContentId = helper.GetSettingValue(SettingsTitles.PRODUCTS_PARAMETERS_CONTENT_ID); var regionsContentId = helper.GetSettingValue(SettingsTitles.REGIONS_CONTENT_ID); var contentId = model.ContentId; int productId = helper.GetValue <int>(Constants.FieldId); using (new QPConnectionScope(helper.Customer.ConnectionString, (DatabaseType)helper.Customer.DatabaseType)) { var articleService = new ArticleService(helper.Customer.ConnectionString, 1); var product = productId > 0 ? articleService.Read(productId) : articleService.New(contentId); var markProductName = helper.GetRelatedFieldName(product, marketingContentId); var markProductId = helper.GetValue <int>(markProductName); var markProduct = articleService.Read(markProductId); var productsName = helper.GetRelatedFieldName(markProduct, contentId); var productTypeName = helper.GetClassifierFieldName(product); int typeId = helper.GetValue <int>(productTypeName); var regionsName = helper.GetRelatedFieldName(product, regionsContentId); var parametersName = helper.GetRelatedFieldName(product, parametersContentId); int[] regionsIds = helper.GetValue <ListOfInt>(regionsName).ToArray(); int[] parametersIds = helper.GetValue <ListOfInt>(parametersName)?.ToArray(); helper.CheckSiteId(productTypesContentId); //Проверка того, что продукт не имеет общих регионов с другими региональными продуктами этого МП var productsIds = markProduct .FieldValues.Where(a => a.Field.Name == productsName) .SelectMany(a => a.RelatedItems) .ToArray(); helper.IsProductsRegionsWithModifierIntersectionsExist(articleService, productId, regionsIds, productsIds, regionsName, Constants.FieldProductModifiers, 0); if (productId > 0) { //Проверка того, что тарифное направление встречается только один раз в продукте var contentProductsParametersId = helper.GetSettingValue(SettingsTitles.PRODUCTS_PARAMETERS_CONTENT_ID); if (parametersIds != null && parametersIds.Any()) { var parameters = helper.GetParameters(articleService, contentProductsParametersId, parametersIds, "c.BaseParameter is not null"); helper.CheckTariffAreaDuplicateExist(parameters, parametersName); } int contentServiceOnTariffId = 0; string tariffRelationFieldName = null; bool hasServicesOnTariff = true; try { contentServiceOnTariffId = helper.GetSettingValue(SettingsTitles.SERVICES_ON_TARIFF_CONTENT_ID); tariffRelationFieldName = helper.GetSettingStringValue(SettingsTitles.TARIFF_RELATION_FIELD_NAME); } catch (ValidationException) { hasServicesOnTariff = false; } if (hasServicesOnTariff) { //Получение id поля Tariffs var fieldService = new FieldService(helper.Customer.ConnectionString, 1); var fieldId = fieldService.List(contentServiceOnTariffId) .Where(w => w.Name.Equals(tariffRelationFieldName)).Select(s => s.Id).FirstOrDefault(); //Получение Id услуг из контента "Услуги на тарифах" var relationsIds = articleService.GetRelatedItems(fieldId, productId, true)? .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .ToArray(); if (relationsIds != null && relationsIds.Any()) { //Проверка того, что тарифное направление встречается только один раз в связи продуктов helper.CheckRelationServicesProductsTariff(articleService, contentServiceOnTariffId, tariffRelationFieldName, relationsIds, parametersName); //Проверка того, что связь между продуктами встречается единожды helper.CheckRelationProductsDuplicate(articleService, Constants.FieldId, contentServiceOnTariffId, relationsIds); } var relatedIds = new List <string>(); //Проверка того, что сущность с другой стороны связи не в архиве var productRelationsContentId = helper.GetSettingValue(SettingsTitles.PRODUCT_RELATIONS_CONTENT_ID); var contentService = new ContentService(helper.Customer.ConnectionString, 1); //Получение связанных контентов var contents = contentService.Read(productRelationsContentId) .AggregatedContents .Where(w => w.Fields .Count(a => a.ExactType == FieldExactTypes.O2MRelation && a.RelateToContentId == product.ContentId) >= 2).ToArray(); foreach (var con in contents) { //Получение полей, по которым может быть связь var productField = con.Fields .Where(w => w.ExactType == FieldExactTypes.O2MRelation && w.RelateToContentId == product.ContentId ).ToArray(); foreach (var field in productField) { //Получение ids связанных статей var relatedArticlesId = articleService.GetRelatedItems(field.Id, productId, true)? .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .ToArray(); if (relatedArticlesId != null && relatedArticlesId.Any()) { var relatedArticles = articleService.List(con.Id, relatedArticlesId, true) .Where(w => !w.Archived).Select(s => s).ToList(); var relField = productField.Where(f => f.Name != field.Name).Select(s => s).First(); var rel = relatedArticles.Select(s => s.FieldValues.First(f => f.Field.Name == relField.Name).Value).ToArray(); if (rel.Any()) { relatedIds.AddRange(rel); } } } } helper.CheckArchivedRelatedEntity(articleService, relatedIds, productId, Constants.FieldId, helper.GetSettingValue(SettingsTitles.PRODUCTS_CONTENT_ID)); } } string markProductType = articleService.Read(markProductId) .FieldValues.FirstOrDefault(a => a.Field.Name == productTypeName)? .Value; //Проверка, что тип маркетингового продукта и тип продукта -- сопоставимы if (!articleService.List(productTypesContentId, null, true).Any(x => x.FieldValues.FirstOrDefault(a => a.Field.Name == Constants.FieldProductContent)?.Value == typeId.ToString() && x.FieldValues.FirstOrDefault(a => a.Field.Name == Constants.FieldMarkProductContent)?.Value == markProductType)) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.SameTypeProductMarketingProduct) }; result.AddModelError( helper.GetPropertyName(markProductName), helper.ToString(message) ); } } return(result); }
public override ActionTaskResult Process(ActionContext context) { int bundleSize = GetBundleSize(); int maxDegreeOfParallelism = GetMaxDegreeOfParallelism(); string[] channels = context.Parameters.GetChannels(); bool localize = context.Parameters.GetLocalize(); int marketingProductContentId = int.Parse(_settingsService.GetSetting(SettingsTitles.MARKETING_PRODUCT_CONTENT_ID)); string productsFieldName = _settingsService.GetSetting(SettingsTitles.MARKETING_PRODUCT_PRODUCTS_FIELD_NAME); Dictionary <int, int[]> articleIdsToCheckRelationsByContentId; int[] productIds; if (context.ContentItemIds == null || context.ContentItemIds.Length == 0) { productIds = DoWithLogging( () => Helpers.GetAllProductIds(int.Parse(context.Parameters["site_id"]), context.ContentId, _provider.GetCustomer()), "Getting all products from content {contentId}", context.ContentId ); articleIdsToCheckRelationsByContentId = new Dictionary <int, int[]> { { context.ContentId, productIds } }; } else { productIds = DoWithLogging( () => Helpers.ExtractRegionalProductIdsFromMarketing(context.ContentItemIds, _articleService, marketingProductContentId, productsFieldName), "Getting regional product ids from marketing products content {contentId} using field {fieldName} and ids {ids}", marketingProductContentId, productsFieldName, context.ContentItemIds ); articleIdsToCheckRelationsByContentId = Helpers.GetContentIds(productIds, _provider.GetCustomer()); } if (productIds.Length == 0) { return(ActionTaskResult.Error(new ActionTaskResultMessage() { ResourceClass = nameof(SendProductActionStrings), ResourceName = nameof(SendProductActionStrings.NotFound), Extra = string.Join(", ", context.ContentItemIds) }, context.ContentItemIds)); } foreach (var articleIdsWithContentId in articleIdsToCheckRelationsByContentId) { var checkResult = DoWithLogging( () => _articleService.CheckRelationSecurity(articleIdsWithContentId.Key, articleIdsWithContentId.Value, false), "Checking relation security in content {contentId} for articles {ids}", articleIdsWithContentId.Key, articleIdsWithContentId.Value ); string idsstr = string.Join(", ", checkResult.Where(n => !n.Value)); if (!string.IsNullOrEmpty(idsstr)) { return(ActionTaskResult.Error(new ActionTaskResultMessage() { ResourceClass = nameof(SendProductActionStrings), ResourceName = nameof(SendProductActionStrings.NoRelationAccess), Extra = idsstr }, context.ContentItemIds)); } } const string skipPublishingKey = "skipPublishing"; bool skipPublishing = context.Parameters.ContainsKey(skipPublishingKey) && bool.Parse(context.Parameters[skipPublishingKey]); const string skipLiveKey = "skipLive"; bool skipLive = context.Parameters.ContainsKey(skipLiveKey) && bool.Parse(context.Parameters[skipLiveKey]); const string ignoredStatusKey = "IgnoredStatus"; string ignoredStatus = (context.Parameters.ContainsKey(ignoredStatusKey)) ? context.Parameters[ignoredStatusKey] : null; float currentPercent = 0; object percentLocker = new object(); var parts = productIds.Section(bundleSize).ToArray(); var filteredInStage = new ConcurrentBag <int>(); var filteredInLive = new ConcurrentBag <int>(); var failed = new ConcurrentDictionary <int, object>(); var missing = new ConcurrentBag <int>(); var excluded = new ConcurrentBag <int>(); var frozen = new ConcurrentBag <int>(); var invisibleOrArchivedIds = new ConcurrentBag <int>(); var errors = new ConcurrentBag <Exception>(); var validationErrors = new ConcurrentDictionary <int, ActionTaskResult>(); var validationErrorsSerialized = new ConcurrentDictionary <int, string>(); Parallel.ForEach(parts, new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }, () => { HttpContextUserProvider.ForcedUserId = context.UserId; return(new Local { ProductService = ObjectFactoryBase.Resolve <IProductService>(), QpNotificationService = ObjectFactoryBase.Resolve <IQPNotificationService>(), XmlProductService = ObjectFactoryBase.Resolve <IXmlProductService>() }); }, (idsToProcess, ps, tl) => { try { if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(tl); } var localInvisibleOrArchivedIds = new HashSet <int>(); Article[] prodsStage = DoWithLogging( () => tl.ProductService.GetProductsByIds(idsToProcess.ToArray()), "Getting products {ids}", idsToProcess.ToArray() ); IEnumerable <string> ignoredStatuses = ignoredStatus?.Split(',') ?? Enumerable.Empty <string>().ToArray(); var excludedStage = prodsStage.Where(n => ignoredStatuses.Contains(n.Status)).ToArray(); foreach (var item in excludedStage) { excluded.Add(item.Id); } prodsStage = prodsStage.Except(excludedStage).ToArray(); var frozenIds = new int[0]; if (!skipLive) { var idsToCheck = prodsStage.Select(p => p.Id).ToArray(); frozenIds = DoWithLogging( () => _freezeService.GetFrozenProductIds(idsToCheck), "Getting freezing state for products {ids}", idsToCheck ); } prodsStage = prodsStage.Where(p => !frozenIds.Contains(p.Id)).ToArray(); foreach (int id in frozenIds) { frozen.Add(id); } if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(tl); } //Валидация продуктов foreach (int id in prodsStage.Where(w => !w.Archived && w.Visible).Select(s => s.Id)) { var xamlValidationErrors = DoWithLogging( () => _articleService.XamlValidationById(id, true), "Validating XAML for product {id}", id ); var validationResult = ActionTaskResult.FromRulesException(xamlValidationErrors, id); if (!validationResult.IsSuccess) { validationErrors.TryAdd(id, validationResult); validationErrorsSerialized.TryAdd(id, validationResult.ToString()); } } prodsStage = prodsStage.Where(w => !validationErrors.Keys.Contains(w.Id)).ToArray(); var prodsLive = new Article[] { }; if (!skipLive) { if (!skipPublishing) { prodsLive = prodsStage; } else { prodsLive = DoWithLogging( () => tl.ProductService.GetProductsByIds(idsToProcess.ToArray(), true), "Getting separate live products {ids}", idsToProcess.ToArray() ); } } if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(tl); } lock (percentLocker) { currentPercent += (float)50 / parts.Length; } TaskContext.SetProgress((byte)currentPercent); // архивные или невидимые продукты следует удалить с витрин foreach (var product in prodsLive.Where(product => product.Archived || !product.Visible)) { localInvisibleOrArchivedIds.Add(product.Id); } if (!skipLive) { foreach (var item in idsToProcess.Except(prodsLive.Select(y => y.Id))) { missing.Add(item); } } //неопубликованные или расщепленные публикуем сразу int[] prodsToPublishIds = null; if (!skipPublishing) { prodsToPublishIds = prodsLive .Where(x => !x.Archived && x.Visible && ( !x.IsPublished || PublishAction.GetAllArticlesToCheck(x).Any(p => !p.IsPublished) || _freezeService.GetFreezeState(x.Id) == FreezeState.Unfrosen ) ) .Select(x => x.Id) .ToArray(); if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(tl); } // удалим требующие публикации или удаления продукты prodsLive = prodsLive .Where(p => !prodsToPublishIds.Contains(p.Id) && !localInvisibleOrArchivedIds.Contains(p.Id)) .ToArray(); } if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(tl); } lock (percentLocker) { currentPercent += (float)30 / parts.Length; } TaskContext.SetProgress((byte)currentPercent); foreach (var id in localInvisibleOrArchivedIds) { invisibleOrArchivedIds.Add(id); } int sectionSize = Math.Min(bundleSize, 5); var tasks = ArticleFilter.LiveFilter.Filter(prodsLive) .Section(sectionSize) .Select(z => tl.QpNotificationService .SendProductsAsync(z.ToArray(), false, context.UserName, context.UserId, localize, false, channels) .ContinueWith(y => UpdateFilteredIds(filteredInLive, y.IsFaulted ? null : y.Result, z, y.Exception, errors, failed))) .Concat(ArticleFilter.DefaultFilter.Filter(prodsStage) .Section(sectionSize) .Select(z => tl.QpNotificationService.SendProductsAsync(z.ToArray(), true, context.UserName, context.UserId, localize, false, channels) .ContinueWith(y => UpdateFilteredIds(filteredInStage, y.IsFaulted ? null : y.Result, z, y.Exception, errors, failed)))) .ToArray(); if (tasks.Length > 0) { float percentsPerTask = (float)10 / parts.Length / tasks.Length; tasks = tasks .Select(x => x.ContinueWith(y => { lock (percentLocker) { currentPercent += percentsPerTask; } TaskContext.SetProgress((byte)currentPercent); })) .ToArray(); DoWithLogging(() => Task.WaitAll(tasks), "Sending notifications for live ({liveIds}) and stage ({stageIds}) products", ArticleFilter.LiveFilter.Filter(prodsLive).Select(n => n.Id).ToArray(), ArticleFilter.DefaultFilter.Filter(prodsStage).Select(n => n.Id).ToArray() ); } else { lock (percentLocker) { currentPercent += (float)10 / parts.Length; } TaskContext.SetProgress((byte)currentPercent); } if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(tl); } // эти продукты имеют неопубликованные или расщепленные статьи if (!skipPublishing && prodsToPublishIds.Length > 0) { var publishAction = ObjectFactoryBase.Resolve <PublishAction>(); var publishActionContext = new ActionContext { ContentItemIds = prodsToPublishIds, Parameters = new Dictionary <string, string>() { { ignoredStatusKey, ignoredStatus } }, UserId = context.UserId, UserName = context.UserName }; try { DoWithLogging( () => publishAction.Process(publishActionContext), "Calling PublishAction for products {ids}", prodsToPublishIds ); } catch (ActionException ex) { var ids = ex.InnerExceptions.OfType <ProductException>().Select(x => x.ProductId); Logger.Error() .Exception(ex) .Message("Exception has been thrown while publishing products {ids}", prodsToPublishIds) .Write(); foreach (var pID in ids) { failed.TryAdd(pID, null); } } catch (Exception ex) { Logger.Error() .Exception(ex) .Message("Exception has been thrown while publishing products {ids}", prodsToPublishIds) .Write(); } } lock (percentLocker) { currentPercent += (float)10 / parts.Length; } TaskContext.SetProgress((byte)currentPercent); return(tl); } catch (Exception ex) { Logger.Error().Message("SendProductAction exception").Exception(ex).Write(); foreach (var item in idsToProcess) { failed.TryAdd(item, null); } errors.Add(ex); } HttpContextUserProvider.ForcedUserId = 0; return(tl); }, tt => { }); if (TaskContext.IsCancellationRequested) { TaskContext.IsCancelled = true; return(ActionTaskResult.Error(new ActionTaskResultMessage() { ResourceClass = nameof(SendProductActionStrings), ResourceName = nameof(SendProductActionStrings.Cancelled) }, context.ContentItemIds)); } var productsToRemove = new int[0]; var productsToRemoveCheck = missing .Concat(invisibleOrArchivedIds) .Except(excluded) .Except(frozen) .Except(validationErrors.Keys) .ToArray(); if (productsToRemoveCheck.Length > 0) { // проверяем, какие из проблемных продуктов присутствуют на витрине var cmService = ObjectFactoryBase.Resolve <IList <IConsumerMonitoringService> >(); productsToRemove = DoWithLogging( () => cmService.SelectMany(s => s.FindExistingProducts(productsToRemoveCheck)).Distinct().ToArray(), "Checking whether products {ids} are missing on fronts", productsToRemoveCheck ); if (productsToRemove.Length > 0) { // эти продукты отсутствуют в DPC или не видны, но остались на витрине // их надо удалить с витрин var service = ObjectFactoryBase.Resolve <IQPNotificationService>(); var productService = ObjectFactoryBase.Resolve <IProductService>(); DoWithLogging( () => Task.WhenAll(productsToRemove.Section(20).Select( s => service.DeleteProductsAsync( productService.GetSimpleProductsByIds(s.ToArray()), context.UserName, context.UserId, false) ) ).Wait(), "Removing missing products from fronts {ids}", productsToRemove ); } } DoWithLogging( () => _validationService.UpdateValidationInfo(productIds, validationErrorsSerialized), "Updating validation info for products {ids}", productIds ); int[] notFound = missing.Except(productsToRemove).Except(excluded).Except(frozen).Except(validationErrors.Keys).ToArray(); var notSucceeded = failed.Keys.Concat(notFound).Concat(excluded).Concat(frozen) .Concat(validationErrors.Keys).ToArray(); var result = new ActionTaskResult() { FailedIds = notSucceeded }; var msg = new ActionTaskResultMessage() { ResourceClass = nameof(SendProductActionStrings) }; if (notSucceeded.Any()) { msg.ResourceName = nameof(SendProductActionStrings.PartiallySucceededResult); msg.Extra = string.Join(", ", notSucceeded); msg.Parameters = new object[] { productIds.Length - notSucceeded.Length, productIds.Length }; } else { msg.ResourceName = nameof(SendProductActionStrings.SucceededResult); msg.Parameters = new object[] { productIds.Length }; } result.Messages.Add(msg); if (errors.Any()) { result.Messages.Add(new ActionTaskResultMessage() { ResourceClass = nameof(SendProductActionStrings), ResourceName = nameof(SendProductActionStrings.Errors), Extra = string.Join(", ", errors.Select(x => x.Message).Distinct()) }); } AddMessages(result, nameof(SendProductActionStrings.ExcludedByStatus), excluded.ToArray()); AddMessages(result, nameof(SendProductActionStrings.ExcludedWithFreezing), frozen.ToArray()); AddMessages(result, nameof(SendProductActionStrings.NotFoundInDpc), notFound.ToArray()); AddMessages(result, nameof(SendProductActionStrings.RemovedFromFronts), productsToRemove.ToArray()); AddMessages(result, nameof(SendProductActionStrings.NotPassedByStageFiltration), filteredInStage.ToArray()); AddMessages(result, nameof(SendProductActionStrings.NotPassedByLiveFiltration), filteredInLive.ToArray()); if (validationErrors.Any()) { result.Messages.AddRange(validationErrors.SelectMany(v => v.Value.Messages)); } TaskContext.Result = result; return(result); }
public RemoteValidationResult Validate(RemoteValidationContext context, RemoteValidationResult result) { var xmlDefinition = context.Definitions.FirstOrDefault(x => x.Alias == FieldXmlDefinition); if (xmlDefinition == null) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.FieldNotFound), Parameters = new object[] { FieldXmlDefinition } }; result.Messages.Add(ValidationHelper.ToString(context, message)); } var xaml = context.ProvideValueExact <string>(xmlDefinition); if (!string.IsNullOrWhiteSpace(xaml)) { Content definition; try { definition = (Content)XamlConfigurationParser.CreateFrom(xaml); } catch (Exception ex) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.NotValidXamlDefinition), Parameters = new object[] { ex.Message } }; result.Messages.Add(ValidationHelper.ToString(context, message)); return(result); } var jsonDefinition = context.Definitions.FirstOrDefault(x => x.Alias == FieldJsonDefinition); if (jsonDefinition != null) { using (var stream = new MemoryStream()) { using (var reader = new StreamReader(stream)) { try { _formatter.Write(stream, definition); stream.Position = 0; context.SetValue(result, jsonDefinition, reader.ReadToEnd()); } catch (Exception ex) { var message = new ActionTaskResultMessage() { ResourceClass = ValidationHelper.ResourceClass, ResourceName = nameof(RemoteValidationMessages.JsonDefinitionError), Parameters = new object[] { ex.Message } }; result.Messages.Add(ValidationHelper.ToString(context, message)); return(result); } } } } } return(result); }
public static string ToString(RemoteValidationContext model, ActionTaskResultMessage atrm) { return(model.LocalizeMessages ? atrm.ToString(new CultureInfo(model.CurrentUICulture)) : JsonConvert.SerializeObject(atrm)); }
public string ToString(ActionTaskResultMessage atrm) { return(ToString(Model, atrm)); }