<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Question Re: How to do product visibility for B2BUnit on search and plp level? in CRM and CX Q&amp;A</title>
    <link>https://community.sap.com/t5/crm-and-cx-q-a/how-to-do-product-visibility-for-b2bunit-on-search-and-plp-level/qaa-p/12204924#M421641</link>
    <description>&lt;P&gt;Hi Rohan Luthra,&lt;/P&gt;&lt;P&gt;Unfortunately, this functionality is not provided by OOTB.&lt;/P&gt;&lt;P&gt;If you need to control visibility on the search page, it requires some customization.&lt;/P&gt;&lt;P&gt;There are several ways to implement such functionality. For example:&lt;/P&gt;&lt;P&gt;1. You need to create a relation between Product and Unit (since you want to manage it on backoffice).&lt;/P&gt;&lt;P&gt;Example code (you can change the deployment code or modifiers): &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&amp;lt;relation code="Product2PrincipalRelation" autocreate="true" localized="false"&amp;gt;

   &amp;lt;deployment table="Product2PrincRel" typecode="11111"/&amp;gt;
   &amp;lt;sourceElement qualifier="accessibleProducts" type="Product" cardinality="many" ordered="false"&amp;gt;
      &amp;lt;description&amp;gt;Products which are accessible for this principal&amp;lt;/description&amp;gt;
      &amp;lt;modifiers read="true" write="false" search="true" optional="true"/&amp;gt;
   &amp;lt;/sourceElement&amp;gt;
   &amp;lt;targetElement qualifier="allowedPrincipals" type="Principal" cardinality="many" collectiontype="set"&amp;gt;
      &amp;lt;description&amp;gt;Principals which are allowed to access this catalog category&amp;lt;/description&amp;gt;
      &amp;lt;modifiers read="true" write="true" search="true" optional="true"/&amp;gt;
   &amp;lt;/targetElement&amp;gt;
&amp;lt;/relation&amp;gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;2.You need to export a unit code that has access to the product in the Solr.&lt;/P&gt;&lt;P&gt;Pay attention that you also need to implement a simple ValueResolver to retrieve the code from the Unit. &lt;/P&gt;&lt;P&gt;Here is an example of how to do it:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;public class PrincipalProductValueResolver extends AbstractValueResolver&amp;lt;ProductModel, Object, Object&amp;gt; {

@Override
protected void addFieldValues(final InputDocument document, final IndexerBatchContext batchCtx, final IndexedProperty indexedProperty, final ProductModel product, final ValueResolverContext&amp;lt;Object, Object&amp;gt; valueResolverCtx) throws FieldValueProviderException {

Set&amp;lt;PrincipalModel&amp;gt; allowedPrincipals = product.getAllowedPrincipals();
for (final PrincipalModel principal : allowedPrincipals) {
    document.addField(indexedProperty, principal.getUid(), valueResolverCtx.getFieldQualifier());
} 
}}&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;This is a simple configuration for Solr: &lt;/P&gt;&lt;P&gt;You need to change IndexedType to your value. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;$solrIndexedType = powertoolsProductType
INSERT_UPDATE SolrIndexedProperty; solrIndexedType(identifier)[unique = true]; name[unique = true]; type(code); sortableType(code); currency[default = false]; localized[default = false]; multiValue[default = false]; useForSpellchecking[default = false]; useForAutocomplete[default = false]; fieldValueProvider; valueProviderParameter

