Example #1
0
        /// <summary>
        /// Default bind data method.
        /// </summary>
        private void BindData()
        {
            // If Shipment have been created, clear Shipment to continue shopping.
            if (CartHelper.Cart.OrderForms.Count > 0 && CartHelper.Cart.OrderForms[0].Shipments.Count >= 1)
            {
                foreach (Shipment shipment in CartHelper.Cart.OrderForms[0].Shipments)
                {
                    string couponCode = Session[Constants.LastCouponCode] as string;

                    if (!String.IsNullOrEmpty(couponCode))
                    {
                        ShipmentDiscount shipmentDiscountWithCouponCode = shipment.Discounts.Cast <ShipmentDiscount>().FirstOrDefault(x => x.DiscountCode.Equals(couponCode));
                        if (shipmentDiscountWithCouponCode != null)
                        {
                            Session.Remove(Constants.LastCouponCode);
                        }
                    }

                    shipment.Delete();
                }
                foreach (OrderAddress address in CartHelper.Cart.OrderAddresses)
                {
                    address.Delete();
                }
            }

            var isEmpty = CartHelper.IsEmpty;

            if (isEmpty)
            {
                CartHelper.Delete();
            }

            CartHelper.Cart.AcceptChanges();
        }
Example #2
0
        public void OrderSystem_GetPurchaseOrderTest()
        {
            Cart cart = CreateShoppingCart();

            cart.OrderForms[0].LineItems[0].Discounts.Add(OrderHelper.CreateLineItemDiscount());

            ShipmentDiscount discount = new ShipmentDiscount();

            discount.DiscountAmount = 10;
            discount.DiscountId     = 1;
            discount.DiscountName   = "asas";
            discount.DiscountValue  = 10;
            discount.DisplayMessage = "asdasd";


            ShipmentDiscount discount2 = new ShipmentDiscount();

            discount2.DiscountAmount = 10;
            discount2.DiscountId     = 2;
            discount2.DiscountName   = "asas";
            discount2.DiscountValue  = 10;
            discount2.DisplayMessage = "asdasd";


            cart.OrderForms[0].Shipments[0].Discounts.Add(discount);
            cart.OrderForms[0].Shipments[0].Discounts.Add(discount2);

            int cartLineItemDiscountCount = cart.OrderForms[0].LineItems[0].Discounts.Count;

            PurchaseOrder po = cart.SaveAsPurchaseOrder();

            po.AcceptChanges();

            // Reload cart from database
            PurchaseOrder po2 = OrderContext.Current.GetPurchaseOrder(po.CustomerId, po.OrderGroupId);

            int po1ShipmentDiscountsCount = po.OrderForms[0].Shipments[0].Discounts.Count;
            int po2ShipmentDiscountsCount = po2.OrderForms[0].Shipments[0].Discounts.Count;
            int po2LineItemDiscountCount  = po2.OrderForms[0].LineItems[0].Discounts.Count;

            // Now remove discounts and add them again
            foreach (ShipmentDiscount dis in po2.OrderForms[0].Shipments[0].Discounts)
            {
                dis.Delete();
            }

            po2.OrderForms[0].Shipments[0].Discounts.Add(discount);
            po2.OrderForms[0].Shipments[0].Discounts.Add(discount2);
            po2.AcceptChanges();

            // Remove created stuff
            cart.Delete();
            cart.AcceptChanges();
            po2.Delete();
            po2.AcceptChanges();

            Assert.AreEqual(po1ShipmentDiscountsCount, po2ShipmentDiscountsCount);
            Assert.AreEqual(cartLineItemDiscountCount, po2LineItemDiscountCount);
        }
        private void AddDiscountToEntity(StorageEntity entity, PromotionReward reward, decimal discountAmount)
        {
            var orderForm = entity as OrderForm;
            var lineItem  = entity as LineItem;
            var shipment  = entity as Shipment;

            if (orderForm != null && reward is CartSubtotalReward)
            {
                var discount = orderForm.Discounts.FirstOrDefault(x => x.PromotionId == reward.PromotionId);
                if (discount == null)
                {
                    discount = new OrderFormDiscount
                    {
                        PromotionId    = reward.PromotionId,
                        DiscountName   = reward.Promotion.Name,
                        DisplayMessage = reward.Promotion.Description,
                        OrderFormId    = orderForm.OrderFormId,
                        DiscountCode   = reward.Promotion.Coupon != null ? reward.Promotion.Coupon.Code : null
                    };
                    orderForm.Discounts.Add(discount);
                }
                discount.DiscountAmount += discountAmount;
            }
            else if (lineItem != null && reward is CatalogItemReward)
            {
                var discount = lineItem.Discounts.FirstOrDefault(x => x.PromotionId == reward.PromotionId);
                if (discount == null)
                {
                    discount = new LineItemDiscount
                    {
                        PromotionId    = reward.PromotionId,
                        DiscountName   = reward.Promotion.Name,
                        DisplayMessage = reward.Promotion.Description,
                        LineItemId     = lineItem.LineItemId,
                        DiscountCode   = reward.Promotion.Coupon != null ? reward.Promotion.Coupon.Code : null
                    };
                    lineItem.Discounts.Add(discount);
                }
                discount.DiscountAmount += discountAmount;
            }
            else if (shipment != null && reward is ShipmentReward)
            {
                var discount = shipment.Discounts.FirstOrDefault(x => x.PromotionId == reward.PromotionId);
                if (discount == null)
                {
                    discount = new ShipmentDiscount
                    {
                        PromotionId    = reward.PromotionId,
                        DiscountName   = reward.Promotion.Name,
                        DisplayMessage = reward.Promotion.Description,
                        ShipmentId     = shipment.ShipmentId,
                        DiscountCode   = reward.Promotion.Coupon != null ? reward.Promotion.Coupon.Code : null
                    };
                    shipment.Discounts.Add(discount);
                }
                discount.DiscountAmount += discountAmount;
            }
        }
