Skip to Content
author's profile photo Former Member
Former Member

How to display product promotions in solr search results?

How to display product promotions in solr search results?

Is there any way to index promotions(Bundle promotion, % promotion and fixed price) in solr?

Thank you, Vinay

Add a comment
10|10000 characters needed characters exceeded

Assigned Tags

Related questions

2 Answers

  • Best Answer
    author's profile photo Former Member
    Former Member
    Posted on Jul 15, 2014 at 12:14 PM

    Heres an example of a value provider that exports each promotion type a product belongs to. This works nice as a facet and serves as a good example. Its TOTALLY UNSUPPORTED of course but sharing is caring right :-)

     package com.hybris.totallyunsupportedcodesample;
     
     import de.hybris.platform.basecommerce.model.site.BaseSiteModel;
     import de.hybris.platform.core.model.c2l.LanguageModel;
     import de.hybris.platform.core.model.product.ProductModel;
     import de.hybris.platform.promotions.PromotionsService;
     import de.hybris.platform.promotions.model.ProductPromotionModel;
     import de.hybris.platform.servicelayer.i18n.CommonI18NService;
     import de.hybris.platform.solrfacetsearch.config.IndexConfig;
     import de.hybris.platform.solrfacetsearch.config.IndexedProperty;
     import de.hybris.platform.solrfacetsearch.config.exceptions.FieldValueProviderException;
     import de.hybris.platform.solrfacetsearch.provider.FieldNameProvider;
     import de.hybris.platform.solrfacetsearch.provider.FieldValue;
     import de.hybris.platform.solrfacetsearch.provider.FieldValueProvider;
     import de.hybris.platform.solrfacetsearch.provider.impl.AbstractPropertyFieldValueProvider;
     
     import java.io.Serializable;
     import java.util.ArrayList;
     import java.util.Collection;
     import java.util.Collections;
     import java.util.List;
     
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.beans.factory.annotation.Required;
     
     
     /**
      * This ValueProvider will provide a list of promotion codes associated with the product. This implementation uses only
      * the DefaultPromotionGroup.
      */
     public class PromotionTypeValueProvider extends AbstractPropertyFieldValueProvider implements FieldValueProvider, Serializable
     {
         private FieldNameProvider fieldNameProvider;
         private PromotionsService promotionService;
         @Autowired
         private CommonI18NService commonI18NService;
     
     
         protected FieldNameProvider getFieldNameProvider()
         {
             return fieldNameProvider;
         }
     
         @Required
         public void setFieldNameProvider(final FieldNameProvider fieldNameProvider)
         {
             this.fieldNameProvider = fieldNameProvider;
         }
     
         protected PromotionsService getPromotionsService()
         {
             return promotionService;
         }
     
         @Required
         public void setPromotionsService(final PromotionsService promotionService)
         {
             this.promotionService = promotionService;
         }
     
         @Override
         public Collection<FieldValue> getFieldValues(final IndexConfig indexConfig, final IndexedProperty indexedProperty,
                 final Object model) throws FieldValueProviderException
         {
             if (model instanceof ProductModel)
             {
                 final ProductModel product = (ProductModel) model;
     
                 final Collection<FieldValue> fieldValues = new ArrayList<FieldValue>();
     
                 if (indexedProperty.isMultiValue())
                 {
                     fieldValues.addAll(createFieldValues(product, indexConfig, indexedProperty));
                 }
                 else
                 {
                     fieldValues.addAll(createFieldValue(product, indexConfig, indexedProperty));
                 }
                 return fieldValues;
             }
             else
             {
                 throw new FieldValueProviderException("Cannot get promotion codes of non-product item");
             }
         }
     
         protected List<FieldValue> createFieldValue(final ProductModel product, final IndexConfig indexConfig,
                 final IndexedProperty indexedProperty)
         {
             final List<FieldValue> fieldValues = new ArrayList<FieldValue>();
             final BaseSiteModel baseSiteModel = indexConfig.getBaseSite();
             if (baseSiteModel != null && baseSiteModel.getDefaultPromotionGroup() != null)
             {
                 for (final ProductPromotionModel promotion : getPromotionsService().getProductPromotions(
                         Collections.singletonList(baseSiteModel.getDefaultPromotionGroup()), product))
                 {
                     final Collection<LanguageModel> languages = indexConfig.getLanguages();
                     for (final LanguageModel language : languages)
                     {
                         addFieldValues(fieldValues, indexedProperty, language, promotion.getPromotionType());
                     }
     
                 }
             }
             return fieldValues;
         }
     
         protected List<FieldValue> createFieldValues(final ProductModel product, final IndexConfig indexConfig,
                 final IndexedProperty indexedProperty)
         {
             final List<FieldValue> fieldValues = new ArrayList<FieldValue>();
             final BaseSiteModel baseSiteModel = indexConfig.getBaseSite();
             if (baseSiteModel != null && baseSiteModel.getDefaultPromotionGroup() != null)
             {
                 for (final ProductPromotionModel promotion : getPromotionsService().getProductPromotions(
                         Collections.singletonList(baseSiteModel.getDefaultPromotionGroup()), product))
                 {
                     final Collection<LanguageModel> languages = indexConfig.getLanguages();
                     for (final LanguageModel language : languages)
                     {
                         addFieldValues(fieldValues, indexedProperty, language,
                                 promotion.getPromotionType(commonI18NService.getLocaleForLanguage(language)));
                     }
                 }
             }
             return fieldValues;
         }
     
         protected void addFieldValues(final List<FieldValue> fieldValues, final IndexedProperty indexedProperty,
                 final LanguageModel language, final Object value)
         {
             final Collection<String> fieldNames = getFieldNameProvider().getFieldNames(indexedProperty,
                     language == null ? null : language.getIsocode());
             for (final String fieldName : fieldNames)
             {
                 fieldValues.add(new FieldValue(fieldName, value));
             }
         }
     }
     
    
    
    

    Heres the spring xml definition

     <bean id="promotionTypeValueProvider"
               class="com.hybris.campaigns.search.solrfacetsearch.provider.impl.PromotionTypeValueProvider"
               parent="abstractPropertyFieldValueProvider" >
             <property name="promotionsService" ref="promotionsService"/>
             <property name="fieldNameProvider" ref="solrFieldNameProvider"/>
         </bean>    
    
    
    

    And some impex to add it to your index type also for good measure :

     # Other facet properties
     INSERT_UPDATE SolrIndexedProperty;solrIndexedType(identifier)[unique=true];name[unique=true];displayName[lang=en];type(code);sortableType(code);currency[default=false];localized[default=true];multiValue[default=true];facet[default=true];facetType(code);facetSort(code);priority;useForSpellchecking[default=false];useForAutocomplete[default=false];fieldValueProvider;facetDisplayNameProvider;customFacetSortProvider;topValuesProvider;rangeSets(name)
     ;$solrIndexedType;promotionsType;Promotion Type;string ;     ;     ;     ;true ;     ;MultiSelectOr ;Alpha ; 30   ;     ;     ;promotionTypeValueProvider    ;;                         ;
     
    
    Add a comment
    10|10000 characters needed characters exceeded

  • author's profile photo Former Member
    Former Member
    Posted on Jul 15, 2014 at 09:10 AM

    Yes, this is possible by implementing your own value providers that can set those values for products. What you need to do when doing the indexing is to calculate what the promotion would be then when buying the product. This implies that you need to make sure to execute the same logic as when adding to cnd taking in account all the restrictions that apply them. In some cases it might be enough to show if a product has a promotion but in other cases you might need to show the promotion price as well.

    There are some challenges indexing the promotion: - Promotion might not be applicable anymore and no promotion applied in cart. Annoying for customer - Promotion price differs because logic in valueprovider has bugs with different prices in cart. - Indexing might take much longer time because logic calculating promotions

    In my projects we have done this a couple of times and it has not always been that easy because of minor things giving trouble. Even hybris seems to recommend that this should not be done but the customers decide in the end what functionality they want.

    Add a comment
    10|10000 characters needed characters exceeded

    • Former Member Former Member

      Then it is little bit easies :) But you might still get the situation that solr and hybris are not in synch because index job has not been executed which means that users might not get promotions that they see or get promotions that they can not see in category page. But if you get the update index work to periodically and correctly you minimize the time of hybris and SOLR being of synch

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.