; $solrIndexedType ; allowedPrincipals            ; string  ;              ;      ;     ; true ;      ;      ; principalProductValueResolver                             ;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;3. Then, you should collect products by unit name/code. (It means that you need to create a custom implementation for FacetSearchListener since you need to add a unit code in Solr query). Example:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;public class GroupRestrictionFacetSearchListener implements FacetSearchListener {
private static final String ALLOWED_PRINCIPALS_KEY = "allowedPrincipals"; 
private static final String FILTER_QUERY = "(%s:%s)"; 
private FieldNameTranslator fieldNameTranslator; 
private B2BUnitService&amp;lt;B2BUnitModel, B2BCustomerModel&amp;gt; b2bUnitService; 
private UserService userService;

@Override
public void beforeSearch(FacetSearchContext context) {
UserModel currentUser = userService.getCurrentUser(); 
if (!(currentUser instanceof B2BCustomerModel)) {
return;
}
final B2BUnitModel currentB2BUnit = b2bUnitService.getParent((B2BCustomerModel) currentUser); 

if (currentB2BUnit == null) {
return;
}

final SearchQuery solrSearchQuery = context.getSearchQuery(); 

final String allowedPrincipalsFieldName = getFieldNameTranslator().translate(context, ALLOWED_PRINCIPALS_KEY);

solrSearchQuery.addFilterRawQuery(String.format(FILTER_QUERY, allowedPrincipalsFieldName, currentB2BUnit.getUid()));
}
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;And this listener should be assigned to your index. Example:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;UPDATE SolrFacetSearchConfig; name[unique = true]; listeners; 
; powertoolsIndex ; b2bGroupFilterListener ;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Thus, you can retrieve a set of products particularly for a specific unit.&lt;/P&gt;&lt;P&gt;In this implementation, you will be able to see which products are assigned to the unit in BO. Example:&lt;/P&gt;&lt;P&gt;&lt;IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/attachments/storage/7/attachments/1807667-image1.png" /&gt;&lt;/P&gt;&lt;P&gt;And on each product, you can choose the principals who can see this product.&lt;/P&gt;&lt;P&gt;&lt;IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/attachments/storage/7/attachments/1807668-image2.png" /&gt;&lt;/P&gt;&lt;P&gt;A little bit about example implementation. Why do we use PrincipalsModel instead of B2BUnitModel? It’s quite simple: in the future, this functionality can be used for any other principals (customers, users, UserGroups, units, etc.).&lt;/P&gt;&lt;P&gt;Best regards,&lt;/P&gt;&lt;P&gt;Igor&lt;/P&gt;</description>
    <pubDate>Wed, 13 May 2020 11:56:36 GMT</pubDate>
    <dc:creator>aimprosoft</dc:creator>
    <dc:date>2020-05-13T11:56:36Z</dc:date>
    <item>
      <title>How to do product visibility for B2BUnit on search and plp level?</title>
      <link>https://community.sap.com/t5/crm-and-cx-q-a/how-to-do-product-visibility-for-b2bunit-on-search-and-plp-level/qaq-p/12204923</link>
      <description>&lt;P&gt;Want to visible products to only particular b2bunit on search and plp.&lt;/P&gt;
  &lt;P&gt;wanted to do only through backoffice configuration. &lt;/P&gt;</description>
      <pubDate>Fri, 13 Mar 2020 20:33:32 GMT</pubDate>
      <guid>https://community.sap.com/t5/crm-and-cx-q-a/how-to-do-product-visibility-for-b2bunit-on-search-and-plp-level/qaq-p/12204923</guid>
      <dc:creator>rohan_luthra94</dc:creator>
      <dc:date>2020-03-13T20:33:32Z</dc:date>
    </item>
    <item>
      <title>Re: How to do product visibility for B2BUnit on search and plp level?</title>
      <link>https://community.sap.com/t5/crm-and-cx-q-a/how-to-do-product-visibility-for-b2bunit-on-search-and-plp-level/qaa-p/12204924#M421641</link>
      <description>&lt;P&gt;Hi Rohan Luthra,&lt;/P&gt;&lt;P&gt;Unfortunately, this functionality is not provided by OOTB.&lt;/P&gt;&lt;P&gt;If you need to control visibility on the search page, it requires some customization.&lt;/P&gt;&lt;P&gt;There are several ways to implement such functionality. For example:&lt;/P&gt;&lt;P&gt;1. You need to create a relation between Product and Unit (since you want to manage it on backoffice).&lt;/P&gt;&lt;P&gt;Example code (you can change the deployment code or modifiers): &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&amp;lt;relation code="Product2PrincipalRelation" autocreate="true" localized="false"&amp;gt;

   &amp;lt;deployment table="Product2PrincRel" typecode="11111"/&amp;gt;
   &amp;lt;sourceElement qualifier="accessibleProducts" type="Product" cardinality="many" ordered="false"&amp;gt;
      &amp;lt;description&amp;gt;Products which are accessible for this principal&amp;lt;/description&amp;gt;
      &amp;lt;modifiers read="true" write="false" search="true" optional="true"/&amp;gt;
   &amp;lt;/sourceElement&amp;gt;
   &amp;lt;targetElement qualifier="allowedPrincipals" type="Principal" cardinality="many" collectiontype="set"&amp;gt;
      &amp;lt;description&amp;gt;Principals which are allowed to access this catalog category&amp;lt;/description&amp;gt;
      &amp;lt;modifiers read="true" write="true" search="true" optional="true"/&amp;gt;
   &amp;lt;/targetElement&amp;gt;
&amp;lt;/relation&amp;gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;2.You need to export a unit code that has access to the product in the Solr.&lt;/P&gt;&lt;P&gt;Pay attention that you also need to implement a simple ValueResolver to retrieve the code from the Unit. &lt;/P&gt;&lt;P&gt;Here is an example of how to do it:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;public class PrincipalProductValueResolver extends AbstractValueResolver&amp;lt;ProductModel, Object, Object&amp;gt; {

@Override
protected void addFieldValues(final InputDocument document, final IndexerBatchContext batchCtx, final IndexedProperty indexedProperty, final ProductModel product, final ValueResolverContext&amp;lt;Object, Object&amp;gt; valueResolverCtx) throws FieldValueProviderException {

Set&amp;lt;PrincipalModel&amp;gt; allowedPrincipals = product.getAllowedPrincipals();
for (final PrincipalModel principal : allowedPrincipals) {
    document.addField(indexedProperty, principal.getUid(), valueResolverCtx.getFieldQualifier());
} 
}}&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;This is a simple configuration for Solr: &lt;/P&gt;&lt;P&gt;You need to change IndexedType to your value. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;$solrIndexedType = powertoolsProductType
INSERT_UPDATE SolrIndexedProperty; solrIndexedType(identifier)[unique = true]; name[unique = true]; type(code); sortableType(code); currency[default = false]; localized[default = false]; multiValue[default = false]; useForSpellchecking[default = false]; useForAutocomplete[default = false]; fieldValueProvider; valueProviderParameter

; $solrIndexedType ; allowedPrincipals            ; string  ;              ;      ;     ; true ;      ;      ; principalProductValueResolver                             ;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;3. Then, you should collect products by unit name/code. (It means that you need to create a custom implementation for FacetSearchListener since you need to add a unit code in Solr query). Example:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;public class GroupRestrictionFacetSearchListener implements FacetSearchListener {
private static final String ALLOWED_PRINCIPALS_KEY = "allowedPrincipals"; 
private static final String FILTER_QUERY = "(%s:%s)"; 
private FieldNameTranslator fieldNameTranslator; 
private B2BUnitService&amp;lt;B2BUnitModel, B2BCustomerModel&amp;gt; b2bUnitService; 
private UserService userService;

@Override
public void beforeSearch(FacetSearchContext context) {
UserModel currentUser = userService.getCurrentUser(); 
if (!(currentUser instanceof B2BCustomerModel)) {
return;
}
final B2BUnitModel currentB2BUnit = b2bUnitService.getParent((B2BCustomerModel) currentUser); 

if (currentB2BUnit == null) {
return;
}

final SearchQuery solrSearchQuery = context.getSearchQuery(); 

final String allowedPrincipalsFieldName = getFieldNameTranslator().translate(context, ALLOWED_PRINCIPALS_KEY);

solrSearchQuery.addFilterRawQuery(String.format(FILTER_QUERY, allowedPrincipalsFieldName, currentB2BUnit.getUid()));
}
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;And this listener should be assigned to your index. Example:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;UPDATE SolrFacetSearchConfig; name[unique = true]; listeners; 
; powertoolsIndex ; b2bGroupFilterListener ;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Thus, you can retrieve a set of products particularly for a specific unit.&lt;/P&gt;&lt;P&gt;In this implementation, you will be able to see which products are assigned to the unit in BO. Example:&lt;/P&gt;&lt;P&gt;&lt;IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/attachments/storage/7/attachments/1807667-image1.png" /&gt;&lt;/P&gt;&lt;P&gt;And on each product, you can choose the principals who can see this product.&lt;/P&gt;&lt;P&gt;&lt;IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/attachments/storage/7/attachments/1807668-image2.png" /&gt;&lt;/P&gt;&lt;P&gt;A little bit about example implementation. Why do we use PrincipalsModel instead of B2BUnitModel? It’s quite simple: in the future, this functionality can be used for any other principals (customers, users, UserGroups, units, etc.).&lt;/P&gt;&lt;P&gt;Best regards,&lt;/P&gt;&lt;P&gt;Igor&lt;/P&gt;</description>
      <pubDate>Wed, 13 May 2020 11:56:36 GMT</pubDate>
      <guid>https://community.sap.com/t5/crm-and-cx-q-a/how-to-do-product-visibility-for-b2bunit-on-search-and-plp-level/qaa-p/12204924#M421641</guid>
      <dc:creator>aimprosoft</dc:creator>
      <dc:date>2020-05-13T11:56:36Z</dc:date>
    </item>
  </channel>
</rss>