Example #4
0
        /// <summary>
        /// Creates the shipment discount.
        /// </summary>
        /// <returns></returns>
        public static ShipmentDiscount CreateShipmentDiscount()
        {
            ShipmentDiscount discount = new ShipmentDiscount();

            discount.DisplayMessage = "Shipment Discount";
            discount.DiscountName   = "@New Discount";
            discount.DiscountId     = -1;
            discount.DiscountAmount = 12;
            discount.DiscountCode   = "";
            return(discount);
        }
 private bool SkipShipmentRateCalculation(ShipmentDiscount discount)
 {
     string discountName = "@ShipmentSkipRateCalc";
     return discount.DiscountName.Equals(discountName);
 }
        /// <summary>
        /// Applies the item discount.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        /// <param name="totalAmount">The total amount.</param>
        /// <returns></returns>
        private decimal ApplyItemDiscount(OrderGroup order, PromotionItemRecord record, decimal totalAmount)
        {

            decimal discountAmount = 0;
            if (record.PromotionReward.RewardType == PromotionRewardType.AllAffectedEntries)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = record.AffectedEntriesSet.TotalCost * record.PromotionReward.AmountOff / 100;
                    decimal averageDiscountAmount = discountAmount / record.AffectedEntriesSet.TotalQuantity;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        // Sasha: changed back, CostPerEntry does not change dynamically, while total cost does
                        // AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100m, 0);
                        // AddDiscountToLineItem(order, record, entry.CatalogEntryCode, averageDiscountAmount * entry.Quantity, 0);
                        AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                    }
                }
                else // need to split discount between all items
                {
                    discountAmount = record.PromotionReward.AmountOff;
                    decimal averageDiscountAmount = record.PromotionReward.AmountOff / record.AffectedEntriesSet.TotalQuantity;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.EachAffectedEntry)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = record.AffectedEntriesSet.TotalCost * record.PromotionReward.AmountOff / 100;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100, 0);
                    }
                }
                else
                {
                    discountAmount = record.AffectedEntriesSet.TotalQuantity * record.PromotionReward.AmountOff;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, record.PromotionReward.AmountOff * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
            {
                decimal percentageOffTotal = 0;
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    decimal extendedCost = 0;
                    foreach (OrderForm orderForm in order.OrderForms)
                    {
                        extendedCost += orderForm.LineItems.ToArray().Sum(x => x.ExtendedPrice);
                    }
                    // calculate percentage adjusted by the running amount, so it will be a little less if running amount is less than total
                    percentageOffTotal = (record.PromotionReward.AmountOff / 100) * (totalAmount / extendedCost);
                    //percentageOffTotal = PromotionReward.AmountOff / 100;
                    discountAmount = totalAmount * record.PromotionReward.AmountOff / 100;
                }
                else
                {
                    // Calculate percentage off discount price
                    if (totalAmount > 0)
                    {
                        percentageOffTotal = record.PromotionReward.AmountOff / totalAmount;
                        // but since CostPerEntry is not an adjusted price, we need to take into account additional discounts already applied
                        percentageOffTotal = percentageOffTotal * (totalAmount / record.AffectedEntriesSet.TotalCost);
                    }
                    else
                    {
                        percentageOffTotal = 100m;
                    }

                    discountAmount = record.PromotionReward.AmountOff;
                }

                // Now distribute discount amount evenly over all entries taking into account running total
                // Special case for shipments, we consider WholeOrder to be a shipment
                if (!record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
                {
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem item = FindLineItemByPromotionEntry(order, entry);
                        AddDiscountToLineItem(order, record, entry, 0, item.ExtendedPrice * percentageOffTotal);
                    }
                }
            }

            // Save discounts
            if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key, StringComparison.OrdinalIgnoreCase)
                || record.PromotionReward is GiftPromotionReward)
            {
                if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
                {
                    OrderFormDiscount discount = FindOrderFormDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.OrderFormId));
                    bool hasOrderFormDiscount = true;
                    if (discount == null)
                    {
                        discount = new OrderFormDiscount();
                        hasOrderFormDiscount = false;
                    }

                    var discountName = record.PromotionItem.DataRow.Name;
                    if (record.PromotionReward is GiftPromotionReward)
                    {
                        discountName = GetGiftPromotionName(record);
                    }
                    discount.DiscountName = discountName;

                    discount.DiscountAmount = record.PromotionReward.AmountOff;
                    discount.DiscountCode = record.PromotionItem.DataRow.CouponCode;
                    discount.DiscountValue = hasOrderFormDiscount ? discountAmount + discount.DiscountValue : discountAmount;
                    discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                    discount.OrderFormId = Int32.Parse(record.AffectedEntriesSet.OrderFormId);
                    discount.DiscountId = record.PromotionItem.DataRow.PromotionId;

                    foreach (OrderForm form in order.OrderForms)
                    {
                        if (form.OrderFormId == discount.OrderFormId && !hasOrderFormDiscount)
                            form.Discounts.Add(discount);
                    }
                }
            }
            else if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
            {
                ShipmentDiscount discount = FindShipmentDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.ShipmentId));

                if (discount == null)
                    discount = new ShipmentDiscount();

                discount.DiscountAmount = record.PromotionReward.AmountOff;
                discount.DiscountCode = record.PromotionItem.DataRow.CouponCode;
                discount.DiscountName = record.PromotionItem.DataRow.Name;
                discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                discount.ShipmentId = Int32.Parse(record.AffectedEntriesSet.ShipmentId);
                discount.DiscountId = record.PromotionItem.DataRow.PromotionId;

                foreach (OrderForm form in order.OrderForms)
                {
                    foreach (Shipment shipment in form.Shipments)
                    {
                        if (shipment.ShipmentId == discount.ShipmentId)
                        {
                            shipment.Discounts.Add(discount);

                            if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                            {
                                discountAmount = shipment.ShippingSubTotal * record.PromotionReward.AmountOff / 100;
                            }
                            else
                            {
                                discountAmount = Math.Min(record.PromotionReward.AmountOff, shipment.ShippingSubTotal);
                            }

                            shipment.ShippingDiscountAmount = Math.Min(shipment.ShippingDiscountAmount + discountAmount, shipment.ShippingSubTotal);
                            // ShippingDiscountAmount will not be subtracted from the ShipmentTotal per discussions on 2/22/2012.
                            break;
                        }
                    }
                }
                discount.DiscountValue = discountAmount;
            }
            return discountAmount;
        }
