Ejemplo n.º 1
0
        public virtual ProductItemViewModel Build(ProductModel productModel, bool inProductListPage = true)
        {
            var currency          = Cart.Currency;
            var websiteModel      = _requestModelAccessor.RequestModel.WebsiteModel;
            var productPriceModel = _productPriceModelBuilder.Build(productModel.SelectedVariant, currency, _requestModelAccessor.RequestModel.ChannelModel.Channel);

            return(new ProductItemViewModel
            {
                Id = productModel.SelectedVariant.Id,
                Price = productPriceModel,
                StockStatusDescription = _stockService.GetStockStatusDescription(productModel.SelectedVariant),
                Currency = currency,
                IsInStock = _stockService.HasStock(productModel.SelectedVariant),
                Images = productModel.GetValue <IList <Guid> >(SystemFieldDefinitionConstants.Images).MapTo <IList <ImageModel> >(),
                Color = _fieldDefinitionService.Get <ProductArea>("Color").GetTranslation(productModel.GetValue <string>("Color")),
                Size = _fieldDefinitionService.Get <ProductArea>("Size").GetTranslation(productModel.GetValue <string>("Size")),
                Brand = _fieldDefinitionService.Get <ProductArea>("Brand").GetTranslation(productModel.GetValue <string>("Brand")),
                Description = productModel.GetValue <string>(SystemFieldDefinitionConstants.Description),
                Name = productModel.GetValue <string>(SystemFieldDefinitionConstants.Name),
                Url = productModel.GetUrl(websiteModel.SystemId, channelSystemId: _requestModelAccessor.RequestModel.ChannelModel.SystemId),
                QuantityFieldId = Guid.NewGuid().ToString(),
                ShowBuyButton = websiteModel.GetValue <bool>(AcceleratorWebsiteFieldNameConstants.ShowBuyButton),
                ShowQuantityField = inProductListPage ? websiteModel.GetValue <bool>(AcceleratorWebsiteFieldNameConstants.ShowQuantityFieldProductList)
                                                      : websiteModel.GetValue <bool>(AcceleratorWebsiteFieldNameConstants.ShowQuantityFieldProductPage),
                UseVariantUrl = productModel.UseVariantUrl
            });
        }
        public virtual ProductItemViewModel Build(ProductModel productModel, bool inProductListPage = true)
        {
            var cartContext = _cartContextAccessor.CartContext;
            var currency    = (cartContext == null) ? _currencyService.Get(_requestModelAccessor.RequestModel.CountryModel.Country.CurrencySystemId)
                                                 : _currencyService.Get(cartContext.CurrencyCode);
            var country = (cartContext == null) ? _requestModelAccessor.RequestModel.CountryModel.Country
                                                : _countryService.Get(cartContext.CountryCode);
            var websiteModel      = _requestModelAccessor.RequestModel.WebsiteModel;
            var productPriceModel = _productPriceModelBuilder.Build(productModel.SelectedVariant, currency, _requestModelAccessor.RequestModel.ChannelModel.Channel, country);
            var images            = productModel.SelectedVariant.Fields.GetValue <IList <Guid> >(SystemFieldDefinitionConstants.Images).MapTo <IList <ImageModel> >();

            return(new ProductItemViewModel
            {
                SystemId = productModel.SelectedVariant.SystemId,
                Id = productModel.SelectedVariant.Id,
                Price = productPriceModel,
                FormattedPrice = productPriceModel.Price.FormatPrice(true),
                StockStatusDescription = _stockService.GetStockStatusDescription(productModel.SelectedVariant),
                Currency = currency,
                IsInStock = _stockService.HasStock(productModel.SelectedVariant),
                Images = images,
                ImageUrls = images.Select(image => image.GetUrlToImage(new System.Drawing.Size(220, 300), new System.Drawing.Size(280, 400)).Url).ToArray(),
                Color = _fieldDefinitionService.Get <ProductArea>("Color").GetTranslation(productModel.GetValue <string>("Color")),
                Size = _fieldDefinitionService.Get <ProductArea>("Size").GetTranslation(productModel.GetValue <string>("Size")),
                Brand = _fieldDefinitionService.Get <ProductArea>("Brand").GetTranslation(productModel.GetValue <string>("Brand")),
                Description = productModel.GetValue <string>(SystemFieldDefinitionConstants.Description),
                Name = productModel.GetValue <string>(SystemFieldDefinitionConstants.Name),
                Url = productModel.GetUrl(websiteModel.SystemId, channelSystemId: _requestModelAccessor.RequestModel.ChannelModel.SystemId),
                QuantityFieldId = Guid.NewGuid().ToString(),
                ShowBuyButton = websiteModel.GetValue <bool>(AcceleratorWebsiteFieldNameConstants.ShowBuyButton),
                ShowQuantityField = inProductListPage ? websiteModel.GetValue <bool>(AcceleratorWebsiteFieldNameConstants.ShowQuantityFieldProductList)
                                                      : websiteModel.GetValue <bool>(AcceleratorWebsiteFieldNameConstants.ShowQuantityFieldProductPage),
                UseVariantUrl = productModel.UseVariantUrl
            });
        }
        public IEnumerable <ProductFieldViewModel> Build([NotNull] ProductModel productModel, [NotNull] string fieldGroup, [NotNull] CultureInfo cultureInfo, bool includeBaseProductFields = true, bool includeVariantFields = true, bool includeHiddenFields = false, bool includeEmptyFields = false)
        {
            var result = new List <ProductFieldViewModel>();

            if (includeBaseProductFields)
            {
                var baseProductFields = productModel.FieldTemplate.ProductFieldGroups?.FirstOrDefault(x => fieldGroup.Equals(x.Id, StringComparison.OrdinalIgnoreCase))?.Fields;
                if (baseProductFields != null)
                {
                    foreach (var field in baseProductFields)
                    {
                        var fieldDefinition = _fieldDefinitionService.Get <ProductArea>(field);
                        if (fieldDefinition == null || fieldDefinition.Hidden && !includeHiddenFields)
                        {
                            continue;
                        }

                        var culture = fieldDefinition.MultiCulture ? cultureInfo.Name : "*";
                        if (productModel.BaseProduct.Fields.TryGetValue(field, culture, out var value))
                        {
                            result.Add(CreateModel(fieldDefinition, cultureInfo, value));
                        }
                        else if (includeEmptyFields)
                        {
                            result.Add(CreateModel(fieldDefinition, cultureInfo, culture));
                        }
                    }
                }
            }

            if (includeVariantFields)
            {
                var variantFields = productModel.FieldTemplate.VariantFieldGroups?.FirstOrDefault(x => fieldGroup.Equals(x.Id, StringComparison.OrdinalIgnoreCase))?.Fields;
                if (variantFields != null)
                {
                    foreach (var field in variantFields)
                    {
                        var fieldDefinition = _fieldDefinitionService.Get <ProductArea>(field);
                        if (fieldDefinition == null || fieldDefinition.Hidden && !includeHiddenFields)
                        {
                            continue;
                        }

                        var culture = fieldDefinition.MultiCulture ? cultureInfo.Name : "*";
                        if (productModel.SelectedVariant.Fields.TryGetValue(field, culture, out var value))
                        {
                            result.Add(CreateModel(fieldDefinition, cultureInfo, value));
                        }
                        else if (includeEmptyFields)
                        {
                            result.Add(CreateModel(fieldDefinition, cultureInfo, culture));
                        }
                    }
                }
            }

            return(result.Where(x => x != null));
        }
