cancel
Showing results for 
Search instead for 
Did you mean: 

How to do product visibility for B2BUnit on search and plp level?

rohan_luthra94
Explorer
0 Kudos

Want to visible products to only particular b2bunit on search and plp.

wanted to do only through backoffice configuration.

Accepted Solutions (0)

Answers (1)

Answers (1)

aimprosoft
Participant
0 Kudos

Hi Rohan Luthra,

Unfortunately, this functionality is not provided by OOTB.

If you need to control visibility on the search page, it requires some customization.

There are several ways to implement such functionality. For example:

1. You need to create a relation between Product and Unit (since you want to manage it on backoffice).

Example code (you can change the deployment code or modifiers):

<relation code="Product2PrincipalRelation" autocreate="true" localized="false">

   <deployment table="Product2PrincRel" typecode="11111"/>
   <sourceElement qualifier="accessibleProducts" type="Product" cardinality="many" ordered="false">
      <description>Products which are accessible for this principal</description>
      <modifiers read="true" write="false" search="true" optional="true"/>
   </sourceElement>
   <targetElement qualifier="allowedPrincipals" type="Principal" cardinality="many" collectiontype="set">
      <description>Principals which are allowed to access this catalog category</description>
      <modifiers read="true" write="true" search="true" optional="true"/>
   </targetElement>
</relation>

2.You need to export a unit code that has access to the product in the Solr.

Pay attention that you also need to implement a simple ValueResolver to retrieve the code from the Unit.

Here is an example of how to do it:

public class PrincipalProductValueResolver extends AbstractValueResolver<ProductModel, Object, Object> {

@Override
protected void addFieldValues(final InputDocument document, final IndexerBatchContext batchCtx, final IndexedProperty indexedProperty, final ProductModel product, final ValueResolverContext<Object, Object> valueResolverCtx) throws FieldValueProviderException {

Set<PrincipalModel> allowedPrincipals = product.getAllowedPrincipals();
for (final PrincipalModel principal : allowedPrincipals) {
    document.addField(indexedProperty, principal.getUid(), valueResolverCtx.getFieldQualifier());
} 
}}

This is a simple configuration for Solr:

You need to change IndexedType to your value.

$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                             ;

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:

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<B2BUnitModel, B2BCustomerModel> 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()));
}
}

And this listener should be assigned to your index. Example:

UPDATE SolrFacetSearchConfig; name[unique = true]; listeners; 
; powertoolsIndex ; b2bGroupFilterListener ;

Thus, you can retrieve a set of products particularly for a specific unit.

In this implementation, you will be able to see which products are assigned to the unit in BO. Example:

And on each product, you can choose the principals who can see this product.

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.).

Best regards,

Igor