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)); }
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)); } }
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 _); } } } }
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)))); }
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); }
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())); }
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() }); }
/// <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); }
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() }); }
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()); }