/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); var spentAmountRequirement = _settingService.GetSettingByKey<decimal>(string.Format("DiscountRequirement.HadSpentAmount-{0}", request.DiscountRequirement.Id)); if (spentAmountRequirement == decimal.Zero) return true; if (request.Customer == null || request.Customer.IsGuest()) return false; //var orders = _orderService.SearchOrders(storeId: request.Store.Id, // customerId: request.Customer.Id, // os: OrderStatus.Complete); //decimal spentAmount = orders.Sum(o => o.OrderTotal); decimal spentAmount = 0; foreach (ShoppingCartItem item in request.Customer.ShoppingCartItems) { spentAmount = spentAmount + (item.Quantity * item.Product.Price); } return spentAmount > spentAmountRequirement; // return true; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (String.IsNullOrWhiteSpace(request.DiscountRequirement.RestrictedProductVariantIds)) return true; if (request.Customer == null) return false; var restrictedProductVariantIds = new List<int>(); try { restrictedProductVariantIds = request.DiscountRequirement.RestrictedProductVariantIds .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => Convert.ToInt32(x)) .ToList(); } catch { //error parsing return false; } if (restrictedProductVariantIds.Count == 0) return false; //purchased products var purchasedProductVariants = _orderService.GetAllOrderProductVariants(0, request.Customer.Id, null, null, OrderStatus.Complete, null, null); bool allFound = true; foreach (var restrictedPvId in restrictedProductVariantIds) { bool found1 = false; foreach (var purchasedPv in purchasedProductVariants) { if (restrictedPvId == purchasedPv.ProductVariantId) { found1 = true; break; } } if (!found1) { allFound = false; break; } } if (allFound) return true; return false; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (String.IsNullOrWhiteSpace(request.DiscountRequirement.RestrictedProductVariantIds)) return true; if (request.Customer == null) return false; var restrictedProductVariantIds = new List<int>(); try { restrictedProductVariantIds = request.DiscountRequirement.RestrictedProductVariantIds .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => Convert.ToInt32(x)) .ToList(); } catch { //error parsing return false; } if (restrictedProductVariantIds.Count == 0) return false; //cart var cart = request.Customer.ShoppingCartItems.Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart); bool allFound = true; foreach (var restrictedPvId in restrictedProductVariantIds) { bool found1 = false; foreach (var sci in cart) { if (restrictedPvId == sci.ProductVariantId) { found1 = true; break; } } if (!found1) { allFound = false; break; } } if (allFound) return true; return false; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (request.DiscountRequirement.SpentAmount == decimal.Zero) return true; if (request.Customer == null || request.Customer.IsGuest()) return false; var orders = request.Customer.Orders.Where(o => !o.Deleted && o.OrderStatus == OrderStatus.Complete); decimal spentAmount = orders.Sum(o => o.OrderTotal); return spentAmount > request.DiscountRequirement.SpentAmount; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (request.Customer == null) return false; var storeId = _settingService.GetSettingByKey<int>(string.Format("DiscountRequirement.Store-{0}", request.DiscountRequirement.Id)); if (storeId == 0) return false; bool result = request.Store.Id == storeId; return result; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (request.Customer == null) return false; if (!request.DiscountRequirement.RestrictedToCustomerRoleId.HasValue) return false; foreach (var customerRole in request.Customer.CustomerRoles.Where(cr => cr.Active).ToList()) if (request.DiscountRequirement.RestrictedToCustomerRoleId == customerRole.Id) return true; return false; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (request.Customer == null) return false; if (request.Customer.ShippingAddress == null) return false; if (request.DiscountRequirement.ShippingCountryId == 0) return false; bool result = request.Customer.ShippingAddress.CountryId == request.DiscountRequirement.ShippingCountryId; return result; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); var spentAmountRequirement = _settingService.GetSettingByKey<decimal>(string.Format("DiscountRequirement.HadSpentAmount-{0}", request.DiscountRequirement.Id)); if (spentAmountRequirement == decimal.Zero) return true; if (request.Customer == null || request.Customer.IsGuest()) return false; var orders = _orderService.SearchOrders(request.Store.Id, 0, request.Customer.Id, null, null, OrderStatus.Complete, null, null, null, null, 0, int.MaxValue); decimal spentAmount = orders.Sum(o => o.OrderTotal); return spentAmount > spentAmountRequirement; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (request.Customer == null) return false; var restrictedToCustomerRoleId = _settingService.GetSettingByKey<int>(string.Format("DiscountRequirement.MustBeAssignedToCustomerRole-{0}", request.DiscountRequirement.Id)); if (restrictedToCustomerRoleId == 0) return false; foreach (var customerRole in request.Customer.CustomerRoles.Where(cr => cr.Active).ToList()) if (restrictedToCustomerRoleId == customerRole.Id) return true; return false; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); // var spentAmountRequirement = _settingService.GetSettingByKey<decimal>(string.Format("DiscountRequirement.FirstTimeUser-{0}", request.DiscountRequirement.Id)); //if (spentAmountRequirement == decimal.Zero) // return true; bool returnValue = true; if (request.Customer == null || request.Customer.IsGuest()) return false; var orders = _orderService.SearchOrders(storeId:0, customerId: request.Customer.Id, os: null); foreach (Order orderItem in orders) { var address = _workContext.CurrentCustomer.Addresses.ToList().FindAddress( orderItem.ShippingAddress.FirstName, orderItem.ShippingAddress.LastName, orderItem.ShippingAddress.PhoneNumber, orderItem.ShippingAddress.Email, orderItem.ShippingAddress.FaxNumber, orderItem.ShippingAddress.Company, orderItem.ShippingAddress.Address1, orderItem.ShippingAddress.Address2, orderItem.ShippingAddress.City, orderItem.ShippingAddress.StateProvinceId, orderItem.ShippingAddress.ZipPostalCode, orderItem.ShippingAddress.CountryId, null ); if (address != null) { returnValue = false; break; } } return returnValue; //decimal spentAmount = orders.Sum(o => o.OrderTotal); //return spentAmount > spentAmountRequirement; }
/// <summary> /// Check discount requirements /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodeToValidate">Coupon code to validate</param> /// <returns>true - requirement is met; otherwise, false</returns> public virtual bool IsDiscountValid(Discount discount, Customer customer, string couponCodeToValidate) { if (discount == null) { throw new ArgumentNullException("discount"); } //check coupon code if (discount.RequiresCouponCode) { if (String.IsNullOrEmpty(discount.CouponCode)) { return(false); } if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase)) { return(false); } } //check date range DateTime now = DateTime.UtcNow; if (discount.StartDateUtc.HasValue) { DateTime startDate = DateTime.SpecifyKind(discount.StartDateUtc.Value, DateTimeKind.Utc); if (startDate.CompareTo(now) > 0) { return(false); } } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) { return(false); } } if (!CheckDiscountLimitations(discount, customer)) { return(false); } //discount requirements var requirements = discount.DiscountRequirements; foreach (var req in requirements) { var requirementRule = LoadDiscountRequirementRuleBySystemName(req.DiscountRequirementRuleSystemName); if (requirementRule == null) { continue; } var request = new CheckDiscountRequirementRequest() { DiscountRequirement = req, Customer = customer }; if (!requirementRule.CheckRequirement(request)) { return(false); } } return(true); }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); var restrictedProductIds = _settingService.GetSettingByKey<string>(string.Format("DiscountRequirement.RestrictedProductIds-{0}", request.DiscountRequirement.Id)); if (String.IsNullOrWhiteSpace(restrictedProductIds)) return true; if (request.Customer == null) return false; //we support three ways of specifying products: //1. The comma-separated list of product identifiers (e.g. 77, 123, 156). //2. The comma-separated list of product identifiers with quantities. // {Product ID}:{Quantity}. For example, 77:1, 123:2, 156:3 //3. The comma-separated list of product identifiers with quantity range. // {Product ID}:{Min quantity}-{Max quantity}. For example, 77:1-3, 123:2-5, 156:3-8 var restrictedProducts = restrictedProductIds .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()) .ToList(); if (restrictedProducts.Count == 0) return false; //group products in the cart by product ID //it could be the same product with distinct product attributes //that's why we get the total quantity of this product var cartQuery = from sci in request.Customer.ShoppingCartItems where sci.ShoppingCartType == ShoppingCartType.ShoppingCart && sci.StoreId == request.Store.Id group sci by sci.ProductId into g select new { ProductId = g.Key, TotalQuantity = g.Sum(x => x.Quantity) }; var cart = cartQuery.ToList(); bool allFound = true; foreach (var restrictedProduct in restrictedProducts) { if (String.IsNullOrWhiteSpace(restrictedProduct)) continue; bool found1 = false; foreach (var sci in cart) { if (restrictedProduct.Contains(":")) { if (restrictedProduct.Contains("-")) { //the third way (the quantity rage specified) //{Product ID}:{Min quantity}-{Max quantity}. For example, 77:1-3, 123:2-5, 156:3-8 int restrictedProductId = 0; if (!int.TryParse(restrictedProduct.Split(new[] { ':' })[0], out restrictedProductId)) //parsing error; exit; return false; int quantityMin = 0; if (!int.TryParse(restrictedProduct.Split(new[] { ':' })[1].Split(new[] { '-' })[0], out quantityMin)) //parsing error; exit; return false; int quantityMax = 0; if (!int.TryParse(restrictedProduct.Split(new[] { ':' })[1].Split(new[] { '-' })[1], out quantityMax)) //parsing error; exit; return false; if (sci.ProductId == restrictedProductId && quantityMin <= sci.TotalQuantity && sci.TotalQuantity <= quantityMax) { found1 = true; break; } } else { //the second way (the quantity specified) //{Product ID}:{Quantity}. For example, 77:1, 123:2, 156:3 int restrictedProductId = 0; if (!int.TryParse(restrictedProduct.Split(new[] { ':' })[0], out restrictedProductId)) //parsing error; exit; return false; int quantity = 0; if (!int.TryParse(restrictedProduct.Split(new[] { ':' })[1], out quantity)) //parsing error; exit; return false; if (sci.ProductId == restrictedProductId && sci.TotalQuantity == quantity) { found1 = true; break; } } } else { //the first way (the quantity is not specified) int restrictedProductId = 0; if (int.TryParse(restrictedProduct, out restrictedProductId)) { if (sci.ProductId == restrictedProductId) { found1 = true; break; } } } } if (!found1) { allFound = false; break; } } if (allFound) return true; return false; }
/// <summary> /// Check discount requirements /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodeToValidate">Coupon code to validate</param> /// <returns>true - requirement is met; otherwise, false</returns> public virtual bool IsDiscountValid(Discount discount, Customer customer, string couponCodeToValidate) { if (discount == null) throw new ArgumentNullException("discount"); //check coupon code if (discount.RequiresCouponCode) { if (String.IsNullOrEmpty(discount.CouponCode)) return false; if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase)) return false; } //check date range DateTime now = DateTime.UtcNow; if (discount.StartDateUtc.HasValue) { DateTime startDate = DateTime.SpecifyKind(discount.StartDateUtc.Value, DateTimeKind.Utc); if (startDate.CompareTo(now) > 0) return false; } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) return false; } if (!CheckDiscountLimitations(discount, customer)) return false; //discount requirements var requirements = discount.DiscountRequirements; foreach (var req in requirements) { var requirementRule = LoadDiscountRequirementRuleBySystemName(req.DiscountRequirementRuleSystemName); if (requirementRule == null) continue; if (!_pluginFinder.AuthenticateStore(requirementRule.PluginDescriptor, _storeContext.CurrentStore.Id)) continue; var request = new CheckDiscountRequirementRequest() { DiscountRequirement = req, Customer = customer, Store = _storeContext.CurrentStore }; if (!requirementRule.CheckRequirement(request)) return false; } return true; }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { return true; }
/// <summary> /// Check discount requirements /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodeToValidate">Coupon code to validate</param> /// <returns>true - requirement is met; otherwise, false</returns> public virtual bool IsDiscountValid(Discount discount, Customer customer, string couponCodeToValidate) { if (discount == null) { throw new ArgumentNullException("discount"); } //check coupon code if (discount.RequiresCouponCode) { if (String.IsNullOrEmpty(discount.CouponCode)) { return(false); } if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase)) { return(false); } } //check date range DateTime now = DateTime.UtcNow; if (discount.StartDateUtc.HasValue) { DateTime startDate = DateTime.SpecifyKind(discount.StartDateUtc.Value, DateTimeKind.Utc); if (startDate.CompareTo(now) > 0) { return(false); } } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) { return(false); } } if (!CheckDiscountLimitations(discount, customer)) { return(false); } //discount requirements var requirements = discount.DiscountRequirements; foreach (var req in requirements) { var requirementRule = LoadDiscountRequirementRuleBySystemName(req.DiscountRequirementRuleSystemName); if (requirementRule == null) { continue; } if (!_pluginFinder.AuthenticateStore(requirementRule.PluginDescriptor, _storeContext.CurrentStore.Id)) { continue; } var request = new CheckDiscountRequirementRequest { DiscountRequirement = req, Customer = customer, Store = _storeContext.CurrentStore }; if (!requirementRule.CheckRequirement(request)) { return(false); } } //Do not allow discounts applied to order subtotal or total when a customer has gift cards in the cart. //Otherwise, this customer can purchase gift cards with discount and get more than paid ("free money"). if (discount.DiscountType == DiscountType.AssignedToOrderSubTotal || discount.DiscountType == DiscountType.AssignedToOrderTotal) { var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart) .LimitPerStore(_storeContext.CurrentStore.Id) .ToList(); var hasGiftCards = cart.Any(x => x.Product.IsGiftCard); if (hasGiftCards) { return(false); } } return(true); }
/// <summary> /// Check discount requirement /// </summary> /// <param name="request">Object that contains all information required to check the requirement (Current customer, discount, etc)</param> /// <returns>true - requirement is met; otherwise, false</returns> public bool CheckRequirement(CheckDiscountRequirementRequest request) { if (request == null) throw new ArgumentNullException("request"); if (request.DiscountRequirement == null) throw new NopException("Discount requirement is not set"); if (String.IsNullOrWhiteSpace(request.DiscountRequirement.RestrictedProductVariantIds)) return true; if (request.Customer == null) return false; //we support three ways of specifying product variants: //1. The comma-separated list of product variant identifiers (e.g. 77, 123, 156). //2. The comma-separated list of product variant identifiers with quantities. // {Product variant ID}:{Quantity}. For example, 77:1, 123:2, 156:3 //3. The comma-separated list of product variant identifiers with quantity range. // {Product variant ID}:{Min quantity}-{Max quantity}. For example, 77:1-3, 123:2-5, 156:3-8 var restrictedProductVariants = request.DiscountRequirement.RestrictedProductVariantIds .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()) .ToList(); if (restrictedProductVariants.Count == 0) return false; //cart var cart = request.Customer.ShoppingCartItems.Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart); bool allFound = true; foreach (var restrictedPv in restrictedProductVariants) { if (String.IsNullOrWhiteSpace(restrictedPv)) continue; bool found1 = false; foreach (var sci in cart) { if (restrictedPv.Contains(":")) { if (restrictedPv.Contains("-")) { //the third way (the quantity rage specified) //{Product variant ID}:{Min quantity}-{Max quantity}. For example, 77:1-3, 123:2-5, 156:3-8 int restrictedPvId = 0; if (!int.TryParse(restrictedPv.Split(new[] { ':' })[0], out restrictedPvId)) //parsing error; exit; return false; int quantityMin = 0; if (!int.TryParse(restrictedPv.Split(new[] { ':' })[1].Split(new[] { '-' })[0], out quantityMin)) //parsing error; exit; return false; int quantityMax = 0; if (!int.TryParse(restrictedPv.Split(new[] { ':' })[1].Split(new[] { '-' })[1], out quantityMax)) //parsing error; exit; return false; if (sci.ProductVariantId == restrictedPvId && quantityMin <= sci.Quantity && sci.Quantity <=quantityMax) { found1 = true; break; } } else { //the second way (the quantity specified) //{Product variant ID}:{Quantity}. For example, 77:1, 123:2, 156:3 int restrictedPvId = 0; if (!int.TryParse(restrictedPv.Split(new[] { ':' })[0], out restrictedPvId)) //parsing error; exit; return false; int quantity = 0; if (!int.TryParse(restrictedPv.Split(new[] { ':' })[1], out quantity)) //parsing error; exit; return false; if (sci.ProductVariantId == restrictedPvId && sci.Quantity == quantity) { found1 = true; break; } } } else { //the first way (the quantity is not specified) int restrictedPvId = int.Parse(restrictedPv); if (sci.ProductVariantId == restrictedPvId) { found1 = true; break; } } } if (!found1) { allFound = false; break; } } if (allFound) return true; return false; }
/// <summary> /// Check discount requirements /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodeToValidate">Coupon code to validate</param> /// <returns>true - requirement is met; otherwise, false</returns> public virtual bool IsDiscountValid(Discount discount, Customer customer, string couponCodeToValidate) { if (discount == null) throw new ArgumentNullException("discount"); //check coupon code if (discount.RequiresCouponCode) { if (String.IsNullOrEmpty(discount.CouponCode)) return false; if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase)) return false; } //check date range DateTime now = DateTime.UtcNow; if (discount.StartDateUtc.HasValue) { DateTime startDate = DateTime.SpecifyKind(discount.StartDateUtc.Value, DateTimeKind.Utc); if (startDate.CompareTo(now) > 0) return false; } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) return false; } if (!CheckDiscountLimitations(discount, customer)) return false; //discount requirements var requirements = discount.DiscountRequirements; foreach (var req in requirements) { var requirementRule = LoadDiscountRequirementRuleBySystemName(req.DiscountRequirementRuleSystemName); if (requirementRule == null) continue; if (!_pluginFinder.AuthenticateStore(requirementRule.PluginDescriptor, _storeContext.CurrentStore.Id)) continue; var request = new CheckDiscountRequirementRequest { DiscountRequirement = req, Customer = customer, Store = _storeContext.CurrentStore }; if (!requirementRule.CheckRequirement(request)) return false; } //Do not allow discounts applied to order subtotal or total when a customer has gift cards in the cart. //Otherwise, this customer can purchase gift cards with discount and get more than paid ("free money"). if (discount.DiscountType == DiscountType.AssignedToOrderSubTotal || discount.DiscountType == DiscountType.AssignedToOrderTotal) { var cart = customer.ShoppingCartItems .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart) .LimitPerStore(_storeContext.CurrentStore.Id) .ToList(); var hasGiftCards = cart.Any(x => x.Product.IsGiftCard); if (hasGiftCards) return false; } return true; }