/// <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 }));
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        public async Task CanLoadDiscountRequirementRuleBySystemKeyword()
        {
            var rule = await _discountPluginManager.LoadPluginBySystemNameAsync("TestDiscountRequirementRule");

            rule.Should().NotBeNull();
        }