7

We have a Sitecore commerce site that sells tickets. There is a requirement related to promotions which is as follows:

If customer purchases tickets for a future event (Jan 1, 2019 to Jan 3, 2019), anytime this month (Aug 1, 2018 to Aug 31, 2018), they will get a discount.

To summarize, there are two types of dates to be validated here

1a. Promo usability Start Date (Aug 1, 2018)
1b. Promo usability End Date (Aug 31, 2018)

and

2a. Future Event Start Date (Jan 1, 2019)
2b. Future Event End Date (Jan 3, 2019)

When creating the promotion in the Pricing & Promotions Manager, out of the box there are Valid From & Valid To date fields, which serve for 1a & 1b.

Following this article, I have managed to create a new condition like this:

namespace Sitecore.Feature.Commerce.Promotions.Engine.Conditions
{
    using Microsoft.ApplicationBlocks.Data;
    using Sitecore.Commerce.Plugin.Carts;
    using Sitecore.Framework.Rules;
    using System;
    using System.Data;
    using System.IO;
    using System.Web;
    using System.Web.Configuration;

    [EntityIdentifier("Future Event Dates")]
    public class FutureEventDatesCondition : ICartsCondition, ICondition, IMappableRuleEntity
    {
        public IRuleValue<string> FutureEventStartDate { get; set; }
        public IRuleValue<string> FutureEventEndDate { get; set; }

        public bool Evaluate(IRuleExecutionContext context)
        {
            bool isPromoApplicable = false;
            DateTime startDate = Convert.ToDateTime(FutureEventStartDate.Yield(context));
            DateTime endDate = Convert.ToDateTime(FutureEventEndDate.Yield(context));
            DateTime checkinDate;
            DateTime checkoutDate;
            GetCartDates(out checkinDate, out checkoutDate);

            isPromoApplicable = (checkinDate != DateTime.MinValue && checkoutDate != DateTime.MinValue &&
                startDate <= checkinDate && checkinDate <= endDate &&
                startDate <= checkoutDate && checkoutDate <= endDate);
            return isPromoApplicable;
        }

        private void GetCartDates(out DateTime checkinDate, out DateTime checkoutDate)
        {
            checkinDate = DateTime.MinValue;
            checkoutDate = DateTime.MinValue;

            try
            {
                string sessionID = HttpContext.Current.Session.SessionID;

                if (!string.IsNullOrEmpty(sessionID))
                {
                    string connectionstring = Convert.ToString(WebConfigurationManager.AppSettings["DH1DbCon"]);
                    string query = "SELECT * FROM tbl_CartDates WHERE sessionId = " + HttpContext.Current.Session.SessionID;
                    DataTable dt = SqlHelper.ExecuteDataset(connectionstring, CommandType.Text, query)?.Tables[0];

                    if (dt != null && dt.Rows.Count > 0)
                    {
                        string startDate = Convert.ToString(dt.Rows[0]["checkinDate"]);
                        string endDate = Convert.ToString(dt.Rows[0]["checkoutDate"]);

                        checkinDate = !string.IsNullOrEmpty(startDate) ? Convert.ToDateTime(startDate) : DateTime.MinValue;
                        checkoutDate = !string.IsNullOrEmpty(endDate) ? Convert.ToDateTime(endDate) : DateTime.MinValue;
                    }
                    else
                    {
                        throw new Exception("CART DATES NOT FOUND");
                    }
                }
                else
                {
                      throw new Exception("NO SESSION ID");       
                }
            }
            catch (Exception ex)
            {
               throw ex;
            }
        }  
    }
}

After selecting it and clicking on OK, it will popup another dialog with two textboxes - FutureEventStartDate & FutureEventEndDate. I set the dates to Jan 01, 2019 & Jan 03, 2019.

On booking page, when I apply promo code, there is an error - "A pipeline error occurred".

In the commerce engine error logs, these were recorded:

ERROR onError:System.Exception: Error processing block: Rules.blocks.runruleset ---> System.AggregateException: One or more errors occurred. ---> Sitecore.Framework.Rules.RuleExecutionException: An error occured evaluating the primary condition of the rule. See the inner exception for details. ---> System.NullReferenceException: Object reference not set to an instance of an object. at Sitecore.Feature.Commerce.Promotions.Engine.Conditions.FutureEventDatesCondition.GetCartDates(DateTime& checkinDate, DateTime& checkoutDate) at Sitecore.Feature.Commerce.Promotions.Engine.Conditions.FutureEventDatesCondition.Evaluate(IRuleExecutionContext context) at Sitecore.Framework.Rules.BinaryCondition.Evaluate(IRuleExecutionContext context) at Sitecore.Framework.Rules.RuleEngine.Run(IRule rule, IFactProvider factProvider) --- End of inner exception stack trace --- --- End of inner exception stack trace --- --- End of inner exception stack trace --- at Sitecore.Framework.Pipelines.ReflectionPipelineBlockRunner.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Sitecore.Framework.Pipelines.BasePipelineBlockRunner.d__31.MoveNext() 37 19:59:19 ERROR CtxMsg.Error.PipelineError: Text=A pipeline error occurred. (c611483f291f41ada2f720559ab05276) 35 19:59:19 ERROR onError:System.Exception: Error processing block: Promotions.block.applypromotions ---> System.ArgumentNullException: Value cannot be null. Parameter name: source at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Sitecore.Commerce.Plugin.Promotions.ApplyPromotionsBlock.d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Sitecore.Framework.Pipelines.ReflectionPipelineBlockRunner.d__2.MoveNext() --- End of inner exception stack trace --- at Sitecore.Framework.Pipelines.ReflectionPipelineBlockRunner.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Sitecore.Framework.Pipelines.BasePipelineBlockRunner.d__3`1.MoveNext() 35 19:59:19 ERROR CtxMsg.Error.PipelineError: Text=A pipeline error occurred. (c611483f291f41ada2f720559ab05276)

Unfortunately, there is no documentation I could find on this.

Using Sitecore Commerce 8.2.1 with sc8.2u5

1

Here is what you can do - write a custom condition which has two fields, event start date and end date. You will then implement the evaluate method for items in the cart wherein you will check if the items in the cart have the start and end date between the dates specified in the condition and return true or false accordingly. For this, you will create a new plugin which will -

  1. import Sitecore.Framework.Rules
  2. have an identity identifier to be displayed at the front end. [EntityIdentifier("UsabilityCondition")]
  3. implement ICondition interface and others as needed
  4. Implement evaluate method from ICondition interface which will check of the dates from the condition against the items in the cart.

Please refer to this sample from Erwin https://github.com/commerceengineplugins/conditions

  • I have updated my question. Could you please have a look. – Qwerty Aug 15 '18 at 8:00
1

The error occurred because of this line:

HttpContext.Current.Session.SessionID;

It seems, it is not possible to get the session id in this method as this is an engine.

So, I instead had to get the cart details to proceed further.

public bool Evaluate(IRuleExecutionContext context)
{
   CommerceContext commerceContext = context.Fact<CommerceContext>((string)null);
   List<Cart> lstCarts = commerceContext.GetObjects<Cart>();
   Cart cart = lstCarts[0];
   ...
   ....
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.