/// <summary>
        /// Prepare paged category product list model
        /// </summary>
        /// <param name="searchModel">Category product search model</param>
        /// <param name="category">Category</param>
        /// <returns>Category product list model</returns>
        public virtual CategoryProductListModel PrepareCategoryProductListModel(CategoryProductSearchModel searchModel, Category category)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (category == null)
            {
                throw new ArgumentNullException(nameof(category));
            }

            //get product categories
            var productCategories = _categoryService.GetProductCategoriesByCategoryId(category.Id,
                                                                                      showHidden: true,
                                                                                      pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize);

            //prepare grid model
            var model = new CategoryProductListModel
            {
                //fill in model values from the entity
                Data = productCategories.Select(productCategory => new CategoryProductModel
                {
                    Id                = productCategory.Id,
                    CategoryId        = productCategory.CategoryId,
                    ProductId         = productCategory.ProductId,
                    ProductName       = _productService.GetProductById(productCategory.ProductId)?.Name,
                    IsFeaturedProduct = productCategory.IsFeaturedProduct,
                    DisplayOrder      = productCategory.DisplayOrder
                }),
                Total = productCategories.TotalCount
            };

            return(model);
        }
        /// <summary>
        /// Prepare paged category product list model
        /// </summary>
        /// <param name="searchModel">Category product search model</param>
        /// <param name="category">Category</param>
        /// <returns>Category product list model</returns>
        public virtual CategoryProductListModel PrepareCategoryProductListModel(CategoryProductSearchModel searchModel, Category category)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (category == null)
            {
                throw new ArgumentNullException(nameof(category));
            }

            //get product categories
            var productCategories = _categoryService.GetProductCategoriesByCategoryId(category.Id,
                                                                                      showHidden: true,
                                                                                      pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize);

            //prepare grid model
            var model = new CategoryProductListModel
            {
                Data = productCategories.Select(productCategory =>
                {
                    //fill in model values from the entity
                    var categoryProductModel = productCategory.ToModel <CategoryProductModel>();

                    //fill in additional values (not existing in the entity)
                    categoryProductModel.ProductName = _productService.GetProductById(productCategory.ProductId)?.Name;

                    return(categoryProductModel);
                }),
                Total = productCategories.TotalCount
            };

            return(model);
        }
        public virtual IActionResult ProductList(CategoryProductSearchModel searchModel)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCategories))
            {
                return(AccessDeniedKendoGridJson());
            }

            //try to get a category with the specified id
            var category = _categoryService.GetCategoryById(searchModel.CategoryId)
                           ?? throw new ArgumentException("No category found with the specified id");

            //prepare model
            var model = _categoryModelFactory.PrepareCategoryProductListModel(searchModel, category);

            return(Json(model));
        }
        public virtual async Task <IActionResult> ProductList(CategoryProductSearchModel searchModel)
        {
            if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCategories))
            {
                return(await AccessDeniedDataTablesJson());
            }

            //try to get a category with the specified id
            var category = await _categoryService.GetCategoryByIdAsync(searchModel.CategoryId)
                           ?? throw new ArgumentException("No category found with the specified id");

            //prepare model
            var model = await _categoryModelFactory.PrepareCategoryProductListModelAsync(searchModel, category);

            return(Json(model));
        }
        /// <summary>
        /// Prepare category product search model
        /// </summary>
        /// <param name="searchModel">Category product search model</param>
        /// <param name="category">Category</param>
        /// <returns>Category product search model</returns>
        protected virtual CategoryProductSearchModel PrepareCategoryProductSearchModel(CategoryProductSearchModel searchModel, Category category)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (category == null)
            {
                throw new ArgumentNullException(nameof(category));
            }

            searchModel.CategoryId = category.Id;

            //prepare page parameters
            searchModel.SetGridPageSize();

            return(searchModel);
        }
        /// <summary>
        /// Prepare paged category product list model
        /// </summary>
        /// <param name="searchModel">Category product search model</param>
        /// <param name="category">Category</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the category product list model
        /// </returns>
        public virtual async Task <CategoryProductListModel> PrepareCategoryProductListModelAsync(CategoryProductSearchModel searchModel, Category category)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (category == null)
            {
                throw new ArgumentNullException(nameof(category));
            }

            //get product categories
            var productCategories = await _categoryService.GetProductCategoriesByCategoryIdAsync(category.Id,
                                                                                                 showHidden : true,
                                                                                                 pageIndex : searchModel.Page - 1, pageSize : searchModel.PageSize);

            //prepare grid model
            var model = await new CategoryProductListModel().PrepareToGridAsync(searchModel, productCategories, () =>
            {
                return(productCategories.SelectAwait(async productCategory =>
                {
                    //fill in model values from the entity
                    var categoryProductModel = productCategory.ToModel <CategoryProductModel>();

                    //fill in additional values (not existing in the entity)
                    categoryProductModel.ProductName = (await _productService.GetProductByIdAsync(productCategory.ProductId))?.Name;

                    return categoryProductModel;
                }));
            });

            return(model);
        }