/// <returns>A task that represents the asynchronous operation</returns>
        public override async Task <IActionResult> Categories()
        {
            //ensure that Avalara tax provider is active
            if (!await _taxPluginManager.IsPluginActiveAsync(AvalaraTaxDefaults.SystemName))
            {
                //if isn't active return base action result
                RouteData.Values["controller"] = "Tax";
                return(await base.Categories());
            }

            if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageTaxSettings))
            {
                return(AccessDeniedView());
            }

            //prepare model
            var model        = new Models.Tax.TaxCategorySearchModel();
            var cacheKey     = _cacheManager.PrepareKeyForDefaultCache(AvalaraTaxDefaults.TaxCodeTypesCacheKey);
            var taxCodeTypes = await _cacheManager.GetAsync(cacheKey, async() => await _avalaraTaxManager.GetTaxCodeTypesAsync());

            if (taxCodeTypes != null)
            {
                model.AvailableTypes = taxCodeTypes.Select(type => new SelectListItem(type.Value, type.Key)).ToList();
            }
            model.SetGridPageSize();

            //use overridden view
            return(View("~/Plugins/Tax.Avalara/Views/Tax/Categories.cshtml", model));
        }