Example #7
0
        /// <summary>
        /// Applies the item discount.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        /// <param name="totalAmount">The total amount.</param>
        /// <returns></returns>
        private decimal ApplyItemDiscount(OrderGroup order, PromotionItemRecord record, decimal totalAmount)
        {
            decimal discountAmount = 0;

            if (record.PromotionReward.RewardType == PromotionRewardType.AllAffectedEntries)
            {
                decimal averageDiscountAmount;
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount        = _currency.Percentage(record.AffectedEntriesSet.TotalCost, record.PromotionReward.AmountOff);
                    averageDiscountAmount = discountAmount / record.AffectedEntriesSet.TotalQuantity;
                }
                else // need to split discount between all items
                {
                    discountAmount        = record.PromotionReward.AmountOff;
                    averageDiscountAmount = record.PromotionReward.AmountOff / record.AffectedEntriesSet.TotalQuantity;
                }

                foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                {
                    AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.EachAffectedEntry)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = _currency.Percentage(record.AffectedEntriesSet.TotalCost, record.PromotionReward.AmountOff);
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100, 0);
                    }
                }
                else
                {
                    discountAmount = record.AffectedEntriesSet.TotalQuantity * record.PromotionReward.AmountOff;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, record.PromotionReward.AmountOff * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
            {
                decimal percentageOffTotal = 0;
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    decimal extendedCost = 0;
                    foreach (OrderForm orderForm in order.OrderForms)
                    {
                        extendedCost += orderForm.LineItems.ToArray().Sum(x => x.ExtendedPrice);
                    }
                    // calculate percentage adjusted by the running amount, so it will be a little less if running amount is less than total
                    percentageOffTotal = (record.PromotionReward.AmountOff / 100) * (totalAmount / extendedCost);
                    discountAmount     = _currency.Percentage(totalAmount, record.PromotionReward.AmountOff);
                }
                else
                {
                    // Calculate percentage off discount price
                    if (totalAmount > 0)
                    {
                        percentageOffTotal = record.PromotionReward.AmountOff / totalAmount;
                        // but since CostPerEntry is not an adjusted price, we need to take into account additional discounts already applied
                        percentageOffTotal = percentageOffTotal * (totalAmount / record.AffectedEntriesSet.TotalCost);
                        discountAmount     = record.PromotionReward.AmountOff;
                    }
                    else
                    {
                        percentageOffTotal = 100m;
                        discountAmount     = 0;
                    }
                }

                // Now distribute discount amount evenly over all entries taking into account running total
                // Special case for shipments, we consider WholeOrder to be a shipment
                if (!record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
                {
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem item = FindLineItemByPromotionEntry(order, entry);
                        var      orderLevelDiscount = _currency.Round(item.ExtendedPrice * percentageOffTotal);
                        AddDiscountToLineItem(order, record, entry, 0, orderLevelDiscount);
                    }
                }
            }

            // Save discounts
            if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key, StringComparison.OrdinalIgnoreCase) ||
                record.PromotionReward is GiftPromotionReward)
            {
                if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder && discountAmount > 0)
                {
                    OrderFormDiscount discount = FindOrderFormDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.OrderFormId));
                    bool hasOrderFormDiscount  = true;
                    if (discount == null)
                    {
                        discount             = new OrderFormDiscount();
                        hasOrderFormDiscount = false;
                    }

                    var discountName = record.PromotionItem.DataRow.Name;
                    if (record.PromotionReward is GiftPromotionReward)
                    {
                        discountName = GetGiftPromotionName(record);
                    }
                    discount.DiscountName = discountName;

                    discount.DiscountAmount = record.PromotionReward.AmountOff;
                    discount.DiscountCode   = record.PromotionItem.DataRow.CouponCode;
                    discount.DiscountValue  = hasOrderFormDiscount ? discountAmount + discount.DiscountValue : discountAmount;
                    discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                    discount.OrderFormId    = Int32.Parse(record.AffectedEntriesSet.OrderFormId);
                    discount.DiscountId     = record.PromotionItem.DataRow.PromotionId;

                    foreach (OrderForm form in order.OrderForms)
                    {
                        if (form.OrderFormId == discount.OrderFormId && !hasOrderFormDiscount)
                        {
                            form.Discounts.Add(discount);
                        }
                    }
                }
            }
            else if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
            {
                ShipmentDiscount discount = FindShipmentDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.ShipmentId));

                if (discount == null)
                {
                    discount = new ShipmentDiscount();
                }

                discount.DiscountAmount = record.PromotionReward.AmountOff;
                discount.DiscountCode   = record.PromotionItem.DataRow.CouponCode;
                discount.DiscountName   = record.PromotionItem.DataRow.Name;
                discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                discount.ShipmentId     = Int32.Parse(record.AffectedEntriesSet.ShipmentId);
                discount.DiscountId     = record.PromotionItem.DataRow.PromotionId;

                var shipment = order.OrderForms.SelectMany(o => o.Shipments).FirstOrDefault(s => s.ShipmentId == discount.ShipmentId);
                if (shipment != null)
                {
                    shipment.Discounts.Add(discount);

                    if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                    {
                        discountAmount = _currency.Percentage(shipment.ShippingSubTotal, record.PromotionReward.AmountOff);
                    }
                    else
                    {
                        // PromotionReward.AmountOff was calculated in Promotion context, it's not be rounded.
                        discountAmount = _currency.Round(Math.Min(record.PromotionReward.AmountOff, shipment.ShippingSubTotal));
                    }

                    shipment.ShippingDiscountAmount = Math.Min(shipment.ShippingDiscountAmount + discountAmount, shipment.ShippingSubTotal);
                    // ShippingDiscountAmount will not be subtracted from the ShipmentTotal per discussions on 2/22/2012.
                }
                discount.DiscountValue = discountAmount;
            }
            return(discountAmount);
        }
