/// <summary> /// Prepare discount requirement rule models /// </summary> /// <param name="requirements">Collection of discount requirements</param> /// <param name="discount">Discount</param> /// <param name="groupInteractionType">Interaction type within the group of requirements</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the list of discount requirement rule models /// </returns> public virtual async Task <IList <DiscountRequirementRuleModel> > PrepareDiscountRequirementRuleModelsAsync (ICollection <DiscountRequirement> requirements, Discount discount, RequirementGroupInteractionType groupInteractionType) { if (requirements == null) { throw new ArgumentNullException(nameof(requirements)); } if (discount == null) { throw new ArgumentNullException(nameof(discount)); } var lastRequirement = requirements.LastOrDefault(); return(await requirements.SelectAwait(async requirement => { //set common properties var requirementModel = new DiscountRequirementRuleModel { DiscountRequirementId = requirement.Id, ParentId = requirement.ParentId, IsGroup = requirement.IsGroup, RuleName = requirement.DiscountRequirementRuleSystemName, IsLastInGroup = lastRequirement == null || lastRequirement.Id == requirement.Id, InteractionType = groupInteractionType.ToString().ToUpper() }; var interactionType = requirement.InteractionType ?? RequirementGroupInteractionType.And; requirementModel.AvailableInteractionTypes = await interactionType.ToSelectListAsync(); if (requirement.IsGroup) { //get child requirements for the group var childRequirements = await _discountService.GetDiscountRequirementsByParentAsync(requirement); requirementModel.ChildRequirements = await PrepareDiscountRequirementRuleModelsAsync(childRequirements, discount, interactionType); return requirementModel; } //or try to get name and configuration URL for the requirement var requirementRule = await _discountPluginManager.LoadPluginBySystemNameAsync(requirement.DiscountRequirementRuleSystemName); if (requirementRule == null) { return null; } requirementModel.RuleName = requirementRule.PluginDescriptor.FriendlyName; requirementModel .ConfigurationUrl = requirementRule.GetConfigurationUrl(discount.Id, requirement.Id); return requirementModel; }).ToListAsync()); }
/// <returns>A task that represents the asynchronous operation</returns> public virtual async Task <IActionResult> GetDiscountRequirementConfigurationUrl(string systemName, int discountId, int?discountRequirementId) { if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageDiscounts)) { return(AccessDeniedView()); } if (string.IsNullOrEmpty(systemName)) { throw new ArgumentNullException(nameof(systemName)); } var discountRequirementRule = await _discountPluginManager.LoadPluginBySystemNameAsync(systemName) ?? throw new ArgumentException("Discount requirement rule could not be loaded"); var discount = await _discountService.GetDiscountByIdAsync(discountId) ?? throw new ArgumentException("Discount could not be loaded"); var url = discountRequirementRule.GetConfigurationUrl(discount.Id, discountRequirementId); return(Json(new { url })); }
/// <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> /// A task that represents the asynchronous operation /// The task result contains the rue if result is valid; otherwise false /// </returns> protected async Task <bool> GetValidationResultAsync(IEnumerable <DiscountRequirement> requirements, RequirementGroupInteractionType groupInteractionType, Customer customer, List <string> errors) { var result = false; foreach (var requirement in requirements) { if (requirement.IsGroup) { var childRequirements = await GetDiscountRequirementsByParentAsync(requirement); //get child requirements for the group var interactionType = requirement.InteractionType ?? RequirementGroupInteractionType.And; result = await GetValidationResultAsync(childRequirements, interactionType, customer, errors); } else { //or try to get validation result for the requirement var requirementRulePlugin = await _discountPluginManager .LoadPluginBySystemNameAsync(requirement.DiscountRequirementRuleSystemName, customer, (await _storeContext.GetCurrentStoreAsync()).Id); if (requirementRulePlugin == null) { continue; } var ruleResult = await requirementRulePlugin.CheckRequirementAsync(new DiscountRequirementValidationRequest { DiscountRequirementId = requirement.Id, Customer = customer, Store = await _storeContext.GetCurrentStoreAsync() }); //add validation error if (!ruleResult.IsValid) { var userError = !string.IsNullOrEmpty(ruleResult.UserError) ? ruleResult.UserError : await _localizationService.GetResourceAsync("ShoppingCart.Discount.CannotBeUsed"); errors.Add(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); }
public async Task CanLoadDiscountRequirementRuleBySystemKeyword() { var rule = await _discountPluginManager.LoadPluginBySystemNameAsync("TestDiscountRequirementRule"); rule.Should().NotBeNull(); }