Esempio n. 1
0
        /// <summary>
        /// Attempts to add the coupons discounts to the invoice
        /// </summary>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <returns>
        /// The <see cref="Attempt"/>.
        /// </returns>
        public override Attempt <IInvoice> PerformTask(IInvoice value)
        {
            // check if there are any coupon offers
            if (!this.SalePreparation.OfferCodes.Any())
            {
                return(Attempt <IInvoice> .Succeed(value));
            }

            if (!(this.SalePreparation is IBasketSalePreparation))
            {
                return(Attempt <IInvoice> .Fail(value, new InvalidCastException("SalePreparation object is not IBasketSalePreparation")));
            }
            this._basketSalePreparation = this.SalePreparation as IBasketSalePreparation;

            foreach (var code in this.SalePreparation.OfferCodes)
            {
                var foundCoupon = this.CouponOfferManager.GetByOfferCode(code, this.SalePreparation.Customer);
                if (!foundCoupon.Success)
                {
                    continue;
                }

                var coupon = foundCoupon.Result;
                var clone  = LineItemExtensions.CreateNewItemCacheLineItemContainer(value.Items.Where(x => x.LineItemType != LineItemType.Tax));
                var apply  = coupon.TryApply(clone, this.SalePreparation.Customer).AsCouponRedemptionResult(coupon);
                if (apply.Success)
                {
                    this.CouponOfferManager.SafeAddCouponAttemptContainer <InvoiceLineItem>(value, apply, true);
                }
            }

            return(Attempt <IInvoice> .Succeed(value));
        }