Example #8
0
        /// <summary>
        /// Applies the item discount.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        /// <param name="totalAmount">The total amount.</param>
        /// <returns></returns>
        private decimal ApplyItemDiscount(OrderGroup order, PromotionItemRecord record, decimal totalAmount)
        {
            decimal discountAmount = 0;

            if (record.PromotionReward.RewardType == PromotionRewardType.AllAffectedEntries)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = record.AffectedEntriesSet.TotalCost * record.PromotionReward.AmountOff / 100;
                    decimal averageDiscountAmount = discountAmount / record.AffectedEntriesSet.TotalQuantity;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        // Sasha: changed back, CostPerEntry does not change dynamically, while total cost does
                        // AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100m, 0);
                        // AddDiscountToLineItem(order, record, entry.CatalogEntryCode, averageDiscountAmount * entry.Quantity, 0);
                        AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                    }
                }
                else // need to split discount between all items
                {
                    discountAmount = record.PromotionReward.AmountOff;
                    decimal averageDiscountAmount = record.PromotionReward.AmountOff / record.AffectedEntriesSet.TotalQuantity;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.EachAffectedEntry)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = record.AffectedEntriesSet.TotalCost * record.PromotionReward.AmountOff / 100;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100, 0);
                    }
                }
                else
                {
                    discountAmount = record.AffectedEntriesSet.TotalQuantity * record.PromotionReward.AmountOff;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, record.PromotionReward.AmountOff * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
            {
                decimal percentageOffTotal = 0;
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    // calculate percentage adjusted by the running amount, so it will be a little less if running amount is less than total
                    percentageOffTotal = (record.PromotionReward.AmountOff / 100) * (totalAmount / record.AffectedEntriesSet.TotalCost);
                    //percentageOffTotal = PromotionReward.AmountOff / 100;
                    discountAmount = totalAmount * record.PromotionReward.AmountOff / 100;
                }
                else
                {
                    // Calculate percentage off discount price
                    percentageOffTotal = record.PromotionReward.AmountOff / totalAmount;

                    // but since CostPerEntry is not an adjusted price, we need to take into account additional discounts already applied
                    percentageOffTotal = percentageOffTotal * (totalAmount / record.AffectedEntriesSet.TotalCost);

                    discountAmount = record.PromotionReward.AmountOff;
                }

                // Now distribute discount amount evenly over all entries taking into account running total
                // Special case for shipments, we consider WholeOrder to be a shipment
                if (!record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
                {
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, 0, (((entry.CostPerEntry * entry.Quantity) /* - entry.Discount*/)) * percentageOffTotal);
                    }
                }
            }

            // Save discounts
            if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key, StringComparison.OrdinalIgnoreCase) ||
                record.PromotionReward is GiftPromotionReward)
            {
                if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
                {
                    OrderFormDiscount discount = FindOrderFormDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.OrderFormId));
                    bool hasOrderFormDiscount  = true;
                    if (discount == null)
                    {
                        discount             = new OrderFormDiscount();
                        hasOrderFormDiscount = false;
                    }

                    var discountName = record.PromotionItem.DataRow.Name;
                    if (record.PromotionReward is GiftPromotionReward)
                    {
                        discountName = GetGiftPromotionName(record);
                    }
                    discount.DiscountName = discountName;

                    discount.DiscountAmount = record.PromotionReward.AmountOff;
                    discount.DiscountCode   = record.PromotionItem.DataRow.CouponCode;
                    discount.DiscountValue  = hasOrderFormDiscount ? discountAmount + discount.DiscountValue : discountAmount;
                    discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                    discount.OrderFormId    = Int32.Parse(record.AffectedEntriesSet.OrderFormId);
                    discount.DiscountId     = record.PromotionItem.DataRow.PromotionId;

                    foreach (OrderForm form in order.OrderForms)
                    {
                        if (form.OrderFormId == discount.OrderFormId && !hasOrderFormDiscount)
                        {
                            form.Discounts.Add(discount);
                        }
                    }
                }
            }
            else if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
            {
                ShipmentDiscount discount = FindShipmentDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.ShipmentId));

                if (discount == null)
                {
                    discount = new ShipmentDiscount();
                }

                discount.DiscountAmount = record.PromotionReward.AmountOff;
                discount.DiscountCode   = record.PromotionItem.DataRow.CouponCode;
                discount.DiscountName   = record.PromotionItem.DataRow.Name;
                discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                discount.ShipmentId     = Int32.Parse(record.AffectedEntriesSet.ShipmentId);
                discount.DiscountId     = record.PromotionItem.DataRow.PromotionId;

                foreach (OrderForm form in order.OrderForms)
                {
                    foreach (Shipment shipment in form.Shipments)
                    {
                        if (shipment.ShipmentId == discount.ShipmentId)
                        {
                            shipment.Discounts.Add(discount);

                            if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                            {
                                discountAmount = shipment.ShipmentTotal * record.PromotionReward.AmountOff / 100;
                            }
                            else
                            {
                                discountAmount = Math.Min(record.PromotionReward.AmountOff, shipment.ShipmentTotal);
                            }

                            shipment.ShippingDiscountAmount += discountAmount;
                            // ShippingDiscountAmount will not be subtracted from the ShipmentTotal per discussions on 2/22/2012.
                            break;
                        }
                    }
                }
                discount.DiscountValue = discountAmount;
            }
            return(discountAmount);
        }