Exemplo n.º 1
0
        public RewardsAccount CalculatePointsAccount(IList <Product> products)
        {
            var appliedAmount = 0M;

            if (IsRewardPointsAccount)
            {
                var pointAccountResponse = Exigo.GetCustomerPointAccount(CustomerId, RewardPointsAccountId.Value);

                var creditsRemaining = (null != pointAccountResponse ? pointAccountResponse.Balance : 0M);

                var productWithDiscount = GetRewardProducts(products);
                foreach (var product in productWithDiscount)
                {
                    if (product.Quantity < product.Discounts.Count)
                    {
                        throw new ApplicationException("Number of discounts applied cannot exceed the number of products.");
                    }

                    appliedAmount += product.Discounts.Where(discount => discount.DiscountType == DiscountType.RecruitingReward).Sum(discount => discount.AppliedAmount);
                }

                RewardsAccount account = new RewardsAccount {
                    PointAccountID = RewardPointsAccountId.Value, Balance = creditsRemaining, AppliedAmount = appliedAmount
                };

                return(account);
            }
            return(null);
        }
        public virtual bool AllowAddToCart(Item rewardProduct, List <IShoppingCartItem> productsInShoppingCart)
        {
            var rewardProducts = GetRewardProducts(productsInShoppingCart);

            if (rewardProducts.Select(p => p.ItemCode).Contains(rewardProduct.ItemCode))
            {
                // The same product cannot be added to the cart multiple times with this reward applied
                return(false);
            }


            if (IsRewardPointsAccount)
            {
                RewardsAccount rewardsAccount = CalculatePointsAccount(productsInShoppingCart);

                if (rewardsAccount.AmountRemaining <= 0)
                {
                    // A credit must be available to apply a reward to a another product
                    return(false);
                }
            }

            List <string> alreadyPurchasedItemCodes = PurchasedItemCodes();

            alreadyPurchasedItemCodes.AddRange(productsInShoppingCart.Select(i => i.ItemCode).ToList());
            if (alreadyPurchasedItemCodes.Contains(rewardProduct.ItemCode))
            {
                // This product has already been purchased in a previuos order
                return(false);
            }

            return(true);
        }
 public PremiumTier(
     int pointsBalance,
     RewardsAccount account,
     ISendsEmails emailer) : base(emailer)
 {
     PointBalance = pointsBalance;
     Account      = account;
     Initialize();
 }
        /// <summary>
        /// This method verifies an order is valid to be submitted in regards to the reward.  An exception is thrown if the order is invalid.
        /// </summary>
        public void VerifyOrderIsValid(IOrder order)
        {
            IList <Product> rewardProducts = GetRewardProducts(order.Products);

            if (rewardProducts.Count() > 0)
            {
                if (CustomerId == 0)
                {
                    throw new ApplicationException("CustomerId cannot be zero");
                }

                // All products must be eligible for half off
                IEnumerable <Product> productsNotEligibleHalfOff = rewardProducts.Where(p => !p.HalfOffRewardsCreditsEligible);
                if (productsNotEligibleHalfOff.Count() > 0)
                {
                    throw new ApplicationException(string.Format("{0} is not not eligible for half off credit", productsNotEligibleHalfOff.First().Description));
                }

                // Quantities greater than one cannot be purchased using the reward
                IEnumerable <Product> productsWithMultipleRewards = rewardProducts.Where(p => p.Discounts.Where(d => d.DiscountType == RewardHalfOffDiscountType).Count() > 1);

                if (productsWithMultipleRewards.Count() > 1)
                {
                    throw new ApplicationException("Half Off Discount cannot be applied multiple times to the same product.");
                }

                if (IsRewardPointsAccount)
                {
                    // Credits cannot be exceeded (one credit per product purchased with this reward)
                    RewardsAccount rewardsAccount = CalculatePointsAccount(order.Products);

                    if (rewardsAccount.AmountRemaining < 0)
                    {
                        throw new ApplicationException("You've exceeded your rewards balance");
                    }
                }

                // Product could not have been purchased before using this reward
                var previouslyPurchasedItemCodes = PurchasedItemCodes();

                IEnumerable <Product> alreadyPurchasedProducts = order.Products.Where(p => previouslyPurchasedItemCodes.Contains(p.ItemCode));

                if (alreadyPurchasedProducts.Count() > 0)
                {
                    throw new ApplicationException(string.Format("{0} has already been purchased with this reward", alreadyPurchasedProducts.First().Description));
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// This method calculates the points account for this reward.
        /// </summary>
        public RewardsAccount CalculatePointsAccount(IList <Product> productsInShoppingCart)
        {
            if (IsRewardPointsAccount)
            {
                var pointAccountResponse = Exigo.GetCustomerPointAccount(CustomerId, RewardPointsAccountId.Value);

                var creditsRemaining = (null != pointAccountResponse ? pointAccountResponse.Balance : 0M);

                var productWithDiscount = GetRewardProducts(productsInShoppingCart);

                var account = new RewardsAccount {
                    PointAccountID = RewardPointsAccountId.Value, Balance = creditsRemaining, AppliedAmount = productWithDiscount.Count()
                };

                return(account);
            }

            return(null);
        }
Exemplo n.º 6
0
        static void Main()
        {
            var logger  = new ConsoleLogger();
            var emailer = new Emailer(logger);

            logger.LogInfo("☕ Welcome to the Cafe Rewards Program");
            logger.LogInfo("--------------------------------------");

            // Sign up for the Rewards Program
            var rewards = new RewardsAccount(logger, emailer, "Katrina");

            logger.LogInfo("Simulating Customer Activity");
            logger.LogInfo("--------------------------------------");
            // Simulate Customer Activity
            rewards.OnPurchase(1);
            rewards.OnPurchase(1);
            rewards.OnPurchase(1);
            rewards.OnPurchase(1);
            rewards.UsePoints(2);
            rewards.UsePoints(1);
        }
Exemplo n.º 7
0
        // TODO: This method can replace the other AddToCart method once it's implemented.
        protected ActionResult AddToCart(Product product, Discount discount = null, IIndividualReward reward = null, Event @event = null)
        {
            var shoppingCart = GetShoppingCart();

            try
            {
                while (product.Discounts.Any())
                {
                    product.UnapplyDiscount(product.Discounts.First());
                }

                // Add the product to the order.
                var p = product.AddToOrder(shoppingCart);

                RewardsAccount pointAccount = null;

                // Validate that the discount can be applied
                // to the product using our validator.
                if (null != discount)
                {
                    bool eventAllowsDiscount  = shoppingCart.ShopperIsHost || shoppingCart.ShopperIsEventSa; // || shoppingCart.ShopperIsBookingRewardsOwner;
                    bool rewardAllowsDiscount = reward != null && reward.IsRewardDiscount(discount) && reward.AllowAddToCart(product, shoppingCart.Products);

                    if ((eventAllowsDiscount || rewardAllowsDiscount) && DiscountValidator.IsValidFor(discount, p, @event))
                    {
                        // TODO: Need to find a better way to map discounts and which point accounts
                        // are deducted based on the discount.
                        switch (discount.DiscountType)
                        {
                        case DiscountType.RewardsCash:
                            pointAccount            = shoppingCart.GetRewardsAccount(PointAccounts.HostRewardsCash);
                            discount.DiscountAmount = pointAccount.AmountRemaining;
                            break;

                        case DiscountType.RecruitingReward:
                            pointAccount            = shoppingCart.GetRewardsAccount(PointAccounts.RecruitingRewards);
                            discount.DiscountAmount = pointAccount.AmountRemaining;
                            break;

                        case DiscountType.EnrolleeReward:
                            pointAccount            = shoppingCart.GetRewardsAccount(PointAccounts.EnrolleeRewards);
                            discount.DiscountAmount = pointAccount.AmountRemaining;
                            break;

                        case DiscountType.HalfOffCredits:
                            pointAccount = shoppingCart.GetRewardsAccount(PointAccounts.Host12offcredits);
                            break;

                        //case DiscountType.BookingRewards:
                        //    pointAccount = shoppingCart.GetRewardsAccount(PointAccounts.BookingsRewardsCash);
                        //    discount.DiscountAmount = pointAccount.AmountRemaining;
                        //    break;
                        case DiscountType.HostSpecial:
                            // TODO: Look into why DI is broken on AJAX calls, seemingly.
                            var hostSpecialReward = new RewardService().GetHostSpecialReward(shoppingCart.EventId.Value);
                            // TODO: Need to validate that the discount exceeds the sales threshold in an IDiscountValidator
                            discount.DiscountAmount = hostSpecialReward.DiscountAmount;
                            break;

                        case DiscountType.Unknown:
                            break;

                        case DiscountType.Fixed:
                            break;

                        case DiscountType.Percent:
                            break;

                        case DiscountType.EBRewards:
                            break;

                        case DiscountType.SAHalfOff:
                            break;

                        case DiscountType.SAHalfOffOngoing:
                            break;

                        case DiscountType.NewProductsLaunchReward:
                            break;

                        case DiscountType.RetailPromoFixed:
                            break;

                        case DiscountType.RetailPromoPercent:
                            break;

                        case DiscountType.PromoCode:
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        if ((pointAccount == null && discount.DiscountAmount > 0M) || (pointAccount != null && pointAccount.AmountRemaining > 0M))
                        {
                            p.ApplyDiscount(discount);
                        }
                        else
                        {
                            // TODO: Need implement error handling at the client for JSON response
                            //ModelState.AddModelError("RewardsError", "The applied rewards amount exceeds the current balance.");
                        }
                    }
                }

                return(new JsonNetResult(new
                {
                    status = 200, cart = shoppingCart
                }));
            }
            catch (Exception)
            {
                return(new JsonNetResult(new
                {
                    status = 500, cart = shoppingCart
                }));
            }
        }