Esempio n. 2
0
        /// <summary>
        /// Attempts to add the coupons discounts to the invoice
        /// </summary>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <returns>
        /// The <see cref="Attempt"/>.
        /// </returns>
        public override Attempt <IInvoice> PerformTask(IInvoice value)
        {
            // check if there are any coupon offers
            if (!this.CheckoutManager.Offer.OfferCodes.Any())
            {
                return(Attempt <IInvoice> .Succeed(value));
            }

            foreach (var code in this.CheckoutManager.Offer.OfferCodes)
            {
                var foundCoupon = this.CouponOfferManager.GetByOfferCode(code, this.CheckoutManager.Context.Customer);
                if (!foundCoupon.Success)
                {
                    continue;
                }

                var coupon = foundCoupon.Result;
                var clone  = LineItemExtensions.CreateNewItemCacheLineItemContainer(value.Items.Where(x => x.LineItemType != LineItemType.Tax));
                var apply  = coupon.TryApply(clone, this.CheckoutManager.Context.Customer).AsCouponRedemptionResult(coupon);
                if (apply.Success)
                {
                    this.CouponOfferManager.SafeAddCouponAttemptContainer <InvoiceLineItem>(value, apply, true);
                }
            }

            return(Attempt <IInvoice> .Succeed(value));
        }
        /// <summary>
        /// Tries to apply the discount line item reward
        /// </summary>
        /// <param name="validate">
        /// The <see cref="ILineItemContainer"/> to validate against
        /// </param>
        /// <param name="customer">
        /// The customer.
        /// </param>
        /// <returns>
        /// The <see cref="Attempt{ILinetItem}"/>.
        /// </returns>
        public override Attempt <ILineItem> TryAward(ILineItemContainer validate, ICustomerBase customer)
        {
            if (!IsConfigured)
            {
                return(Attempt <ILineItem> .Fail(new OfferRedemptionException("The coupon reward is not configured.")));
            }
            if (MerchelloContext.Current == null)
            {
                return(Attempt <ILineItem> .Fail(new OfferRedemptionException("The MerchelloContext was null")));
            }

            // apply to the entire collection excluding previously added discounts
            var qualifying =
                LineItemExtensions.CreateNewItemCacheLineItemContainer(validate.Items.Where(x => x.LineItemType != LineItemType.Discount));

            var visitor = new CouponDiscountLineItemRewardVisitor(Amount, AdjustmentType);

            qualifying.Items.Accept(visitor);

            var qualifyingTotal = visitor.QualifyingTotal;


            var discount = this.AdjustmentType == Adjustment.Flat
                                    ? this.Amount > qualifyingTotal ? qualifyingTotal : this.Amount
                                    : qualifyingTotal * (this.Amount / 100);

            // Get the item template
            var discountLineItem = CreateTemplateDiscountLineItem(visitor.Audits);

            discountLineItem.ExtendedData.SetValue(Core.Constants.ExtendedDataKeys.CouponAdjustedProductPreTaxTotal, visitor.AdjustedProductPreTaxTotal.ToString(CultureInfo.InvariantCulture));
            discountLineItem.ExtendedData.SetValue(Core.Constants.ExtendedDataKeys.CouponAdjustedProductTaxTotal, visitor.AdjustedTaxTotal.ToString(CultureInfo.InvariantCulture));
            discountLineItem.Price = discount;

            return(Attempt <ILineItem> .Succeed(discountLineItem));
        }
        /// <summary>
        /// Attempts to add a coupon offer to the sale.
        /// </summary>
        /// <param name="offerCode">
        /// The offer code.
        /// </param>
        /// <returns>
        /// The <see cref="ICouponRedemptionResult"/>.
        /// </returns>
        public ICouponRedemptionResult RedeemCouponOffer(string offerCode)
        {
            var couponAttempt = this.GetCouponAttempt(offerCode);

            if (!couponAttempt)
            {
                return(new CouponRedemptionResult(couponAttempt.Exception));
            }

            var coupon = couponAttempt.Result;

            var validationItems = this.PrepareInvoice();
            var result          = TryApplyOffer <ILineItemContainer, ILineItem>(LineItemExtensions.CreateNewItemCacheLineItemContainer(validationItems.Items.Where(x => x.LineItemType != LineItemType.Tax)), offerCode).AsCouponRedemptionResult(coupon);

            if (!result.Success)
            {
                return(result);
            }

            // check if there are any previously added coupons and if so revalidate them with the new coupon added.
            // Use case:  First coupon added has the "not usable with other coupons constraint" and then a second coupon is added.
            // In this case the first coupon needs to be revalidated.  If the attempt to apply the coupon again fails, the one currently
            // being added needs to fail.
            if (OfferCodes.Any())
            {
                // Now we have to revalidate any existing coupon offers to make sure the newly approved ones will still be valid.
                var clone = this.CreateNewLineContainer(ItemCache.Items.Where(x => x.LineItemType != LineItemType.Discount));

                _couponManager.Value.SafeAddCouponAttemptContainer <ItemCacheLineItem>(clone, result);
                ICouponRedemptionResult redemption = new CouponRedemptionResult(result.Award, result.Messages);

                foreach (var oc in OfferCodes)
                {
                    redemption = DoTryApplyOffer <ILineItemContainer, ILineItem>(clone, oc).AsCouponRedemptionResult(coupon);
                    if (!redemption.Success)
                    {
                        if (redemption.Messages.Any())
                        {
                            result.AddMessage(redemption.Messages);
                        }

                        result.Exception = redemption.Exception;
                        result.Success   = false;
                        break;
                    }

                    _couponManager.Value.SafeAddCouponAttemptContainer <ItemCacheLineItem>(clone, result);
                }

                if (!redemption.Success)
                {
                    return(redemption);
                }
            }

            this.SaveOfferCode(offerCode);

            return(result);
        }
 /// <summary>
 /// Creates a new <see cref="ILineItemContainer"/> with filtered items.
 /// </summary>
 /// <param name="filteredItems">
 /// The line items.
 /// </param>
 /// <returns>
 /// The <see cref="ILineItemContainer"/>.
 /// </returns>
 internal ILineItemContainer CreateNewLineContainer(IEnumerable <ILineItem> filteredItems)
 {
     return(LineItemExtensions.CreateNewItemCacheLineItemContainer(filteredItems));
 }