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__3
1.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](IEnumerable
1 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