protected void CheckAccess(string usernameOrEmail, string userPassword) { //check whether web service plugin is installed var pluginDescriptor = _pluginFinder.GetPluginDescriptorBySystemName("Misc.WebServices"); if (pluginDescriptor == null) { throw new ApplicationException("Web services plugin cannot be loaded"); } if (!_pluginFinder.AuthenticateStore(pluginDescriptor, _storeContext.CurrentStore.Id)) { throw new ApplicationException("Web services plugin is not available in this store"); } if (_customerRegistrationService.ValidateCustomer(usernameOrEmail, userPassword) != CustomerLoginResults.Successful) { throw new ApplicationException("Not allowed"); } var customer = _customerSettings.UsernamesEnabled ? _customerService.GetCustomerByUsername(usernameOrEmail) : _customerService.GetCustomerByEmail(usernameOrEmail); _workContext.CurrentCustomer = customer; _authenticationService.SignIn(customer, true); //valdiate whether we can access this web service if (!_permissionSettings.Authorize(WebServicePermissionProvider.AccessWebService)) { throw new ApplicationException("Not allowed to access web service"); } }
private ActionResult LoginInternal(string returnUrl, bool verifyResponse) { var processor = _openAuthenticationService.LoadExternalAuthenticationMethodBySystemName("ExternalAuth.Weixin"); if (processor == null || !processor.IsMethodActive(_externalAuthenticationSettings) || !processor.PluginDescriptor.Installed || !_pluginFinder.AuthenticateStore(processor.PluginDescriptor, _storeContext.CurrentStore.Id)) { throw new NopException("Weixin module cannot be loaded"); } var viewModel = new LoginModel(); TryUpdateModel(viewModel); var result = _oAuthProviderWeixinAuthorizer.Authorize(returnUrl, verifyResponse); switch (result.AuthenticationStatus) { case OpenAuthenticationStatus.Error: { if (!result.Success) { foreach (var error in result.Errors) { ExternalAuthorizerHelper.AddErrorsToDisplay(error); } } return(new RedirectResult(Url.LogOn(returnUrl))); } case OpenAuthenticationStatus.AssociateOnLogon: { return(new RedirectResult(Url.LogOn(returnUrl))); } case OpenAuthenticationStatus.AutoRegisteredEmailValidation: { //result return(RedirectToRoute("RegisterResult", new { resultId = (int)UserRegistrationType.EmailValidation })); } case OpenAuthenticationStatus.AutoRegisteredAdminApproval: { return(RedirectToRoute("RegisterResult", new { resultId = (int)UserRegistrationType.AdminApproval })); } case OpenAuthenticationStatus.AutoRegisteredStandard: { return(RedirectToRoute("RegisterResult", new { resultId = (int)UserRegistrationType.Standard })); } default: break; } if (result.Result != null) { return(result.Result); } return(HttpContext.Request.IsAuthenticated ? new RedirectResult(!string.IsNullOrEmpty(returnUrl) ? returnUrl : "~/") : new RedirectResult(Url.LogOn(returnUrl))); }
/// <summary> /// Check whether authentication by the passed external authentication method is available /// </summary> /// <param name="systemName">System name of the external authentication method</param> /// <returns>True if authentication is available; otherwise false</returns> public virtual bool ExternalAuthenticationMethodIsAvailable(string systemName) { //load method var authenticationMethod = LoadExternalAuthenticationMethodBySystemName(systemName); return(authenticationMethod != null && authenticationMethod.IsMethodActive(_externalAuthenticationSettings) && authenticationMethod.PluginDescriptor.Installed && _pluginFinder.AuthenticateStore(authenticationMethod.PluginDescriptor, _storeContext.CurrentStore.Id)); }
/// <summary> /// Check whether authentication by the passed external authentication method is available /// </summary> /// <param name="systemName">System name of the external authentication method</param> /// <returns>True if authentication is available; otherwise false</returns> public virtual bool ExternalAuthenticationMethodIsAvailable(string systemName) { //load method var authenticationMethod = LoadExternalAuthenticationMethodBySystemName(systemName); return(authenticationMethod != null && this.IsExternalAuthenticationMethodActive(authenticationMethod) && authenticationMethod.PluginDescriptor.Installed && _pluginFinder.AuthenticateStore(authenticationMethod.PluginDescriptor, _storeContext.CurrentStore.Id) && _pluginFinder.AuthorizedForUser(authenticationMethod.PluginDescriptor, _workContext.CurrentCustomer)); }
public ActionResult Login(string returnUrl) { var processor = _openAuthenticationService.LoadExternalAuthenticationMethodBySystemName("QQ外部认证"); if (processor == null || !processor.IsMethodActive(_externalAuthenticationSettings) || !processor.PluginDescriptor.Installed || !_pluginFinder.AuthenticateStore(processor.PluginDescriptor, _storeContext.CurrentStore.Id)) { throw new NopException("QQ模块没有被装载"); } var viewModel = new LoginModel(); TryUpdateModel(viewModel); var authenticationUrl = RequestAuthentication(); return(new RedirectResult(authenticationUrl)); }
/// <summary> /// Handles the event. /// </summary> /// <param name="eventMessage">The event message.</param> public void HandleEvent(OrderPlacedEvent eventMessage) { //is enabled? if (!_verizonSettings.Enabled) { return; } var pluginDescriptor = _pluginFinder.GetPluginDescriptorBySystemName("Mobile.SMS.Verizon"); if (pluginDescriptor == null) { return; } if (!_pluginFinder.AuthenticateStore(pluginDescriptor, _storeContext.CurrentStore.Id)) { return; } var plugin = pluginDescriptor.Instance() as VerizonSmsProvider; if (plugin == null) { return; } var order = eventMessage.Order; //send SMS if (plugin.SendSms(String.Format("New order(#{0}) has been placed.", order.Id))) { order.OrderNotes.Add(new OrderNote { Note = "\"Order placed\" SMS alert (to store owner) has been sent", DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow, OrderId = order.Id, }); _orderService.UpdateOrder(order); } }
/// <summary> /// Get discount validation result /// </summary> /// <param name="requirements">Collection of discount requirement</param> /// <param name="groupInteractionType">Interaction type within the group of requirements</param> /// <param name="customer">Customer</param> /// <param name="errors">Errors</param> /// <returns>True if result is valid; otherwise false</returns> protected bool GetValidationResult(IEnumerable <DiscountRequirementForCaching> requirements, RequirementGroupInteractionType groupInteractionType, Customer customer, List <string> errors) { var result = false; foreach (var requirement in requirements) { if (requirement.IsGroup) { //get child requirements for the group var interactionType = requirement.InteractionType ?? RequirementGroupInteractionType.And; result = GetValidationResult(requirement.ChildRequirements, interactionType, customer, errors); } else { //or try to get validation result for the requirement var requirementRulePlugin = LoadDiscountRequirementRuleBySystemName(requirement.SystemName); if (requirementRulePlugin == null) { continue; } if (!_pluginFinder.AuthorizedForUser(requirementRulePlugin.PluginDescriptor, customer)) { continue; } if (!_pluginFinder.AuthenticateStore(requirementRulePlugin.PluginDescriptor, _storeContext.CurrentStore.Id)) { continue; } var ruleResult = requirementRulePlugin.CheckRequirement(new DiscountRequirementValidationRequest { DiscountRequirementId = requirement.Id, Customer = customer, Store = _storeContext.CurrentStore }); //add validation error if (!ruleResult.IsValid) { errors.Add(ruleResult.UserError); } result = ruleResult.IsValid; } //all requirements must be met, so return false if (!result && groupInteractionType == RequirementGroupInteractionType.And) { return(false); } //any of requirements must be met, so return true if (result && groupInteractionType == RequirementGroupInteractionType.Or) { return(true); } } return(result); }
/// <summary> /// Validate discount /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodeToValidate">Coupon code to validate</param> /// <returns>Discount validation result</returns> public virtual DiscountValidationResult ValidateDiscount(Discount discount, Customer customer, string couponCodeToValidate) { if (discount == null) { throw new ArgumentNullException("discount"); } if (customer == null) { throw new ArgumentNullException("customer"); } //invalid by default var result = new DiscountValidationResult(); //check coupon code if (discount.RequiresCouponCode) { if (String.IsNullOrEmpty(discount.CouponCode)) { return(result); } if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase)) { return(result); } } //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.IsGiftCard); if (hasGiftCards) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedWithGiftCards"); return(result); } } //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) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.NotStartedYet"); return(result); } } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.Expired"); return(result); } } //discount limitation switch (discount.DiscountLimitation) { case DiscountLimitationType.NTimesOnly: { var usedTimes = GetAllDiscountUsageHistory(discount.Id, null, null, 0, 1).TotalCount; if (usedTimes >= discount.LimitationTimes) { return(result); } } break; case DiscountLimitationType.NTimesPerCustomer: { if (customer.IsRegistered()) { var usedTimes = GetAllDiscountUsageHistory(discount.Id, customer.Id, null, 0, 1).TotalCount; if (usedTimes >= discount.LimitationTimes) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedAnymore"); return(result); } } } break; case DiscountLimitationType.Unlimited: default: break; } //discount requirements //UNDONE we should inject static cache manager into constructor. we we already have "per request" cache manager injected. better way to do it? //we cache meta info of rdiscount requirements. this way we should not load them for each HTTP request var staticCacheManager = EngineContext.Current.ContainerManager.Resolve <ICacheManager>(); string key = string.Format(DiscountRequirementEventConsumer.DISCOUNT_REQUIREMENT_MODEL_KEY, discount.Id); //var requirements = discount.DiscountRequirements; var requirements = staticCacheManager.Get(key, () => { var cachedRequirements = new List <DiscountRequirementForCaching>(); foreach (var dr in discount.DiscountRequirements) { cachedRequirements.Add(new DiscountRequirementForCaching { Id = dr.Id, DiscountId = dr.DiscountId, SystemName = dr.DiscountRequirementRuleSystemName }); } return(cachedRequirements); }); foreach (var req in requirements) { //load a plugin var requirementRulePlugin = LoadDiscountRequirementRuleBySystemName(req.SystemName); if (requirementRulePlugin == null) { continue; } if (!_pluginFinder.AuthenticateStore(requirementRulePlugin.PluginDescriptor, _storeContext.CurrentStore.Id)) { continue; } var ruleRequest = new DiscountRequirementValidationRequest { DiscountRequirementId = req.Id, Customer = customer, Store = _storeContext.CurrentStore, DiscountId = req.DiscountId, }; var ruleResult = requirementRulePlugin.CheckRequirement(ruleRequest); if (!ruleResult.IsValid) { result.UserError = ruleResult.UserError; return(result); } } result.IsValid = true; return(result); }
/// <summary> /// Validate discount /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodesToValidate">Coupon codes to validate</param> /// <returns>Discount validation result</returns> public virtual async Task <DiscountValidationResult> ValidateDiscount(Discount discount, Customer customer, string[] couponCodesToValidate) { if (discount == null) { throw new ArgumentNullException("discount"); } if (customer == null) { throw new ArgumentNullException("customer"); } var result = new DiscountValidationResult(); //check is enabled if (!discount.IsEnabled) { return(result); } //do not allow use discount in the current store if (discount.LimitedToStores && !discount.Stores.Any(x => _storeContext.CurrentStore.Id == x)) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedInStore"); return(result); } //check coupon code if (discount.RequiresCouponCode) { if (couponCodesToValidate == null || !couponCodesToValidate.Any()) { return(result); } var exists = false; foreach (var item in couponCodesToValidate) { if (discount.Reused) { if (await ExistsCodeInDiscount(item, discount.Id, null)) { result.CouponCode = item; exists = true; } } else { if (await ExistsCodeInDiscount(item, discount.Id, false)) { result.CouponCode = item; exists = true; } } } if (!exists) { return(result); } } //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(_shoppingCartSettings.CartsSharedBetweenStores, _storeContext.CurrentStore.Id) .ToList(); var hasGiftCards = cart.Any(x => x.IsGiftCard); if (hasGiftCards) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedWithGiftCards"); return(result); } } //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) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.NotStartedYet"); return(result); } } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.Expired"); return(result); } } //discount limitation switch (discount.DiscountLimitation) { case DiscountLimitationType.NTimesOnly: { var usedTimes = await GetAllDiscountUsageHistory(discount.Id, null, null, false, 0, 1); if (usedTimes.TotalCount >= discount.LimitationTimes) { return(result); } } break; case DiscountLimitationType.NTimesPerCustomer: { if (customer.IsRegistered()) { var usedTimes = await GetAllDiscountUsageHistory(discount.Id, customer.Id, null, false, 0, 1); if (usedTimes.TotalCount >= discount.LimitationTimes) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedAnymore"); return(result); } } } break; case DiscountLimitationType.Unlimited: default: break; } //discount requirements string keyReq = string.Format(DiscountRequirementEventConsumer.DISCOUNT_REQUIREMENT_MODEL_KEY, discount.Id); var requirements = await _cacheBase.GetAsync(keyReq, async() => { return(await Task.FromResult(discount.DiscountRequirements.ToList())); }); foreach (var req in requirements) { //load a plugin var discountRequirementPlugin = LoadDiscountPluginBySystemName(req.DiscountRequirementRuleSystemName); if (discountRequirementPlugin == null) { continue; } if (!_pluginFinder.AuthenticateStore(discountRequirementPlugin.PluginDescriptor, _storeContext.CurrentStore.Id)) { continue; } var ruleRequest = new DiscountRequirementValidationRequest { DiscountRequirementId = req.Id, DiscountId = req.DiscountId, Customer = customer, Store = _storeContext.CurrentStore }; var singleRequirementRule = discountRequirementPlugin.GetRequirementRules().Single(x => x.SystemName == req.DiscountRequirementRuleSystemName); var ruleResult = await singleRequirementRule.CheckRequirement(ruleRequest); if (!ruleResult.IsValid) { result.UserError = ruleResult.UserError; return(result); } } result.IsValid = true; return(result); // }); //return validationResult; }
/// <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 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); }
public void HandleEvent(OrderPlacedEvent eventMessage) { if (!_smsSettings.Enabled) { return; } if (!_smsSettings.EnableOrderPlaced) { return; } if (_smsSettings.IgnnoreUserIDs.Split(',').Contains(eventMessage.Order.CustomerId.ToString())) { eventMessage.Order.OrderNotes.Add(new OrderNote { Note = "SMS alert not send. user:"******" in Ignore Lit", DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(eventMessage.Order); return; } string template = ""; if (eventMessage.Order.CustomerLanguageId == _smsSettings.SecondLanguageID) { // second language template = _smsSettings.TemplateOrderPlaced2; } else { if (eventMessage.Order.CustomerLanguageId == _smsSettings.ThirdLanguageID) { // Third language template = _smsSettings.TemplateOrderPlaced3; } else { // default template = _smsSettings.TemplateOrderPlaced; } } if (string.IsNullOrEmpty(template)) { template = _smsSettings.TemplateOrderPlaced; } try { template = string.Format(template, eventMessage.Order.Id, eventMessage.Order.OrderTotal); } catch { } var pluginDescriptor = _pluginFinder.GetPluginDescriptorBySystemName("SMS.Notifications"); if (pluginDescriptor == null) { return; } if (!_pluginFinder.AuthenticateStore(pluginDescriptor, _storeContext.CurrentStore.Id)) { return; } var plugin = pluginDescriptor.Instance() as SMSNotificationsProvider; if (plugin == null) { return; } string phonenum = string.IsNullOrEmpty(eventMessage.Order.Customer.BillingAddress.PhoneNumber) ? eventMessage.Order.Customer.ShippingAddress.PhoneNumber : eventMessage.Order.Customer.BillingAddress.PhoneNumber; phonenum = ParcePhoneNumbe(phonenum); string resText = ""; if (plugin.SendSms(phonenum, template, out resText)) { eventMessage.Order.OrderNotes.Add(new OrderNote { Note = "\"Order placed\" SMS alert has been sent to phone:" + phonenum, DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(eventMessage.Order); } else { eventMessage.Order.OrderNotes.Add(new OrderNote { Note = "\"Order placed\" SMS alert can't send to phone:" + phonenum + ". Error" + resText, DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(eventMessage.Order); } }
/// <summary> /// Validate discount /// </summary> /// <param name="discount">Discount</param> /// <param name="customer">Customer</param> /// <param name="couponCodeToValidate">Coupon code to validate</param> /// <returns>Discount validation result</returns> public virtual DiscountValidationResult ValidateDiscount(Discount discount, Customer customer, string couponCodeToValidate) { if (discount == null) { throw new ArgumentNullException("discount"); } if (customer == null) { throw new ArgumentNullException("customer"); } //invalid by default var result = new DiscountValidationResult(); //check coupon code if (discount.RequiresCouponCode) { if (String.IsNullOrEmpty(discount.CouponCode)) { return(result); } if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase)) { return(result); } } //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) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.NotStartedYet"); return(result); } } if (discount.EndDateUtc.HasValue) { DateTime endDate = DateTime.SpecifyKind(discount.EndDateUtc.Value, DateTimeKind.Utc); if (endDate.CompareTo(now) < 0) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.Expired"); return(result); } } //discount limitation switch (discount.DiscountLimitation) { case DiscountLimitationType.NTimesOnly: { var usedTimes = GetAllDiscountUsageHistory(discount.Id, null, null, 0, 1).TotalCount; if (usedTimes >= discount.LimitationTimes) { return(result); } } break; case DiscountLimitationType.NTimesPerCustomer: { if (customer.IsRegistered()) { var usedTimes = GetAllDiscountUsageHistory(discount.Id, customer.Id, null, 0, 1).TotalCount; if (usedTimes >= discount.LimitationTimes) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedAnymore"); return(result); } } } break; case DiscountLimitationType.Unlimited: default: break; } //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 ruleRequest = new DiscountRequirementValidationRequest { DiscountRequirement = req, Customer = customer, Store = _storeContext.CurrentStore }; var ruleResult = requirementRule.CheckRequirement(ruleRequest); if (!ruleResult.IsValid) { result.UserError = ruleResult.UserError; return(result); } } //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) { result.UserError = _localizationService.GetResource("ShoppingCart.Discount.CannotBeUsedWithGiftCards"); return(result); } } result.IsValid = true; return(result); }