Developer forum

Forum » Development » Show own assortment before shared assortment in list.

Show own assortment before shared assortment in list.

Marie Louise Veigert
Reply

Hi, 

We are having a project where loggedin users have two assortments. One is their own (personal products) and one is "all". 
They need their own assortment products to always be shown in the top.

We have solved this by checking products in their own assortment on load, but it doesnt work with pagination in Swift (1).

Are there any good notification subscribers where we can sort the list in the query before in some way?
The 'BeforeQuery' doesnt give any options to get the productlist. And the 'AfterQuery' only give the first page in pagination of products.

We are on a DW 9.19.3.

 

BR

Marie Louise


Replies

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Hi Marie Louise

You mentioned BeforeQuery and AfterQuery. These are limited, but BeforeQuery can still alter how the Lucene query is composed, even if it doesn’t expose the final product list. You could:

  • Intercept and inject a boosted term for your user’s assortment products.

  • Use Lucene’s query syntax to give extra weight to assortment items, like:

    assortmentid:user123^5 OR assortmentid:all

    where ^5 boosts your own assortment in ranking.

Another solution could be to do 2 lists - one for my assortment and one for shared assortment. Maybe in tabs. But that would be somewhat different.

Another solution would be creating a combined sorting key - one column for each customer assortment.

 
Marie Louise Veigert
Reply

Hi, 

We like the idea of injecting our own lucene query to boots the customers own assortment. But we cannot find any property on the BeforeQuery notificationsubscriber to incject raw lucene syntax.
Can you specify how to get further? 

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Here is a sample from our docs:

using System;
using System.Collections.Generic;
using System.Linq;
using Dynamicweb.Ecommerce.Shops;
using Dynamicweb.Environment;
using Dynamicweb.Extensibility;
using Dynamicweb.Extensibility.Notifications;
using Dynamicweb.Indexing;
using Dynamicweb.Indexing.Querying;
using Dynamicweb.Indexing.Querying.Expressions;
using Dynamicweb.Security.Permissions;

namespace Dynamicweb.Ecommerce.Indexing
{
    [Subscribe(Dynamicweb.Indexing.Notifications.Query.BeforeQuery)]
    public class BeforeQueryObserver : NotificationSubscriber
    {
        public override void OnNotify(string notification, NotificationArgs args)
        {
            if (ExecutingContext.IsBackEnd())
            {
                Dynamicweb.Indexing.Notifications.Query.BeforeQueryArgs beforeQueryArgs = args as Dynamicweb.Indexing.Notifications.Query.BeforeQueryArgs;
                var query = beforeQueryArgs?.Query;
                if (query is object)
                {
                    var indexService = ServiceLocator.Current.GetInstance<IIndexService>();
                    var index = indexService.LoadIndex(query.Source.Repository, query.Source.Item);
                    if (index.Builds.Any(build => build.Value is ProductIndexBuilder))
                    {
                        var expressions = new List<Expression>(new[] { query.Expression });
                        var permissionService = new UnifiedPermissionService();
                        var disallowedProductGroupIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                        var disallowedShopIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                        var allowedGroupIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                        var allowedShopIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                        using (var backendPermission = PermissionContext.Backend())
                        {
                            foreach (List<IdWithDefaultPermissionLevel<string>> permissionQueue in backendPermission.PermissionPriority)
                            {
                                foreach (var userPermission in permissionQueue)
                                {
                                    foreach (string allowedProductGroupId in permissionService.GetAllMatchingKeys<Products.Group>(userPermission.Id.ToString()))
                                        allowedGroupIds.Add(allowedProductGroupId);
                                    foreach (string allowedShopId in permissionService.GetAllMatchingKeys<Shop>(userPermission.Id.ToString()))
                                        allowedShopIds.Add(allowedShopId);
                                    foreach (string disallowedGroupId in permissionService.GetAllMatchingKeys<Products.Group>(userPermission.Id.ToString(), PermissionLevel.None))
                                    {
                                        if (!allowedGroupIds.Contains(disallowedGroupId))
                                        {
                                            disallowedProductGroupIds.Add(disallowedGroupId);
                                        }
                                    }

                                    foreach (string disallowedShopId in permissionService.GetAllMatchingKeys<Shop>(userPermission.Id.ToString(), PermissionLevel.None))
                                    {
                                        if (!allowedShopIds.Contains(disallowedShopId))
                                        {
                                            disallowedShopIds.Add(disallowedShopId);
                                        }
                                    }
                                }
                            }
                        }
                        UpdateExpressions(query, expressions, disallowedShopIds, "ShopIDs");
                        UpdateExpressions(query, expressions, disallowedProductGroupIds, "GroupIDs");
                        UpdateExpressions(query, expressions, disallowedProductGroupIds, "ParentGroupIDs");
                        query.Expression = Expression.Group(false, OperatorType.And, expressions);
                    }
                }
            }
        }

        private void UpdateExpressions(IQuery query, List<Expression> expressions, HashSet<string> disalowedValues, string fieldName)
        {
            var existingExpression = FindPermissionExpression(fieldName, query.Expression);
            if (disalowedValues.Any() && existingExpression is null)
            {
                var g = Expression.Group(true, OperatorType.And, new List<Expression>(new[] { Expression.In(Expression.Field(fieldName, fieldName), Expression.Term(disalowedValues.ToArray())) }));
                expressions.Add(g);
            }
        }

        private BinaryExpression FindPermissionExpression(string fieldName, Expression topLevelExpression)
        {
            var groupExpression = topLevelExpression as GroupExpression;
            if (groupExpression is object)
            {
                foreach (var item in groupExpression.Expressions)
                {
                    var childExpression = item as GroupExpression;
                    if (childExpression is object && childExpression.Negate && childExpression.Expressions?.Count() == 1 && childExpression.Operator == OperatorType.And)
                    {
                        var binaryExpression = childExpression.Expressions?.First() as BinaryExpression;
                        if (binaryExpression is object && binaryExpression.Operator == OperatorType.In)
                        {
                            if (binaryExpression.Left is FieldExpression)
                            {
                                var fieldExpression = binaryExpression.Left as FieldExpression;
                                if (fieldName.Equals(fieldExpression?.FieldName, StringComparison.OrdinalIgnoreCase))
                                {
                                    return binaryExpression;
                                }
                            }
                        }
                    }
                }
            }
            return null;
        }
    }
}

 

You must be logged in to post in the forum