Ejemplo n.º 4
0
        private FieldDefinition GetTextOptionField(string area, string textOptionId)
        {
            switch (area)
            {
            default:
                return(_fieldDefinitionService.Get <ProductArea>(textOptionId));

            case nameof(CustomerArea):
                return(_fieldDefinitionService.Get <CustomerArea>(textOptionId));

            case nameof(SalesArea):
                return(_fieldDefinitionService.Get <SalesArea>(textOptionId));

            case nameof(WebsiteArea):
                return(_fieldDefinitionService.Get <WebsiteArea>(textOptionId));

            case nameof(GlobalizationArea):
                return(_fieldDefinitionService.Get <GlobalizationArea>(textOptionId));

            case nameof(MediaArea):
                return(_fieldDefinitionService.Get <MediaArea>(textOptionId));

            case nameof(BlockArea):
                return(_fieldDefinitionService.Get <BlockArea>(textOptionId));
            }
        }
Ejemplo n.º 5
0
        public void AddProperties <TArea>(StructureInfo structureInfo, IFieldFramework oldFieldContainer, IFieldFramework fieldContainer, bool changeUrl = true, IList <string> excludeFields = null)
            where TArea : IArea
        {
            if (oldFieldContainer[SystemFieldDefinitionConstants.Images] is List <Guid> images)
            {
                var newImages = images.Select(structureInfo.Id).ToList();

                fieldContainer[SystemFieldDefinitionConstants.Images] = newImages;
            }

            var fields = Get <TArea>((IFieldContainerAccessor)oldFieldContainer);

            foreach (var field in fields)
            {
                if (excludeFields?.Contains(field.Key) == true)
                {
                    continue;
                }

                var fieldDefinition = _fieldDefinitionService.Get <TArea>(field.Key);
                if (fieldDefinition == null)
                {
                    continue;
                }

                if (fieldDefinition.MultiCulture)
                {
                    foreach (var cultureValue in field.Value)
                    {
                        var value = CorrectValue <TArea>(structureInfo, field.Key, cultureValue.Value, fieldDefinition, changeUrl);
                        fieldContainer[fieldDefinition.Id, cultureValue.Key] =
                            ConvertFromEditValue(
                                new EditFieldTypeConverterArgs(fieldDefinition, new CultureInfo(cultureValue.Key)),
                                value);
                    }
                }
                else
                {
                    if (field.Value.TryGetValue("*", out var value))
                    {
                        var newValue = CorrectValue <TArea>(structureInfo, field.Key, value, fieldDefinition, changeUrl);
                        fieldContainer[fieldDefinition.Id] =
                            ConvertFromEditValue(
                                new EditFieldTypeConverterArgs(fieldDefinition, CultureInfo.CurrentCulture), newValue);
                    }
                    else
                    {
                        fieldContainer.TryRemoveValue(fieldDefinition.Id, out _);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        private void InitFields(IEnumerable <FieldDefinition> fields)
        {
            foreach (var item in fields)
            {
                if (IsAlreadyExecuted <FieldDefinition>(item.Id, item.AreaType.Name))
                {
                    continue;
                }

                var currentField = _fieldDefinitionService.Get(item.AreaType, item.Id);
                if (currentField == null)
                {
                    _fieldFrameworkSetupLocalizationService.Localize(item);
                    _fieldDefinitionService.Create(item);
                    SetAlreadyExecuted <FieldDefinition>(item.Id, item.AreaType.Name);
                    continue;
                }

                if (item.FieldType != currentField.FieldType)
                {
                    _logger.LogError("Accelerator \"{Id}\" field with \"{FieldType}\" type can't be created. The system already has the \"{CurrentId}\" field with \"{CurrentFieldType}\" type. Accelerator deployment would fail.", item.Id, item.FieldType, currentField.Id, currentField.FieldType);
                    _settingService.Set <bool?>("Accelerator.DefinitionsError", true);
                    continue;
                }
                if (item.MultiCulture != currentField.MultiCulture)
                {
                    _logger.LogError("Accelerator \"{Id}\" field with \"MultiCulture\" setting and \"{MultiCulture}\" value can't be created. The system already has the \"{CurrentId}\" field with \"MultiCulture\" setting and \"{CurrentMultiCulture}\" value. Accelerator deployment would fail.", item.Id, item.MultiCulture, currentField.Id, currentField.MultiCulture);
                    _settingService.Set <bool?>("Accelerator.DefinitionsError", true);
                    continue;
                }

                SetAlreadyExecuted <FieldDefinition>(item.Id, item.AreaType.Name);
            }
        }
        private void InitFields()
        {
            var items = new[]
            {
                new FieldDefinition(SmartImageService.FieldName, SystemFieldTypeConstants.Text)
                {
                    CanBeGridColumn = true,
                    CanBeGridFilter = true,
                    Localizations   =
                    {
                        ["sv-SE"] = { Name = "Smart Image Tags" },
                        ["en-US"] = { Name = "Smart Image Tags" },
                    }
                },
            };

            foreach (var item in items)
            {
                var currentField = _fieldDefinitionService.Get(item.Id);
                if (currentField != null)
                {
                    continue;
                }
                _fieldDefinitionService.Create(item);
            }
        }
        public JToken ConvertToEditValue(EditFieldTypeConverterArgs args, object item)
        {
            var items = item as IList <string> ?? new List <string>();

            var removedIds = new List <string>();
            var ignoredIds = new List <string> {
                "#Price", "#News"
            };
            var productFilteringFields = _settingsService.Get <IList <string> >("Accelerator.ProductFiltering") ?? new List <string>();

            foreach (var fieldId in items.Where(x => !ignoredIds.Contains(x)))
            {
                if (!productFilteringFields.Contains(fieldId))
                {
                    removedIds.Add(fieldId);
                }
                else
                {
                    var field = _fieldDefinitionService.Get <ProductArea>(fieldId);
                    if (field == null || field.Hidden || !field.CanBeGridFilter)
                    {
                        removedIds.Add(fieldId);
                    }
                }
            }

            return(new JArray(items.Where(x => !removedIds.Contains(x))));
        }
Ejemplo n.º 9
0
        private OrderDetailsViewModel.OrderRowItem BuildOrderRow(OrderRow orderRow, Currency currency)
        {
            var productModel           = _productModelBuilder.BuildFromVariant(_variantService.Get(orderRow.ArticleNumber));
            var shoppingCartIncludeVat = _requestModelAccessor.RequestModel.Cart.IncludeVAT;

            var unitOfMeasurement             = _unitOfMeasurementService.Get(orderRow.SKUCode);
            var unitOfMeasurementFormatString = $"0.{new string('0', unitOfMeasurement?.DecimalDigits ?? 0)}";

            var totalPrice = shoppingCartIncludeVat ? orderRow.TotalPriceWithVat : orderRow.TotalPrice;

            var campaign = orderRow.Campaign;
            var model    = new OrderDetailsViewModel.OrderRowItem
            {
                DeliveryId     = orderRow.DeliveryID,
                Brand          = productModel == null ? null : _fieldDefinitionService.Get <ProductArea>("Brand")?.GetTranslation(productModel.GetValue <string>("Brand")),
                Name           = productModel == null ? orderRow.ArticleNumber : productModel.GetValue <string>(SystemFieldDefinitionConstants.Name),
                QuantityString = $"{orderRow.Quantity.ToString(unitOfMeasurementFormatString, CultureInfo.CurrentUICulture.NumberFormat)} {unitOfMeasurement?.Localizations.CurrentUICulture.Name ?? orderRow.SKUCode}",
                PriceInfo      = new ProductPriceModel
                {
                    CampaignPrice = campaign == null ? null : SetFormattedPrice(new ProductPriceModel.CampaignPriceItem(0, orderRow.UnitCampaignPrice, orderRow.VATPercentage, orderRow.UnitCampaignPrice * (1 + orderRow.VATPercentage), campaign.ID), shoppingCartIncludeVat, currency),
                    Price         = SetFormattedPrice(new ProductPriceModel.PriceItem(0, orderRow.UnitListPrice, orderRow.VATPercentage, orderRow.UnitListPrice * (1 + orderRow.VATPercentage)), shoppingCartIncludeVat, currency)
                },
                TotalPrice = currency.Format(totalPrice, true, CultureInfo.CurrentUICulture),
                Link       = productModel?.SelectedVariant.MapTo <LinkModel>()
            };

            return(model);
        }
Ejemplo n.º 10
0
        private FieldDefinition CreateField(FieldDefinition fieldDefinition)
        {
            var currentField = _fieldDefinitionService.Get<ProductArea>(fieldDefinition.Id);
            if (currentField != null)
            {
                // Update options of the field even if the field already exists
                if (fieldDefinition.Option != null)
                {
                    currentField = currentField.MakeWritableClone();
                    currentField.Option = fieldDefinition.Option;
                    _fieldDefinitionService.Update(currentField);
                }

                return currentField;
            }

            _fieldDefinitionService.Create(fieldDefinition);
            return _fieldDefinitionService.Get<ProductArea>(fieldDefinition.Id);
        }
            private ProductModel CreateProductModel(SearchQuery searchQuery, BaseProduct baseProduct, ICollection <Variant> variants, Guid channelSystemId)
            {
                IEnumerable <Variant> currentVariants = variants;

                if (searchQuery.CategorySystemId != null && searchQuery.CategorySystemId != Guid.Empty)
                {
                    var product      = baseProduct ?? _baseProductService.Get(currentVariants.First().BaseProductSystemId);
                    var categoryLink = _categoryService.Get(searchQuery.CategorySystemId.Value)?.ProductLinks.FirstOrDefault(x => x.BaseProductSystemId == product.SystemId);
                    if (categoryLink != null)
                    {
                        currentVariants = currentVariants.Where(x => categoryLink.ActiveVariantSystemIds.Contains(x.SystemId));
                    }
                }

                currentVariants = currentVariants
                                  .Where(x => x.ChannelLinks.Any(z => z.ChannelSystemId == channelSystemId))
                                  .OrderBy(x => x.SortIndex);

                if (searchQuery.Tags.Count > 0)
                {
                    var     order        = new ConcurrentDictionary <Variant, int>();
                    Variant firstVariant = null;
                    foreach (var tag in searchQuery.Tags)
                    {
                        var fieldDefinition = _fieldDefinitionService.Get <ProductArea>(tag.Key);
                        // ReSharper disable once PossibleMultipleEnumeration
                        foreach (var variant in currentVariants)
                        {
                            if (firstVariant == null)
                            {
                                firstVariant = variant;
                            }

                            var value = GetTranslatedValue((variant.Fields[tag.Key, CultureInfo.CurrentCulture] ?? variant.Fields[tag.Key]) as string, CultureInfo.CurrentCulture, fieldDefinition);
                            if (tag.Value.Contains(value))
                            {
                                order.AddOrUpdate(variant, _ => 1, (_, c) => c + 1);
                            }
                        }
                    }

                    if (order.Count > 0)
                    {
                        currentVariants = order.OrderByDescending(x => x.Value).Select(x => x.Key);
                    }
                }

                return(baseProduct == null
                    ? _productModelBuilder.BuildFromVariant(currentVariants.First())
                    : _productModelBuilder.BuildFromBaseProduct(baseProduct, currentVariants.First()));
            }
Ejemplo n.º 12
0
 public IndexingModel Get()
 {
     return(new IndexingModel
     {
         Templates = _fieldTemplateService.GetAll().OfType <ProductFieldTemplate>().Select(x => new IndexingModel.Template
         {
             Title = x.Localizations.CurrentUICulture.Name ?? x.Id,
             TemplateId = x.Id,
             GroupingFieldId = _templateSettingService.GetTemplateGroupingField(x.Id)?.ToLowerInvariant(),
             Fields = x.VariantFieldGroups.SelectMany(z => z.Fields)
                      .Distinct()
                      .Select(z => _fieldDefinitionService.Get <ProductArea>(z))
                      .Where(z => z != null)
                      .Select(z => new IndexingModel.FieldGroup {
                 Title = z.Localizations.CurrentUICulture.Name ?? z.Id, FieldId = z.Id.ToLowerInvariant()
             })
                      .OrderBy(z => z.Title)
                      .ToList()
         })
                     .OrderBy(x => x.Title)
                     .ToList()
     });
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Updates a field value in 'fields' specified by 'fieldId' and 'file'
        /// </summary>
        /// <param name="fields">The list of fields to update</param>
        /// <param name="fieldId">The ID of the field to update</param>
        /// <param name="file">The file to set to the field value</param>
        private void SetField(FieldContainer fields, string fieldId, File file)
        {
            var def = _fieldDefinitionService.Get <ProductArea>(fieldId);

            var logger = this.Log().ForContext("FileID", file.SystemId)
                         .ForContext("FieldID", fieldId)
                         .ForContext("Filename", file.Name);

            if (def == null)
            {
                logger.Warning("Could not map media: Unable to find field with ID {FieldId}", fieldId);
                return;
            }

            var setter = _fieldSetters.FirstOrDefault(r => r.CanSet(def));

            if (setter == null)
            {
                logger.Warning("Could not map media: Unable to find field setter for type {FieldType}", def.FieldType);
                return;
            }

            setter.Set(fields, def, file);
        }
Ejemplo n.º 14
0
        public override async Task <IEnumerable <GroupFilter> > GetFilterAsync(SearchQuery searchQuery, IEnumerable <string> fieldNames)
        {
            var fieldNamesList = fieldNames as IList <string> ?? fieldNames.ToList();

            if (!_searchClientService.IsConfigured)
            {
                return(await _parent.GetFilterAsync(searchQuery, fieldNames));
            }
            else if (fieldNamesList.Count > 0 &&
                     !fieldNamesList.All(fieldName => fieldName.Equals(FilteringConstants.FilterNews, StringComparison.OrdinalIgnoreCase)))
            {
                var noFilterFieldNames = new HashSet <string>(new[]
                {
                    FilteringConstants.FilterPrice,
                    FilteringConstants.FilterNews,
                    FilteringConstants.FilterProductCategories
                }, StringComparer.OrdinalIgnoreCase);

                var result = await _searchClientService.SearchAsync <ProductDocument>(CultureInfo.CurrentCulture, descriptor => descriptor
                                                                                      .Size(0)
                                                                                      .QueryWithPermission(queryContainerDescriptor => _searchQueryBuilder.BuildQuery(queryContainerDescriptor,
                                                                                                                                                                      searchQuery,
                                                                                                                                                                      tags: null,
                                                                                                                                                                      addPriceFilterTags: false,
                                                                                                                                                                      addNewsFilterTags: false,
                                                                                                                                                                      addCategoryFilterTags: false,
                                                                                                                                                                      addDefaultQuery: true))
                                                                                      .Aggregations(rootAgg =>
                {
                    var aggs = new List <AggregationContainerDescriptor <ProductDocument> >();

                    var aggregationTagNames = fieldNames
                                              .Where(fieldName => !noFilterFieldNames.Contains(fieldName));

                    aggs.AddRange(BuildFieldAggregations(rootAgg, aggregationTagNames));
                    aggs.Add(BuildFieldAggregation(rootAgg, aggregationTagNames));

                    if (fieldNamesList.Any(fieldName => fieldName.Equals(FilteringConstants.FilterPrice, StringComparison.OrdinalIgnoreCase)))
                    {
                        aggs.Add(BuildPriceAggregation(rootAgg));
                    }

                    if (fieldNamesList.Any(fieldName => fieldName.Equals(FilteringConstants.FilterProductCategories, StringComparison.OrdinalIgnoreCase)))
                    {
                        aggs.Add(BuildCategoryAggregation(rootAgg));
                    }

                    return(aggs.Aggregate((a, b) => a & b));
                }));

                return(CollectGroupFilter());

                IEnumerable <GroupFilter> CollectGroupFilter()
                {
                    foreach (var fieldName in fieldNames)
                    {
                        if (fieldName.Equals(FilteringConstants.FilterPrice, StringComparison.OrdinalIgnoreCase))
                        {
                            var filterGroup = CollectPriceFacet();
                            if (filterGroup is object)
                            {
                                yield return(filterGroup);
                            }
                        }
                        else if (fieldName.Equals(FilteringConstants.FilterNews, StringComparison.OrdinalIgnoreCase))
                        {
                            var filterGroup = GetNewsTag(searchQuery);
                            if (filterGroup is object)
                            {
                                yield return(filterGroup);
                            }
                        }
                        else if (fieldName.Equals(FilteringConstants.FilterProductCategories, StringComparison.OrdinalIgnoreCase))
                        {
                            var filterGroup = CollectCategoryFacet();
                            if (filterGroup is object)
                            {
                                yield return(filterGroup);
                            }
                        }
                        else
                        {
                            var tag = CollectFieldFacet(fieldName);
                            if (tag is object)
                            {
                                yield return(tag);
                            }
                        }
                    }
                }

                AggregationContainerDescriptor <ProductDocument> BuildCategoryAggregation(AggregationContainerDescriptor <ProductDocument> selector)
                {
                    return(selector
                           .Nested("$Categories", filterContainer => filterContainer
                                   .Path(x => x.MainCategories)
                                   .Aggregations(a => a
                                                 .Filter("filter", filterSelector => filterSelector
                                                         .Filter(ff => ff
                                                                 .Bool(bq => bq
                                                                       .Must(m =>
                    {
                        var qc = m
                                 .Term(t => t
                                       .Field(x => x.MainCategories[0].AssortmentSystemId)
                                       .Value(_assortmentSystemId.Value)
                                       );

                        if (searchQuery.ContainsFilter() && (!searchQuery.ContainsCategoryFilter() || searchQuery.ContainsMultipleFilters()))
                        {
                            qc &= _searchQueryBuilder.BuildQuery(
                                m,
                                searchQuery,
                                tags: searchQuery.Tags,
                                addPriceFilterTags: true,
                                addNewsFilterTags: true,
                                addCategoryFilterTags: false,
                                addDefaultQuery: false);
                        }

                        return qc;
                    })
                                                                       )
                                                                 )
                                                         .Aggregations(termAgg => termAgg
                                                                       .Terms("tags", termSelector => termSelector
                                                                              .Field(x => x.MainCategories[0].AssortmentSystemId)
                                                                              .Aggregations(subAggregation => subAggregation
                                                                                            .Terms("tag", valueSelector => valueSelector
                                                                                                   .Field(x => x.MainCategories[0].CategorySystemId)
                                                                                                   .Size(100)
                                                                                                   )
                                                                                            )
                                                                              )
                                                                       )
                                                         )
                                                 )
                                   ));
                }

                IEnumerable <AggregationContainerDescriptor <ProductDocument> > BuildFieldAggregations(AggregationContainerDescriptor <ProductDocument> selector, IEnumerable <string> fieldNames)
                {
                    return(fieldNames
                           .Select(fieldName =>
                    {
                        if (searchQuery.ContainsFilter(exceptTag: fieldName))
                        {
                            return selector
                            .Filter(fieldName, filterContainer => filterContainer
                                    .Filter(filterSelector => filterSelector
                                            .Bool(bq => bq
                                                  .Must(m => _searchQueryBuilder.BuildQuery(
                                                            m,
                                                            searchQuery,
                                                            tags: FilterFields(fieldName),
                                                            addPriceFilterTags: true,
                                                            addNewsFilterTags: true,
                                                            addCategoryFilterTags: true,
                                                            addDefaultQuery: false)
                                                        )
                                                  )
                                            )
                                    .Aggregations(x => BuildFilterAggregation(x, fieldName))
                                    );
                        }

                        return BuildFilterAggregation(selector, fieldName);
                    }));

                    AggregationContainerDescriptor <ProductDocument> BuildFilterAggregation(AggregationContainerDescriptor <ProductDocument> container, string fieldName)
                    {
                        return(container
                               .Nested(fieldName, nestedPerField => nestedPerField
                                       .Path(x => x.Tags)
                                       .Aggregations(fieldAggregation => fieldAggregation
                                                     .Filter("filter", fieldFilter => fieldFilter
                                                             .Filter(filter => filter
                                                                     .Term(filterTerm => filterTerm
                                                                           .Field(field => field.Tags[0].Key)
                                                                           .Value(fieldName)
                                                                           )
                                                                     )
                                                             .Aggregations(tags => tags
                                                                           .Terms("tags", termSelector => termSelector
                                                                                  .Field(field => field.Tags[0].Key)
                                                                                  .Aggregations(subAggregation => subAggregation
                                                                                                .Terms("tag", tag => tag
                                                                                                       .Field(x => x.Tags[0].Value)
                                                                                                       .Size(100)
                                                                                                       )
                                                                                                )
                                                                                  )
                                                                           )
                                                             )
                                                     )
                                       ));
                    }

                    IDictionary <string, ISet <string> > FilterFields(string fieldName)
                    {
                        return(searchQuery
                               .Tags
                               .Where(x => !x.Key.Equals(fieldName, StringComparison.OrdinalIgnoreCase))
                               .ToDictionary(x => x.Key, x => x.Value));
                    }
                }

                AggregationContainerDescriptor <ProductDocument> BuildFieldAggregation(AggregationContainerDescriptor <ProductDocument> selector, IEnumerable <string> fieldNames)
                {
                    return(selector
                           .Nested("$all-tags", filterContainer => filterContainer
                                   .Path(x => x.Tags)
                                   .Aggregations(a => a
                                                 .Filter("filter", filterSelector => filterSelector
                                                         .Filter(ff => ff
                                                                 .Bool(bq => bq
                                                                       .Must(m => m
                                                                             .Terms(t => t
                                                                                    .Field(x => x.Tags[0].Key)
                                                                                    .Terms(fieldNames)
                                                                                    )
                                                                             )
                                                                       )
                                                                 )
                                                         .Aggregations(termAgg => termAgg
                                                                       .Terms("tags", termSelector => termSelector
                                                                              .Field(x => x.Tags[0].Key)
                                                                              .Aggregations(subAggregation => subAggregation
                                                                                            .Terms("tag", valueSelector => valueSelector
                                                                                                   .Field(x => x.Tags[0].Value)
                                                                                                   .Size(100)
                                                                                                   )
                                                                                            )
                                                                              )
                                                                       )
                                                         )
                                                 )
                                   ));
                }

                AggregationContainerDescriptor <ProductDocument> BuildPriceAggregation(AggregationContainerDescriptor <ProductDocument> selector)
                {
                    if (searchQuery.ContainsFilter(includePriceFilter: false))
                    {
                        return(selector
                               .Filter("$Prices", filterContainer => filterContainer
                                       .Filter(filterSelector => filterSelector
                                               .Bool(bq => bq
                                                     .Must(m => _searchQueryBuilder.BuildQuery(
                                                               m,
                                                               searchQuery,
                                                               tags: searchQuery.Tags,
                                                               addPriceFilterTags: false,
                                                               addNewsFilterTags: true,
                                                               addCategoryFilterTags: true,
                                                               addDefaultQuery: false)
                                                           )
                                                     )
                                               )
                                       .Aggregations(x => BuildPriceAggregationItem(x))
                                       ));
                    }
                    else
                    {
                        return(BuildPriceAggregationItem(selector));
                    };

                    AggregationContainerDescriptor <ProductDocument> BuildPriceAggregationItem(AggregationContainerDescriptor <ProductDocument> selector)
                    {
                        return(selector
                               .Terms("$Prices", prices => prices
                                      .Script(script => script
                                              .Source("double r; for (item in params._source.prices) { if (params.id.contains(item.systemId) && item.countrySystemId == params.country && item.isCampaignPrice == false) { r = r == 0 ? item.price : Math.min(r, item.price)}} return r")
                                              .Params(new Dictionary <string, object> {
                            { "id", _priceContainer.Value.PriceLists.ToArray() },
                            { "country", _countrySystemId.Value },
                        }))
                                      .Size(10000)));
                    }
                }

                GroupFilter CollectCategoryFacet()
                {
                    var categoryBucket = result.Aggregations
                                         .Global("$Categories")
                                         .Filter("filter")?
                                         .Terms("tags")?
                                         .Buckets
                                         .FirstOrDefault()?
                                         .Terms("tag")?
                                         .Buckets
                                         .Select(x => new { CanConvert = Guid.TryParse(x.Key, out var id), Key = id, x.DocCount })
                                         .Where(x => x.CanConvert)
                                         .ToDictionary(x => x.Key, x => unchecked ((int)x.DocCount));

                    if (categoryBucket == null)
                    {
                        return(null);
                    }

                    return(GetProductCategoryTag(searchQuery, categoryBucket));
                }

                GroupFilter CollectFieldFacet(string fieldName)
                {
                    var fieldDefinition = _fieldDefinitionService.Get <ProductArea>(fieldName);

                    if (fieldDefinition == null)
                    {
                        return(null);
                    }

                    var allBuckets = result.Aggregations
                                     .Global("$all-tags")
                                     .Filter("filter")?
                                     .Terms("tags")?
                                     .Buckets
                                     .FirstOrDefault(x => x.Key.Equals(fieldName, StringComparison.OrdinalIgnoreCase))?
                                     .Terms("tag")?
                                     .Buckets;

                    if (allBuckets == null)
                    {
                        return(null);
                    }

                    var topNode    = result.Aggregations.Filter(fieldName);
                    var tagBuckets = (topNode?.Nested(fieldName) ?? topNode)?
                                     .Filter("filter")?
                                     .Terms("tags")?
                                     .Buckets
                                     .FirstOrDefault()?
                                     .Terms("tag")?
                                     .Buckets;

                    var tagValues = new Dictionary <string, int>();

                    foreach (var item in allBuckets)
                    {
                        var current = tagBuckets?.FirstOrDefault(x => x.Key.Equals(item.Key, StringComparison.OrdinalIgnoreCase));
                        tagValues.Add(item.Key, unchecked ((int)(current?.DocCount ?? 0)));
                    }

                    return(GetFilterTag(searchQuery, fieldDefinition, tagValues));
                }

                GroupFilter CollectPriceFacet()
                {
                    var priceBucket = result.Aggregations?.Filter("$Prices")?.Terms("$Prices")?.Buckets ?? result.Aggregations.Terms("$Prices")?.Buckets;

                    if (priceBucket != null)
                    {
                        var priceFacets = priceBucket.ToDictionary(x => decimal.Parse(x.Key, NumberStyles.Any, CultureInfo.InvariantCulture), x => unchecked ((int)x.DocCount.GetValueOrDefault()));
                        var keys        = priceFacets.Keys.Where(x => x > decimal.Zero).ToArray();
                        var minPrice    = keys.Length > 0 ? (int)Math.Abs(keys.Min()) : 0;
                        var maxPrice    = keys.Length > 0 ? (int)Math.Floor(keys.Max()) : 0;

                        var priceHits = GetPriceGroups(priceFacets, minPrice, maxPrice).ToList();
                        return(GetPriceTag(searchQuery, priceHits, true, _requestModelAccessor.RequestModel.CountryModel.Country.CurrencySystemId));
                    }
                    return(null);
                }
            }
        public override async Task <List <TagTerms> > GetTagTermsAsync(SearchQuery searchQuery, IEnumerable <string> tagNames)
        {
            if (!_searchClientService.IsConfigured)
            {
                return(await _parent.GetTagTermsAsync(searchQuery, tagNames));
            }

            var searchResponse = await _searchClientService.SearchAsync <ProductDocument>(CultureInfo.CurrentCulture, descriptor => descriptor
                                                                                          .Size(0)
                                                                                          .QueryWithPermission(queryContainerDescriptor => _searchQueryBuilder.BuildQuery(queryContainerDescriptor,
                                                                                                                                                                          searchQuery,
                                                                                                                                                                          tags: null,
                                                                                                                                                                          addPriceFilterTags: false,
                                                                                                                                                                          addNewsFilterTags: false,
                                                                                                                                                                          addCategoryFilterTags: false,
                                                                                                                                                                          addDefaultQuery: true))
                                                                                          .Aggregations(rootAgg =>
            {
                var aggs = new List <AggregationContainerDescriptor <ProductDocument> >();
                aggs.AddRange(tagNames.Select(tagName => BuildFilterAggregation(rootAgg, tagName)));
                aggs.Add(BuildTagAggregation(rootAgg, tagNames));

                return(aggs.Aggregate((a, b) => a & b));
            }));

            var result = new List <TagTerms>();

            foreach (var tagName in tagNames)
            {
                var tag = CollectTagTerms(tagName);
                if (tag != null)
                {
                    result.Add(tag);
                }
            }

            return(result);

            AggregationContainerDescriptor <ProductDocument> BuildFilterAggregation(AggregationContainerDescriptor <ProductDocument> container, string tagName)
            {
                return(container
                       .Nested(tagName, nestedPerTag => nestedPerTag
                               .Path(x => x.Tags)
                               .Aggregations(tagAggregation => tagAggregation
                                             .Filter("filter", tagFilter => tagFilter
                                                     .Filter(filter => filter
                                                             .Term(filterTerm => filterTerm
                                                                   .Field(field => field.Tags[0].Key)
                                                                   .Value(tagName)
                                                                   )
                                                             )
                                                     .Aggregations(tags => tags
                                                                   .Terms("tags", termSelector => termSelector
                                                                          .Field(field => field.Tags[0].Key)
                                                                          .Aggregations(subAggregation => subAggregation
                                                                                        .Terms("tag", tag => tag
                                                                                               .Field(x => x.Tags[0].Value)
                                                                                               )
                                                                                        )
                                                                          )
                                                                   )
                                                     )
                                             )
                               ));
            }

            AggregationContainerDescriptor <ProductDocument> BuildTagAggregation(AggregationContainerDescriptor <ProductDocument> selector, IEnumerable <string> tagNames)
            {
                return(selector
                       .Nested("$all-tags", filterContainer => filterContainer
                               .Path(x => x.Tags)
                               .Aggregations(a => a
                                             .Filter("filter", filterSelector => filterSelector
                                                     .Filter(ff => ff
                                                             .Bool(bq => bq
                                                                   .Must(m => m
                                                                         .Terms(t => t
                                                                                .Field(x => x.Tags[0].Key)
                                                                                .Terms(tagNames)
                                                                                )
                                                                         )
                                                                   )
                                                             )
                                                     .Aggregations(termAgg => termAgg
                                                                   .Terms("tags", termSelector => termSelector
                                                                          .Field(x => x.Tags[0].Key)
                                                                          .Aggregations(subAggregation => subAggregation
                                                                                        .Terms("tag", valueSelector => valueSelector
                                                                                               .Field(x => x.Tags[0].Value)
                                                                                               )
                                                                                        )
                                                                          )
                                                                   )
                                                     )
                                             )
                               ));
            }

            TagTerms CollectTagTerms(string tagName)
            {
                var fieldDefinition = _fieldDefinitionService.Get <ProductArea>(tagName);

                if (fieldDefinition == null)
                {
                    return(null);
                }

                var allBuckets = searchResponse.Aggregations
                                 .Global("$all-tags")
                                 .Filter("filter")?
                                 .Terms("tags")?
                                 .Buckets
                                 .FirstOrDefault(x => x.Key.Equals(fieldDefinition.Id, StringComparison.OrdinalIgnoreCase))?
                                 .Terms("tag")?
                                 .Buckets;

                if (allBuckets == null)
                {
                    return(null);
                }

                var topNode    = searchResponse.Aggregations.Filter(fieldDefinition.Id);
                var tagBuckets = (topNode?.Nested(fieldDefinition.Id) ?? topNode)?.Filter("filter")?
                                 .Terms("tags")?
                                 .Buckets
                                 .FirstOrDefault()?
                                 .Terms("tag")?
                                 .Buckets;

                var tagValues = new Dictionary <string, int>();

                foreach (var item in allBuckets)
                {
                    var current = tagBuckets?.FirstOrDefault(x => x.Key.Equals(item.Key, StringComparison.OrdinalIgnoreCase));
                    tagValues.Add(item.Key, unchecked ((int)(current?.DocCount ?? 0)));
                }

                return(new TagTerms
                {
                    TagName = fieldDefinition.Localizations.CurrentCulture.Name ?? fieldDefinition.Id,
                    TermCounts = tagValues
                                 .Select(x =>
                    {
                        string key;
                        switch (fieldDefinition.FieldType)
                        {
                        case SystemFieldTypeConstants.Decimal:
                        case SystemFieldTypeConstants.Int:
                            {
                                key = x.Key.TrimStart('0');
                                break;
                            }

                        case SystemFieldTypeConstants.Date:
                        case SystemFieldTypeConstants.DateTime:
                            {
                                if (long.TryParse(x.Key, NumberStyles.Any, CultureInfo.InvariantCulture, out var l))
                                {
                                    key = new DateTime(l).ToShortDateString();
                                }
                                else
                                {
                                    goto default;
                                }
                                break;
                            }

                        default:
                            {
                                key = x.Key;
                                break;
                            }
                        }

                        return new TermCount
                        {
                            Term = key,
                            Count = x.Value
                        };
                    })
                                 .ToList()
                });
            }
Ejemplo n.º 16
0
            public string Resolve(ProductSearchResult source, SearchItem destination, string destMember, ResolutionContext context)
            {
                var brandName = _fieldDefinitionService.Get <ProductArea>("Brand").GetTranslation(source.Item.GetValue <string>("Brand"), CultureInfo.CurrentCulture);

                return($"{brandName} {source.Name}".Trim());
            }