public void MerketingSystem_BuyXGetNoffYatReducedPrice() { PromotionEntriesSet sourceSet = new PromotionEntriesSet(); PromotionEntriesSet targetSet = new PromotionEntriesSet(); PromotionEntry itemY1 = new PromotionEntry("", "Apple iPod touch 16 GB (Old)", "ELCB000JNYWBG6", 100); PromotionEntry itemY2 = new PromotionEntry("", "Apple iPod touch 16 GB (Old)", "ELCB000JNYWBG6", 100); itemY2.Quantity = 10; PromotionEntry itemXspecified = new PromotionEntry("", "Plantronics Voyager 510 - Bluetooth Headset Carrying Case", "ELCB000FOM68A6", 100); PromotionEntry itemXnotspecified = new PromotionEntry("", "510 Headset Charger", "ELCB000GKLGX46", 100); PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; //Exsist promotion //X promotion entry set is ELCB000PBOWNK6, ELCB000GKLGX46 //Exclude set to off //Y promotion entry is ELCB000JNYWBG6 //Max Y quantity is 3 //Amount 15 percent //First use case. X entry not contains in promotion X entry set itemXnotspecified.Quantity = 2; sourceSet.Entries.Add(itemXnotspecified); //Two Y entry one 1 quantity , other 10 quantity targetSet.Entries.Add(itemY1); targetSet.Entries.Add(itemY2); PromotionContext context = PrepareMarketingContext(sourceSet, targetSet); MarketingContext.Current.EvaluatePromotions(true, context, filter); Assert.IsTrue(context.PromotionResult.PromotionRecords.Count == 0); //Second use case. X entry contains in promotion X entry set sourceSet.Entries.Clear(); sourceSet.Entries.Add(itemXspecified); context = PrepareMarketingContext(sourceSet, targetSet); MarketingContext.Current.EvaluatePromotions(true, context, filter); Assert.IsTrue(context.PromotionResult.PromotionRecords.Count == 1); foreach (PromotionItemRecord record in context.PromotionResult.PromotionRecords) { Assert.IsTrue(record.AffectedEntriesSet.TotalQuantity == 3); Assert.IsTrue(record.PromotionReward.AmountOff == 15); } //Third use case. X entry empty. Y entry specified. First instanse of item Y becomes the eligible item X, and charged bu regular price sourceSet.Entries.Clear(); targetSet.Entries.Clear(); itemY1.Quantity = 3; targetSet.Entries.Add(itemY1); context = PrepareMarketingContext(sourceSet, targetSet); MarketingContext.Current.EvaluatePromotions(true, context, filter); Assert.IsTrue(context.PromotionResult.PromotionRecords.Count == 1); foreach (PromotionItemRecord record in context.PromotionResult.PromotionRecords) { Assert.IsTrue(record.AffectedEntriesSet.TotalQuantity == 2); Assert.IsTrue(record.PromotionReward.AmountOff == 15); } }
public IPriceValue GetDiscountPrice(IPriceValue price, EntryContentBase entry, Currency currency, PromotionHelperFacade promotionHelper) { var promotionEntry = CreatePromotionEntry(entry, price); var filter = new PromotionFilter { IgnoreConditions = false, IgnorePolicy = false, IgnoreSegments = false, IncludeCoupons = false }; var sourceSet = new PromotionEntriesSet(); sourceSet.Entries.Add(promotionEntry); var promotionContext = promotionHelper.Evaluate(filter, sourceSet, sourceSet, false); if (promotionContext.PromotionResult.PromotionRecords.Count > 0) { return new PriceValue { CatalogKey = price.CatalogKey, CustomerPricing = CustomerPricing.AllCustomers, MarketId = price.MarketId, MinQuantity = 1, UnitPrice = new Money(price.UnitPrice.Amount - GetDiscountPrice(promotionContext), currency), ValidFrom = DateTime.UtcNow, ValidUntil = null }; } return price; }
public void MerketingSystem_BuyXOffShipment_10PercentOff() { // three Promotion #1 - 10 MinQuantity, 5$ reward; // #2 - 20 MinQuantity, 10$ Reward; // #3 - 30 MinQuantity 15$ Reward. PromotionEntriesSet sourceSet = new PromotionEntriesSet(); PromotionEntry entry = new PromotionEntry("", "", "Plasma-EDTV", 100); entry.Quantity = 20; sourceSet.Entries.Add(entry); MarketingContext ctx = MarketingContext.Current; Assert.IsNotNull(ctx); Assert.IsNotNull(ctx.MarketingProfileContext); //IDictionary<string, object> ctx = new Dictionary<string, object>(); PromotionContext context = new PromotionContext(ctx.MarketingProfileContext, sourceSet, sourceSet); PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; MarketingContext.Current.EvaluatePromotions(true, context, filter); foreach (PromotionItemRecord record in context.PromotionResult.PromotionRecords) { decimal amountOff = record.PromotionReward.AmountOff; // Validate promotion Assert.IsTrue(amountOff == 10); } }
public IPriceValue GetDiscountPrice(IPriceValue price, EntryContentBase entry, Currency currency, PromotionHelperFacade promotionHelper) { var promotionEntry = CreatePromotionEntry(entry, price); var filter = new PromotionFilter { IgnoreConditions = false, IgnorePolicy = false, IgnoreSegments = false, IncludeCoupons = false }; var sourceSet = new PromotionEntriesSet(); sourceSet.Entries.Add(promotionEntry); var promotionContext = promotionHelper.Evaluate(filter, sourceSet, sourceSet, false); if (promotionContext.PromotionResult.PromotionRecords.Count > 0) { return(new PriceValue { CatalogKey = price.CatalogKey, CustomerPricing = CustomerPricing.AllCustomers, MarketId = price.MarketId, MinQuantity = 1, UnitPrice = new Money(price.UnitPrice.Amount - GetDiscountPrice(promotionContext), currency), ValidFrom = DateTime.UtcNow, ValidUntil = null }); } return(price); }
public virtual PromotionContext Evaluate(PromotionFilter filter, PromotionEntriesSet sourceEntriesSet, PromotionEntriesSet targetEntriesSet, bool checkEntryLevelLimit) { var helper = new PromotionHelper(); helper.PromotionContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; helper.PromotionContext.SourceEntriesSet = sourceEntriesSet; helper.PromotionContext.TargetEntriesSet = targetEntriesSet; helper.Eval(filter, checkEntryLevelLimit); return helper.PromotionContext; }
public virtual PromotionContext Evaluate(PromotionFilter filter, PromotionEntriesSet sourceEntriesSet, PromotionEntriesSet targetEntriesSet, bool checkEntryLevelLimit) { var helper = new PromotionHelper(); helper.PromotionContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; helper.PromotionContext.SourceEntriesSet = sourceEntriesSet; helper.PromotionContext.TargetEntriesSet = targetEntriesSet; helper.Eval(filter, checkEntryLevelLimit); return(helper.PromotionContext); }
private PromotionContext PrepareMarketingContext(PromotionEntriesSet sourceSet, PromotionEntriesSet targetSet) { PromotionContext retVal = null; MarketingContext ctx = MarketingContext.Current; Assert.IsNotNull(ctx); Assert.IsNotNull(ctx.MarketingProfileContext); //IDictionary<string, object> ctx = new Dictionary<string, object>(); retVal = new PromotionContext(ctx.MarketingProfileContext, sourceSet, targetSet); return(retVal); }
/// <summary> /// Creates the set from order form. /// </summary> /// <param name="form">The form.</param> /// <returns></returns> private PromotionEntriesSet CreateSetFromOrderForm(OrderForm form) { PromotionEntriesSet set = new PromotionEntriesSet(); set.OwnerId = form.OrderFormId.ToString(); foreach (LineItem lineItem in form.LineItems) { set.Entries.Add(CreatePromotionEntryFromLineItem(lineItem)); } return(set); }
private static void PreparePromotion(PromotionHelper helper, Entry entry, bool checkEntryLevelDiscountLimit) { var currentMarket = CurrentMarket.Service.GetCurrentMarket(); decimal minQuantity = 1; // get min quantity attribute if (entry.ItemAttributes != null) { minQuantity = entry.ItemAttributes.MinQuantity; } // we can't pass qauntity of 0, so make it default to 1 if (minQuantity <= 0) { minQuantity = 1; } var price = StoreHelper.GetSalePrice(entry, minQuantity, currentMarket) ?? new Mediachase.Commerce.Catalog.Objects.Price(new Money(0, currentMarket.DefaultCurrency)); // Create filter var filter = new PromotionFilter() { IgnoreConditions = false, IgnorePolicy = false, IgnoreSegments = false, IncludeCoupons = false }; // Create new entry // TPB: catalogNodes is determined by the front end. GetParentNodes(entry) var result = new PromotionEntry(String.Empty, String.Empty, entry.ID, price.Money.Amount); var promotionEntryPopulateService = (IPromotionEntryPopulate)MarketingContext.Current.PromotionEntryPopulateFunctionClassInfo.CreateInstance(); promotionEntryPopulateService.Populate(result, entry, currentMarket.MarketId, currentMarket.DefaultCurrency); var sourceSet = new PromotionEntriesSet(); sourceSet.Entries.Add(result); // Only target entries helper.PromotionContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; // Configure promotion context helper.PromotionContext.SourceEntriesSet = sourceSet; helper.PromotionContext.TargetEntriesSet = sourceSet; // Execute the promotions and filter out basic collection of promotions, we need to execute with cache disabled, so we get latest info from the database helper.Eval(filter, checkEntryLevelDiscountLimit); }
/// <summary> /// Creates the set from order form. /// </summary> /// <param name="form">The form.</param> /// <returns></returns> private PromotionEntriesSet CreateSetFromOrderForm(OrderForm form) { PromotionEntriesSet set = new PromotionEntriesSet(); set.OrderFormId = form.OrderFormId.ToString(); IOrderedEnumerable <LineItem> lineItemByPrice = form.LineItems.ToArray().Where(x => !IsGiftLineItem(x)).OrderByDescending(x => x.PlacedPrice); foreach (LineItem lineItem in lineItemByPrice) { set.Entries.Add(CreatePromotionEntryFromLineItem(lineItem)); } return(set); }
/// <summary> /// Creates the set from shipment. /// </summary> /// <param name="shipment">The shipment.</param> /// <returns></returns> private PromotionEntriesSet CreateSetFromShipment(Shipment shipment) { PromotionEntriesSet set = new PromotionEntriesSet(); set.OwnerId = shipment.ShipmentId.ToString(); foreach (string lineItemIndex in shipment.LineItemIndexes) { LineItem lineItem = shipment.Parent.LineItems[Int32.Parse(lineItemIndex)]; if (lineItem != null) { PromotionEntry entry = CreatePromotionEntryFromLineItem(lineItem); set.Entries.Add(entry); } } return(set); }
/// <summary> /// Adds the free gift to cart. /// </summary> /// <remarks> This method using in promotion actions rulset</remarks> /// <param name="quantity">The quantity.</param> /// <param name="entryCodes">The entry codes.</param> public void AddFreeGiftToCart(string quantity, params string[] entryCodes) { decimal giftQuantity = Convert.ToDecimal(quantity, System.Globalization.CultureInfo.InvariantCulture); GiftPromotionReward giftAddWhenNeedReward = new GiftPromotionReward(PromotionRewardType.EachAffectedEntry, 0, PromotionRewardAmountType.Percentage, GiftPromotionReward.Strategy.AddWhenNeeded); PromotionEntriesSet giftEntrySet = new PromotionEntriesSet(); giftEntrySet.OwnerId = this.PromotionContext.TargetEntriesSet.OwnerId; foreach (string entryCode in entryCodes) { PromotionEntry entry = new PromotionEntry(entryCode, entryCode, entryCode, 0); entry.Quantity = giftQuantity; giftEntrySet.Entries.Add(entry); } this.AddPromotionItemRecord(giftAddWhenNeedReward, giftEntrySet); }
public void MarketingSystem_BuyXGetXDiscount() { PromotionEntriesSet sourceSet = new PromotionEntriesSet(); sourceSet.Entries.Add(new PromotionEntry("", "", "42-Plasma-EDTV", 1)); MarketingContext ctx = MarketingContext.Current; Assert.IsNotNull(ctx); Assert.IsNotNull(ctx.MarketingProfileContext); //IDictionary<string, object> ctx = new Dictionary<string, object>(); PromotionContext context = new PromotionContext(ctx.MarketingProfileContext, sourceSet, sourceSet); PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; MarketingContext.Current.EvaluatePromotions(true, context, filter); foreach (PromotionItemRecord record in context.PromotionResult.PromotionRecords) { // Validate promotion Assert.IsTrue(record.PromotionReward.AmountOff == 10); } }
public void MerketingSystem_OrderVolumePromotion_10PercentOff() { PromotionEntriesSet sourceSet = new PromotionEntriesSet(); //Add entry totalCost equals 2000 sourceSet.Entries.Add(new PromotionEntry("", "", "42-Plasma-EDTV", 2000)); MarketingContext ctx = MarketingContext.Current; Assert.IsNotNull(ctx); Assert.IsNotNull(ctx.MarketingProfileContext); //IDictionary<string, object> ctx = new Dictionary<string, object>(); PromotionContext context = new PromotionContext(ctx.MarketingProfileContext, sourceSet, sourceSet); PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; MarketingContext.Current.EvaluatePromotions(true, context, filter); foreach (PromotionItemRecord record in context.PromotionResult.PromotionRecords) { decimal amountOff = record.PromotionReward.AmountOff; // Validate promotion Assert.IsTrue(amountOff == 10); } }
/// <summary> /// Creates the entry from target. /// </summary> /// <param name="entryCode">The entry code.</param> /// <param name="quantity">The quantity.</param> /// <returns></returns> public PromotionEntriesSet CreatePromotionEntriesSetFromTarget(string entryCode, decimal quantity) { PromotionEntriesSet retVal = new PromotionEntriesSet(); retVal.OwnerId = this.PromotionContext.TargetEntriesSet.OwnerId; foreach (PromotionEntry entry in PromotionContext.TargetEntriesSet.Entries) { if (quantity == 0) { break; } if (entry.CatalogEntryCode.Equals(entryCode, StringComparison.CurrentCultureIgnoreCase)) { PromotionEntry entryToAdd = (PromotionEntry)entry.Clone(); entryToAdd.Quantity = Math.Min(quantity, entryToAdd.Quantity); quantity -= entryToAdd.Quantity; retVal.Entries.Add(entryToAdd); } } return(retVal); }
/// <summary> /// Initializes a new instance of the <see cref="PromotionItemRecord"/> class. /// </summary> /// <param name="targetEntries">The target entries.</param> /// <param name="affectedEntries">The affected entries.</param> /// <param name="reward">The reward.</param> public PromotionItemRecord(PromotionEntriesSet targetEntries, PromotionEntriesSet affectedEntries, PromotionReward reward) { _TargetEntriesSet = targetEntries; _AffectedEntriesSet = affectedEntries; _Reward = reward; }
// Old stuff... no demo... Legacy Promos // This is a slightly-refactored version of the StoreHelper.GetDiscountPrice() method // catalogName and catalogNodeCode... can be used to filter out certain nodes or catalogs private static Price GetDiscountPriceInternal(EntryContentBase contentSku, Entry sku, IPriceValue price, string catalogName, string catalogNodeCode) { string catalogNodes = String.Empty; string catalogs = String.Empty; // Now cycle through all the catalog nodes where this entry is present filtering by specified catalog and node code // Note: The nodes are only populated when Full or Nodes response group is specified. if (sku.Nodes != null && sku.Nodes.CatalogNode != null && sku.Nodes.CatalogNode.Length > 0) { foreach (CatalogNode node in sku.Nodes.CatalogNode) { string entryCatalogName = CatalogContext.Current.GetCatalogDto(node.CatalogId).Catalog[0].Name; // Skip filtered catalogs if (!String.IsNullOrEmpty(catalogName) && !entryCatalogName.Equals(catalogName)) { continue; } // Skip filtered catalogs nodes if (!String.IsNullOrEmpty(catalogNodeCode) && !node.ID.Equals(catalogNodeCode, StringComparison.OrdinalIgnoreCase)) { continue; } if (String.IsNullOrEmpty(catalogs)) { catalogs = entryCatalogName; } else { catalogs += ";" + entryCatalogName; } if (String.IsNullOrEmpty(catalogNodes)) { catalogNodes = node.ID; } else { catalogNodes += ";" + node.ID; } } } if (String.IsNullOrEmpty(catalogs)) { catalogs = catalogName; } if (String.IsNullOrEmpty(catalogNodes)) { catalogNodes = catalogNodeCode; } // Get current context Dictionary <string, object> context = MarketingContext.Current.MarketingProfileContext; // Create filter PromotionFilter filter = new PromotionFilter { IgnoreConditions = false, IgnorePolicy = false, IgnoreSegments = false, IncludeCoupons = false }; // Create new entry // Note: catalogNodes is determined by GetParentNodes(entry) PromotionEntry result = new PromotionEntry(catalogs, catalogNodes, sku.ID, price.UnitPrice.Amount); var promotionEntryPopulateService = (IPromotionEntryPopulate)MarketingContext.Current.PromotionEntryPopulateFunctionClassInfo.CreateInstance(); promotionEntryPopulateService.Populate(result, sku, _currentMarket.Service.GetCurrentMarket().MarketId, _currentMarket.Service.GetCurrentMarket().DefaultCurrency); PromotionEntriesSet sourceSet = new PromotionEntriesSet(); sourceSet.Entries.Add(result); // Create new promotion helper, which will initialize PromotionContext object for us and setup context dictionary PromotionHelper helper = new PromotionHelper(); // Only target entries helper.PromotionContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; // Configure promotion context helper.PromotionContext.SourceEntriesSet = sourceSet; helper.PromotionContext.TargetEntriesSet = sourceSet; // Execute the promotions and filter out basic collection of promotions, we need to execute with cache disabled, so we get latest info from the database helper.Eval(filter); Money discountedAmount; // Check the count, and get new price if promotion is applied if (helper.PromotionContext.PromotionResult.PromotionRecords.Count > 0) { discountedAmount = new Money(price.UnitPrice.Amount - GetDiscountPriceFromPromotionResult( helper.PromotionContext.PromotionResult), _currentMarket.Service.GetCurrentMarket().DefaultCurrency); return(new Price { UnitPrice = discountedAmount, ValidFrom = price.ValidFrom, ValidUntil = price.ValidUntil, MinQuantity = price.MinQuantity, MarketId = price.MarketId, EntryContent = contentSku, CustomerPricing = price.CustomerPricing }); } else { return(new Price(price)); } }
public override PromotionContext Evaluate(PromotionFilter filter, PromotionEntriesSet sourceEntriesSet, PromotionEntriesSet targetEntriesSet, bool checkEntryLevelLimit) { return null; }
/// <summary> /// Creates the set from order form. /// </summary> /// <param name="form">The form.</param> /// <returns></returns> private PromotionEntriesSet CreateSetFromOrderForm(OrderForm form) { PromotionEntriesSet set = new PromotionEntriesSet(); set.OrderFormId = form.OrderFormId.ToString(); IOrderedEnumerable<LineItem> lineItemByPrice = form.LineItems.ToArray().Where(x => !IsGiftLineItem(x)).OrderByDescending(x => x.PlacedPrice); foreach (LineItem lineItem in lineItemByPrice) { set.Entries.Add(CreatePromotionEntryFromLineItem(lineItem)); } return set; }
/// <summary> /// Creates the set from shipment. /// </summary> /// <param name="shipment">The shipment.</param> /// <returns></returns> private PromotionEntriesSet CreateSetFromShipment(Shipment shipment) { PromotionEntriesSet set = new PromotionEntriesSet(); set.ShipmentId = shipment.ShipmentId.ToString(); set.OrderFormId = shipment.Parent.OrderFormId.ToString(); foreach (string lineItemIndex in shipment.LineItemIndexes) { LineItem lineItem = shipment.Parent.LineItems[Int32.Parse(lineItemIndex)]; if (lineItem != null && !IsGiftLineItem(lineItem)) { PromotionEntry entry = CreatePromotionEntryFromLineItem(lineItem); set.Entries.Add(entry); } } return set; }
/// <summary> /// Calculates the discounts. /// </summary> private void CalculateDiscounts() { PromotionDto promotionDto = PromotionManager.GetPromotionDto(FrameworkContext.Current.CurrentDateTime); if (promotionDto.Promotion.Count == 0) return; // Get current context Dictionary<string, object> context = MarketingContext.Current.MarketingProfileContext; // Parameter that tells if we need to use cached values for promotions or not bool useCache = false; // Constract the filter, ignore conditions for now PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; filter.IgnorePolicy = false; filter.IgnoreSegments = false; filter.IncludeCoupons = false; // Get property OrderGroup order = this.OrderGroup; decimal runningTotal = 0; foreach (OrderForm orderForm in order.OrderForms) { runningTotal += orderForm.LineItems.Where(c => !IsGiftLineItem(c)).Sum(x => x.Quantity * x.PlacedPrice); } // Create Promotion Context PromotionEntriesSet sourceSet = null; // Reuse the same context so we can track exclusivity properly PromotionContext promoContext = new PromotionContext(context, new PromotionEntriesSet(), new PromotionEntriesSet()); promoContext.PromotionResult.RunningTotal = runningTotal; #region Determine Line item level discounts int totalNumberOfItems = 0; // Process line item discounts first foreach (OrderForm form in order.OrderForms) { foreach (OrderFormDiscount discount in form.Discounts) { if (!discount.DiscountName.StartsWith("@")/* && discount.DiscountId == -1*/) // ignore custom entries discount.Delete(); } // Create source from current form sourceSet = CreateSetFromOrderForm(form); // Build dictionary to keep track of entry discount limit Dictionary<PromotionDto.PromotionRow, decimal?> entryDiscountApplicationCount = new Dictionary<PromotionDto.PromotionRow, decimal?>(); foreach (PromotionDto.PromotionRow promotion in promotionDto.Promotion) { if (!promotion.IsMaxEntryDiscountQuantityNull()) { entryDiscountApplicationCount.Add(promotion, promotion.MaxEntryDiscountQuantity); } } // Now cycle through each line item one by one IOrderedEnumerable<LineItem> highPlacedPriceFirst = form.LineItems.ToArray().OrderByDescending(x => x.PlacedPrice); int lineItemCount = highPlacedPriceFirst.Count(); int i = 0; foreach (LineItem lineItem in highPlacedPriceFirst) { i++; // First remove items foreach (LineItemDiscount discount in lineItem.Discounts) { if (!discount.DiscountName.StartsWith("@")/* && discount.DiscountId == -1*/) // ignore custom entries discount.Delete(); } //Exclude gift lineItems from evaluation discounts process if (IsGiftLineItem(lineItem)) { continue; } totalNumberOfItems++; // Target only entry promotions PromotionEntriesSet targetSet = new PromotionEntriesSet(); targetSet.OrderFormId = form.OrderFormId.ToString(); //ET [16.06.2009] If order contains two item with same code, in target hit only first //targetSet.Entries.Add(sourceSet.FindEntryByCode(lineItem.CatalogEntryId)); targetSet.Entries.Add(CreatePromotionEntryFromLineItem(lineItem)); promoContext.SourceEntriesSet = sourceSet; promoContext.TargetEntriesSet = targetSet; promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; // Evaluate conditions bool checkEntryLevelDiscountLimit = i == lineItemCount; MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter, entryDiscountApplicationCount, checkEntryLevelDiscountLimit); // from now on use cache useCache = true; } } #endregion #region Determine Order level discounts foreach (OrderForm form in order.OrderForms) { // Now process global order discounts // Now start processing it // Create source from current form sourceSet = CreateSetFromOrderForm(form); promoContext.SourceEntriesSet = sourceSet; promoContext.TargetEntriesSet = sourceSet; promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key; } // Evaluate conditions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter, null, false); //Removing now not aplyied Gift discounts from Order RemoveGiftPromotionFromOrder(order, promoContext); #endregion #region Determine Shipping Discounts // add shipping fee to RunningTotal after calculating item and order level discounts, in order to apply shipping discounts. foreach (OrderForm orderForm in order.OrderForms) { foreach (Shipment shipment in orderForm.Shipments) { promoContext.PromotionResult.RunningTotal += shipment.ShippingSubTotal; } } foreach (OrderForm form in order.OrderForms) { foreach (Shipment shipment in form.Shipments) { // Remove old discounts if any foreach (ShipmentDiscount discount in shipment.Discounts) { if (!discount.DiscountName.StartsWith("@")/* && discount.DiscountId == -1*/) // ignore custom entries discount.Delete(); } // Create content for current shipment /* sourceSet = CreateSetFromOrderForm(form); promoContext.SourceEntriesSet.Entries = sourceSet.Entries; * */ PromotionEntriesSet targetSet = CreateSetFromShipment(shipment); promoContext.SourceEntriesSet = targetSet; promoContext.TargetEntriesSet = targetSet; promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key; // Evaluate promotions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter, null, false); // Set the total discount for the shipment // shipment.ShippingDiscountAmount = GetDiscountPrice(order, promoContext.PromotionResult); } } #endregion #region Start Applying Discounts foreach (PromotionItemRecord itemRecord in promoContext.PromotionResult.PromotionRecords) { if (itemRecord.Status != PromotionItemRecordStatus.Commited) continue; // Pre process item record PreProcessItemRecord(order, itemRecord); // Applies discount and adjusts the running total if (itemRecord.AffectedEntriesSet.Entries.Count > 0) { var discountAmount = ApplyItemDiscount(order, itemRecord, runningTotal); if (!(itemRecord.PromotionReward is GiftPromotionReward)) { runningTotal -= discountAmount; } } } #endregion #region True up order level discounts (from Mark's fix for Teleflora) decimal orderLevelAmount = 0; decimal lineItemOrderLevelTotal = 0; foreach (OrderForm form in order.OrderForms) { orderLevelAmount += form.Discounts.Cast<OrderFormDiscount>().Where(y => !y.DiscountName.StartsWith("@")).Sum(x => x.DiscountValue); lineItemOrderLevelTotal += form.LineItems.ToArray().Sum(x => x.OrderLevelDiscountAmount); if (orderLevelAmount > lineItemOrderLevelTotal) { form.LineItems[0].OrderLevelDiscountAmount += orderLevelAmount - lineItemOrderLevelTotal; } } #endregion }
/// <summary> /// Calculates the discounts. /// </summary> private void CalculateDiscounts() { // Get current context Dictionary <string, object> context = MarketingContext.Current.MarketingProfileContext; // Parameter that tells if we need to use cached values for promotions or not bool useCache = false; // Constract the filter, ignore conditions for now PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; filter.IgnorePolicy = false; filter.IgnoreSegments = false; filter.IncludeCoupons = false; // Get property OrderGroup order = this.OrderGroup; // Create Promotion Context PromotionEntriesSet sourceSet = null; // Reuse the same context so we can track exclusivity properly PromotionContext promoContext = new PromotionContext(context, new PromotionEntriesSet(), new PromotionEntriesSet()); promoContext.PromotionResult.RunningTotal = order.SubTotal; #region Determine Line item level discounts int totalNumberOfItems = 0; // Process line item discounts first foreach (OrderForm form in order.OrderForms) { foreach (OrderFormDiscount discount in form.Discounts) { if (!discount.DiscountName.StartsWith("@") /* && discount.DiscountId == -1*/) // ignore custom entries { discount.Delete(); } } // Create source from current form sourceSet = CreateSetFromOrderForm(form); // Now cycle through each line item one by one foreach (LineItem lineItem in form.LineItems) { // First remove items foreach (LineItemDiscount discount in lineItem.Discounts) { if (!discount.DiscountName.StartsWith("@") /* && discount.DiscountId == -1*/) // ignore custom entries { discount.Delete(); } } totalNumberOfItems++; // Target only entry promotions PromotionEntriesSet targetSet = new PromotionEntriesSet(); targetSet.OwnerId = form.OrderFormId.ToString(); //ET [16.06.2009] If order contains two item with same code, in target hit only first //targetSet.Entries.Add(sourceSet.FindEntryByCode(lineItem.CatalogEntryId)); targetSet.Entries.Add(CreatePromotionEntryFromLineItem(lineItem)); promoContext.SourceEntriesSet = sourceSet; promoContext.TargetEntriesSet = targetSet; promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; // Evaluate conditions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter); // from now on use cache useCache = true; } } #endregion #region Determine Order level discounts foreach (OrderForm form in order.OrderForms) { // Now process global order discounts // Now start processing it // Create source from current form sourceSet = CreateSetFromOrderForm(form); promoContext.SourceEntriesSet = sourceSet; promoContext.TargetEntriesSet = sourceSet; promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key; } // Evaluate conditions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter); #endregion #region Determine Shipping Discounts foreach (OrderForm form in order.OrderForms) { foreach (Shipment shipment in form.Shipments) { // Remove old discounts if any foreach (ShipmentDiscount discount in shipment.Discounts) { if (!discount.DiscountName.StartsWith("@") /* && discount.DiscountId == -1*/) // ignore custom entries { discount.Delete(); } } // Create content for current shipment /* * sourceSet = CreateSetFromOrderForm(form); * promoContext.SourceEntriesSet.Entries = sourceSet.Entries; * */ PromotionEntriesSet targetSet = CreateSetFromShipment(shipment); promoContext.SourceEntriesSet = targetSet; promoContext.TargetEntriesSet = targetSet; promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key; // Evaluate promotions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter); // Set the total discount for the shipment // shipment.ShippingDiscountAmount = GetDiscountPrice(order, promoContext.PromotionResult); } } #endregion #region Start Applying Discounts decimal runningTotal = order.SubTotal; foreach (PromotionItemRecord itemRecord in promoContext.PromotionResult.PromotionRecords) { if (itemRecord.Status != PromotionItemRecordStatus.Commited) { continue; } // Pre process item record PreProcessItemRecord(order, itemRecord); // Applies discount and adjusts the running total if (itemRecord.AffectedEntriesSet.Entries.Count > 0) { runningTotal -= ApplyItemDiscount(order, itemRecord, runningTotal); } } #endregion }
/// <summary> /// Gets the discount price by evaluating the discount rules and taking into account segments customer belongs to. /// </summary> /// <param name="entry">The entry.</param> /// <param name="catalogName">Name of the catalog.</param> /// <returns></returns> public static Price GetDiscountPrice(Entry entry, string catalogName) { if (entry == null) { throw new NullReferenceException("entry can't be null"); } decimal minQuantity = 1; // get min quantity attribute if (entry.ItemAttributes != null) { minQuantity = entry.ItemAttributes.MinQuantity; } // we can't pass qauntity of 0, so make it default to 1 if (minQuantity <= 0) { minQuantity = 1; } // Get sale price for the current user Price price = StoreHelper.GetSalePrice(entry, minQuantity); // Create new promotion helper, which will initialize PromotionContext object for us and setup context dictionary PromotionHelper helper = new PromotionHelper(); // Get current context Dictionary <string, object> context = MarketingContext.Current.MarketingProfileContext; // Create filter PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; filter.IgnorePolicy = false; filter.IgnoreSegments = false; filter.IncludeCoupons = false; // Create new entry PromotionEntry promotEntry = new PromotionEntry(catalogName, String.Empty, entry.ID, price.Amount); // Populate entry parameters ((IPromotionEntryPopulate)MarketingContext.Current.PromotionEntryPopulateFunctionClassInfo.CreateInstance()).Populate(ref promotEntry, entry); PromotionEntriesSet sourceSet = new PromotionEntriesSet(); sourceSet.Entries.Add(promotEntry); // Configure promotion context helper.PromotionContext.SourceEntriesSet = sourceSet; helper.PromotionContext.TargetEntriesSet = sourceSet; // Only target entries helper.PromotionContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; // Execute the promotions and filter out basic collection of promotions, we need to execute with cache disabled, so we get latest info from the database helper.Eval(filter); // Check the count, and get new price if (helper.PromotionContext.PromotionResult.PromotionRecords.Count > 0) { return(ObjectHelper.CreatePrice(price.Amount - GetDiscountPrice(helper.PromotionContext.PromotionResult), price.CurrencyCode)); } else { return(price); } }
public override PromotionContext Evaluate(PromotionFilter filter, PromotionEntriesSet sourceEntriesSet, PromotionEntriesSet targetEntriesSet, bool checkEntryLevelLimit) { return(null); }
/// <summary> /// Calculates the discounts. /// </summary> private void CalculateDiscounts() { // Update manual discount amount UpdateManualDiscounts(OrderGroup); PromotionDto promotionDto = PromotionManager.GetPromotionDto(FrameworkContext.Current.CurrentDateTime); if (promotionDto.Promotion.Count == 0) { return; } // Get current context Dictionary <string, object> context = MarketingContext.Current.MarketingProfileContext; // Parameter that tells if we need to use cached values for promotions or not bool useCache = false; // Constract the filter, ignore conditions for now PromotionFilter filter = new PromotionFilter(); filter.IgnoreConditions = false; filter.IgnorePolicy = false; filter.IgnoreSegments = false; filter.IncludeCoupons = false; // Get property OrderGroup order = OrderGroup; decimal runningTotal = 0; foreach (OrderForm orderForm in order.OrderForms) { runningTotal += orderForm.LineItems.Where(c => !IsGiftLineItem(c)).Sum(x => x.Quantity * x.PlacedPrice); } // Create Promotion Context PromotionEntriesSet sourceSet = null; // Reuse the same context so we can track exclusivity properly PromotionContext promoContext = new PromotionContext(context, new PromotionEntriesSet(), new PromotionEntriesSet()); promoContext.PromotionResult.RunningTotal = runningTotal; #region Determine Line item level discounts int totalNumberOfItems = 0; // Process line item discounts first foreach (OrderForm form in order.OrderForms) { foreach (OrderFormDiscount discount in form.Discounts) { if (!discount.DiscountName.StartsWith("@") /* && discount.DiscountId == -1*/) // ignore custom entries { discount.Delete(); } } // Create source from current form sourceSet = CreateSetFromOrderForm(form); // Build dictionary to keep track of entry discount limit Dictionary <PromotionDto.PromotionRow, decimal?> entryDiscountApplicationCount = new Dictionary <PromotionDto.PromotionRow, decimal?>(); foreach (PromotionDto.PromotionRow promotion in promotionDto.Promotion) { if (!promotion.IsMaxEntryDiscountQuantityNull()) { entryDiscountApplicationCount.Add(promotion, promotion.MaxEntryDiscountQuantity); } } // Now cycle through each line item one by one IOrderedEnumerable <LineItem> highPlacedPriceFirst = form.LineItems.ToArray().OrderByDescending(x => x.PlacedPrice); int lineItemCount = highPlacedPriceFirst.Count(); List <PromotionEntriesSet> entriesSetCollection = new List <PromotionEntriesSet>(); foreach (LineItem lineItem in highPlacedPriceFirst) { // First remove items foreach (LineItemDiscount discount in lineItem.Discounts) { if (!discount.DiscountName.StartsWith("@") /* && discount.DiscountId == -1*/) // ignore custom entries { discount.Delete(); } } //Exclude gift lineItems from evaluation discounts process if (IsGiftLineItem(lineItem)) { continue; } totalNumberOfItems++; // Target only entry promotions PromotionEntriesSet targetSet = new PromotionEntriesSet(); targetSet.OrderFormId = form.OrderFormId.ToString(); //ET [16.06.2009] If order contains two item with same code, in target hit only first //targetSet.Entries.Add(sourceSet.FindEntryByCode(lineItem.CatalogEntryId)); targetSet.Entries.Add(CreatePromotionEntryFromLineItem(lineItem)); entriesSetCollection.Add(targetSet); } promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key; // Evaluate conditions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter, entryDiscountApplicationCount, sourceSet, entriesSetCollection, null); // from now on use cache useCache = true; } #endregion #region Determine Order level discounts List <PromotionEntriesSet> orderEntriesSetCollection = new List <PromotionEntriesSet>(); foreach (OrderForm form in order.OrderForms) { // Now process global order discounts // Now start processing it // Create source from current form sourceSet = CreateSetFromOrderForm(form); orderEntriesSetCollection.Add(sourceSet); } promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key; // Evaluate conditions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter, null, orderEntriesSetCollection, false); //Removing now not aplyied Gift discounts from Order RemoveGiftPromotionFromOrder(order, promoContext); #endregion #region Determine Shipping Discounts // add shipping fee to RunningTotal after calculating item and order level discounts, in order to apply shipping discounts. foreach (OrderForm orderForm in order.OrderForms) { foreach (Shipment shipment in orderForm.Shipments) { promoContext.PromotionResult.RunningTotal += shipment.ShippingSubTotal; } } foreach (OrderForm form in order.OrderForms) { List <PromotionEntriesSet> shipmentEntriesSetCollection = new List <PromotionEntriesSet>(); foreach (Shipment shipment in form.Shipments) { // Remove old discounts if any foreach (ShipmentDiscount discount in shipment.Discounts) { if (!discount.DiscountName.StartsWith("@") /* && discount.DiscountId == -1*/) // ignore custom entries { discount.Delete(); } } // Create content for current shipment /* * sourceSet = CreateSetFromOrderForm(form); * promoContext.SourceEntriesSet.Entries = sourceSet.Entries; * */ PromotionEntriesSet targetSet = CreateSetFromShipment(shipment); shipmentEntriesSetCollection.Add(targetSet); } promoContext.TargetGroup = PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key; // Evaluate promotions MarketingContext.Current.EvaluatePromotions(useCache, promoContext, filter, null, shipmentEntriesSetCollection, false); } #endregion #region Start Applying Discounts foreach (PromotionItemRecord itemRecord in promoContext.PromotionResult.PromotionRecords) { if (itemRecord.Status != PromotionItemRecordStatus.Commited) { continue; } // Pre process item record PreProcessItemRecord(order, itemRecord); // Applies discount and adjusts the running total if (itemRecord.AffectedEntriesSet.Entries.Count > 0) { var discountAmount = ApplyItemDiscount(order, itemRecord, runningTotal); if (!(itemRecord.PromotionReward is GiftPromotionReward)) { runningTotal -= discountAmount; } } } #endregion #region True up order level discounts (from Mark's fix for Teleflora) decimal orderLevelAmount = 0; decimal lineItemOrderLevelTotal = 0; foreach (OrderForm form in order.OrderForms) { orderLevelAmount += form.Discounts.Cast <OrderFormDiscount>().Where(y => !y.DiscountName.StartsWith("@")).Sum(x => x.DiscountValue); lineItemOrderLevelTotal += form.LineItems.ToArray().Sum(x => x.OrderLevelDiscountAmount); if (orderLevelAmount != lineItemOrderLevelTotal) { form.LineItems[0].OrderLevelDiscountAmount += orderLevelAmount - lineItemOrderLevelTotal; } } #endregion }