Skip to content

Instantly share code, notes, and snippets.

@lunchin
Created March 7, 2016 17:11
Show Gist options
  • Save lunchin/e47311db1f1a53c16d07 to your computer and use it in GitHub Desktop.
Save lunchin/e47311db1f1a53c16d07 to your computer and use it in GitHub Desktop.
using EPiServer;
using EPiServer.Commerce.Marketing;
using EPiServer.Core;
using EPiServer.ServiceLocation;
using Mediachase.Commerce;
using Mediachase.Commerce.Catalog;
using Mediachase.Commerce.Marketing;
using Mediachase.Commerce.Orders;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace CodeSamples.EPiServer.Commerce.Marketing
{
#region PercentagePromotionProcessorSample
/// <summary>
/// Sample of a promotion processor for <see cref="PercentagePromotionSample"/>.
/// </summary>
[ServiceConfiguration(Lifecycle = ServiceInstanceScope.Singleton)]
public class PercentagePromotionProcessorSample : PromotionProcessorBase<PercentagePromotionSample>
{
private readonly CollectionTargetEvaluator _targetEvaluator;
private readonly IContentLoader _contentLoader;
private readonly ReferenceConverter _referenceConverter;
/// <summary>
/// Creates a new instance of a <see cref="PercentagePromotionProcessorSample"/>.
/// </summary>
/// <param name="targetEvaluator">The service that is used to evaluate an order against a promotion's target properties.</param>
/// <param name="contentLoader">The content loader used for finding the content of any <see cref="AffectedItem"/>s.</param>
/// <param name="contentLoader">The reference converter used for converting line items into <see cref="ContentReference"/>s.</param>
public PercentagePromotionProcessorSample(CollectionTargetEvaluator targetEvaluator, IContentLoader contentLoader, ReferenceConverter referenceConverter)
{
_contentLoader = contentLoader;
_targetEvaluator = targetEvaluator;
_referenceConverter = referenceConverter;
}
/// <summary>
/// Evaluates a promotion against an order form.
/// </summary>
/// <param name="orderForm">The order form to use for the evaluation.</param>
/// <param name="currency">The currency.</param>
/// <param name="promotionData">The promotion to evaluate.</param>
/// <returns>
/// A <see cref="RewardDescription" /> telling whether the promotion was fulfilled,
/// which items the promotion was applied to and to which discount percentage.
/// </returns>
public override RewardDescription Evaluate(IOrderForm orderForm, PercentagePromotionSample promotionData, PromotionProcessorContext context)
{
if (promotionData.PercentageDiscount <= 0)
{
return RewardDescription.CreatePercentageReward(
FulfillmentStatus.NotFulfilled,
Enumerable.Empty<AffectedItem>(),
promotionData,
0,
GetRewardDescriptionText(Enumerable.Empty<AffectedItem>(), FulfillmentStatus.NotFulfilled, promotionData));
}
var lineItems = GetLineItems(orderForm);
var affectedItems = _targetEvaluator.GetApplicableItems(lineItems, promotionData.Condition.Items, promotionData.Condition.MatchRecursive);
var status = FulfillmentEvaluator.GetStatusForBuyQuantityPromotion(affectedItems.Select(x => x.LineItem), promotionData.Condition.RequiredQuantity, promotionData.Condition.PartiallyFulfilledThreshold);
return RewardDescription.CreatePercentageReward(
status,
affectedItems,
promotionData,
promotionData.PercentageDiscount,
GetRewardDescriptionText(affectedItems, status, promotionData));
}
/// <summary>
/// Gets the reward description text based on a promotion's <see cref="FulfillmentStatus"/>.
/// </summary>
/// <param name="affectedItems">A collection of <see cref="AffectedItem"/>s a that a promotion has been applied to.</param>
/// <param name="fulfillmentStatus">The promotion's fulfillment status.</param>
/// <param name="promotion">The related promotion.</param>
/// <returns>The reward description text.</returns>
protected virtual string GetRewardDescriptionText(IEnumerable<AffectedItem> affectedItems, FulfillmentStatus fulfillmentStatus, PercentagePromotionSample promotion)
{
if (fulfillmentStatus.HasFlag(FulfillmentStatus.Fulfilled))
{
var contentNames = GetContentNames(affectedItems);
return String.Format(CultureInfo.InvariantCulture, "{0}% discount has been given for the items '{1}'!", promotion.PercentageDiscount, contentNames);
}
if (fulfillmentStatus.HasFlag(FulfillmentStatus.PartiallyFulfilled))
{
var remainingQuantity = promotion.Condition.RequiredQuantity - affectedItems.Sum(x => x.LineItem.Quantity);
return String.Format(CultureInfo.InvariantCulture, "Buy {0} more items and get a {1}% discount!", remainingQuantity, promotion.PercentageDiscount);
}
return "The promotion is not applicable for the current order.";
}
/// <summary>
/// Gets the names of the affected items.
/// </summary>
/// <param name="affectedItems">A collection of <see cref="AffectedItem"/>s used for getting the names.</param>
/// <returns>The names of all affected items combined into a string.</returns>
private string GetContentNames(IEnumerable<AffectedItem> affectedItems)
{
var affectedContentLinks = affectedItems.Select(x => _referenceConverter.GetContentLink(x.LineItem.Code));
var contentNames = _contentLoader.GetItems(affectedContentLinks, CultureInfo.InvariantCulture).Select(x => x.Name);
return String.Join(", ", contentNames);
}
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment