Example #1
0
        /// <summary>
        /// Prepare paged tax provider list model
        /// </summary>
        /// <param name="searchModel">Tax provider search model</param>
        /// <returns>Tax provider list model</returns>
        public virtual async Task <TaxProviderListModel> PrepareTaxProviderListModelAsync(TaxProviderSearchModel searchModel)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            //get tax providers
            var taxProviders = (await _taxPluginManager.LoadAllPluginsAsync()).ToPagedList(searchModel);

            //prepare grid model
            var model = new TaxProviderListModel().PrepareToGrid(searchModel, taxProviders, () =>
            {
                return(taxProviders.Select(provider =>
                {
                    //fill in model values from the entity
                    var taxProviderModel = provider.ToPluginModel <TaxProviderModel>();

                    //fill in additional values (not existing in the entity)
                    taxProviderModel.ConfigurationUrl = provider.GetConfigurationPageUrl();
                    taxProviderModel.IsPrimaryTaxProvider = _taxPluginManager.IsPluginActive(provider);

                    return taxProviderModel;
                }));
            });

            return(model);
        }
        public IActionResult ExportProducts(string selectedIds)
        {
            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return(RedirectToAction("List", "Product"));
            }

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

            //export items
            var exportedItems = _avalaraTaxManager.ExportProducts(selectedIds);

            if (exportedItems.HasValue)
            {
                if (exportedItems > 0)
                {
                    _notificationService.SuccessNotification(string.Format(_localizationService.GetResource("Plugins.Tax.Avalara.Items.Export.Success"), exportedItems));
                }
                else
                {
                    _notificationService.SuccessNotification(_localizationService.GetResource("Plugins.Tax.Avalara.Items.Export.AlreadyExported"));
                }
            }
            else
            {
                _notificationService.ErrorNotification(_localizationService.GetResource("Plugins.Tax.Avalara.Items.Export.Error"));
            }

            return(RedirectToAction("List", "Product"));
        }
        /// <summary>
        /// Invoke the widget view component
        /// </summary>
        /// <param name="widgetZone">Widget zone</param>
        /// <param name="additionalData">Additional parameters</param>
        /// <returns>View component result</returns>
        public IViewComponentResult Invoke(string widgetZone, object additionalData)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return(Content(string.Empty));
            }

            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return(Content(string.Empty));
            }

            //ensure that it's a proper widget zone
            if (!widgetZone.Equals(AdminWidgetZones.TaxSettingsDetailsBlock))
            {
                return(Content(string.Empty));
            }

            //prepare model
            var model = new TaxOriginAddressTypeModel
            {
                PrecedingElementId          = nameof(TaxSettingsModel.TaxBasedOn),
                AvalaraTaxOriginAddressType = (int)_avalaraTaxSettings.TaxOriginAddressType,
                TaxOriginAddressTypes       = TaxOriginAddressType.DefaultTaxAddress.ToSelectList(false)
                                              .Select(type => new SelectListItem(type.Text, type.Value)).ToList(),
            };

            return(View("~/Plugins/Tax.Avalara/Views/Settings/TaxOriginAddressType.cshtml", model));
        }
        /// <summary>
        /// Prepare plugins enabled warning model
        /// </summary>
        /// <param name="models">List of system warning models</param>
        protected virtual void PreparePluginsEnabledWarningModel(List <SystemWarningModel> models)
        {
            var plugins = _pluginService.GetPlugins <IPlugin>();

            var notEnabled = new List <string>();

            foreach (var plugin in plugins)
            {
                var isEnabled = true;

                switch (plugin)
                {
                case IPaymentMethod paymentMethod:
                    isEnabled = _paymentPluginManager.IsPluginActive(paymentMethod);
                    break;

                case IShippingRateComputationMethod shippingRateComputationMethod:
                    isEnabled = _shippingPluginManager.IsPluginActive(shippingRateComputationMethod);
                    break;

                case IPickupPointProvider pickupPointProvider:
                    isEnabled = _pickupPluginManager.IsPluginActive(pickupPointProvider);
                    break;

                case ITaxProvider taxProvider:
                    isEnabled = _taxPluginManager.IsPluginActive(taxProvider);
                    break;

                case IExternalAuthenticationMethod externalAuthenticationMethod:
                    isEnabled = _authenticationPluginManager.IsPluginActive(externalAuthenticationMethod);
                    break;

                case IWidgetPlugin widgetPlugin:
                    isEnabled = _widgetPluginManager.IsPluginActive(widgetPlugin);
                    break;

                case IExchangeRateProvider exchangeRateProvider:
                    isEnabled = _exchangeRatePluginManager.IsPluginActive(exchangeRateProvider);
                    break;
                }

                if (isEnabled)
                {
                    continue;
                }

                notEnabled.Add(plugin.PluginDescriptor.FriendlyName);
            }

            if (notEnabled.Any())
            {
                models.Add(new SystemWarningModel
                {
                    Level = SystemWarningLevel.Warning,
                    Text  = $"{_localizationService.GetResource("Admin.System.Warnings.PluginNotEnabled")}: {string.Join(", ", notEnabled)}"
                });
            }
        }
Example #5
0
        public override IActionResult Categories()
        {
            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                //if isn't active return base action result
                RouteData.Values["controller"] = "Tax";
                return(base.Categories());
            }

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

            //prepare model
            var model        = new Models.Tax.TaxCategorySearchModel();
            var cacheKey     = _cacheKeyService.PrepareKeyForDefaultCache(AvalaraTaxDefaults.TaxCodeTypesCacheKey);
            var taxCodeTypes = _cacheManager.Get(cacheKey, () => _avalaraTaxManager.GetTaxCodeTypes());

            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));
        }
        /// <summary>
        /// Prepare paged tax category list model
        /// </summary>
        /// <param name="searchModel">Tax category search model</param>
        /// <returns>Tax category list model</returns>
        public override TaxCategoryListModel PrepareTaxCategoryListModel(TaxCategorySearchModel searchModel)
        {
            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return(base.PrepareTaxCategoryListModel(searchModel));
            }

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

            //get tax categories
            var taxCategories = _taxCategoryService.GetAllTaxCategories().ToPagedList(searchModel);

            //get tax types and define the default value
            var taxTypes = _cacheManager.Get(AvalaraTaxDefaults.TaxCodeTypesCacheKey, () => _avalaraTaxManager.GetTaxCodeTypes())
                           ?.Select(taxType => new { Id = taxType.Key, Name = taxType.Value });
            var defaultType = taxTypes
                              ?.FirstOrDefault(taxType => taxType.Name.Equals("Unknown", StringComparison.InvariantCultureIgnoreCase))
                              ?? taxTypes?.FirstOrDefault();

            //prepare grid model
            var model = new Models.Tax.TaxCategoryListModel().PrepareToGrid(searchModel, taxCategories, () =>
            {
                //fill in model values from the entity
                return(taxCategories.Select(taxCategory =>
                {
                    //fill in model values from the entity
                    var taxCategoryModel = new Models.Tax.TaxCategoryModel
                    {
                        Id = taxCategory.Id,
                        Name = taxCategory.Name,
                        DisplayOrder = taxCategory.DisplayOrder
                    };

                    //try to get previously saved tax code type and description
                    var taxCodeType = taxTypes?.FirstOrDefault(type =>
                                                               type.Id.Equals(_genericAttributeService.GetAttribute <string>(taxCategory, AvalaraTaxDefaults.TaxCodeTypeAttribute) ?? string.Empty))
                                      ?? defaultType;
                    taxCategoryModel.Type = taxCodeType?.Name ?? string.Empty;
                    taxCategoryModel.TypeId = taxCodeType?.Id ?? Guid.Empty.ToString();
                    taxCategoryModel.Description = _genericAttributeService
                                                   .GetAttribute <string>(taxCategory, AvalaraTaxDefaults.TaxCodeDescriptionAttribute) ?? string.Empty;

                    return taxCategoryModel;
                }));
            });

            return(new TaxCategoryListModel {
                Data = model.Data, Draw = model.Draw, RecordsTotal = model.RecordsTotal, RecordsFiltered = model.RecordsFiltered
            });
        }
        /// <summary>
        /// Prepare plugin model properties of the installed plugin
        /// </summary>
        /// <param name="model">Plugin model</param>
        /// <param name="plugin">Plugin</param>
        protected virtual void PrepareInstalledPluginModel(PluginModel model, IPlugin plugin)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

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

            //prepare configuration URL
            model.ConfigurationUrl = plugin.GetConfigurationPageUrl();

            //prepare enabled/disabled (only for some plugin types)
            model.CanChangeEnabled = true;
            switch (plugin)
            {
            case IPaymentMethod paymentMethod:
                model.IsEnabled = _paymentPluginManager.IsPluginActive(paymentMethod);
                break;

            case IShippingRateComputationMethod shippingRateComputationMethod:
                model.IsEnabled = _shippingPluginManager.IsPluginActive(shippingRateComputationMethod);
                break;

            case IPickupPointProvider pickupPointProvider:
                model.IsEnabled = _pickupPluginManager.IsPluginActive(pickupPointProvider);
                break;

            case ITaxProvider taxProvider:
                model.IsEnabled = _taxPluginManager.IsPluginActive(taxProvider);
                break;

            case IExternalAuthenticationMethod externalAuthenticationMethod:
                model.IsEnabled = _authenticationPluginManager.IsPluginActive(externalAuthenticationMethod);
                break;

            case IMultiFactorAuthenticationMethod multiFactorAuthenticationMethod:
                model.IsEnabled = _multiFactorAuthenticationPluginManager.IsPluginActive(multiFactorAuthenticationMethod);
                break;

            case IWidgetPlugin widgetPlugin:
                model.IsEnabled = _widgetPluginManager.IsPluginActive(widgetPlugin);
                break;

            default:
                model.CanChangeEnabled = false;
                break;
            }
        }
        /// <summary>
        /// Invoke the widget view component
        /// </summary>
        /// <param name="widgetZone">Widget zone</param>
        /// <param name="additionalData">Additional parameters</param>
        /// <returns>View component result</returns>
        public IViewComponentResult Invoke(string widgetZone, object additionalData)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return(Content(string.Empty));
            }

            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return(Content(string.Empty));
            }

            //ensure that it's a proper widget zone
            if (!widgetZone.Equals(AdminWidgetZones.TaxCategoryListButtons))
            {
                return(Content(string.Empty));
            }

            return(View("~/Plugins/Tax.Avalara/Views/Tax/TaxCodes.cshtml"));
        }
        /// <summary>
        /// Save entity use code
        /// </summary>
        /// <param name="model">Base QNet entity model</param>
        private void SaveEntityUseCode(BaseQNetEntityModel model)
        {
            //ensure that received model is BaseQNetEntityModel
            if (model == null)
            {
                return;
            }

            //get entity by received model
            var entity = model is CustomerModel?_customerService.GetCustomerById(model.Id)
                             : model is CustomerRoleModel?_customerService.GetCustomerRoleById(model.Id)
                                 : model is ProductModel?_productService.GetProductById(model.Id)
                                     : model is CheckoutAttributeModel ? (BaseEntity)_checkoutAttributeService.GetCheckoutAttributeById(model.Id)
                : null;

            if (entity == null)
            {
                return;
            }

            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return;
            }

            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return;
            }

            //whether there is a form value for the entity use code
            if (_httpContextAccessor.HttpContext.Request.Form.TryGetValue(AvalaraTaxDefaults.EntityUseCodeAttribute, out var entityUseCodeValue) &&
                !StringValues.IsNullOrEmpty(entityUseCodeValue))
            {
                //save attribute
                var entityUseCode = !entityUseCodeValue.ToString().Equals(Guid.Empty.ToString()) ? entityUseCodeValue.ToString() : null;
                _genericAttributeService.SaveAttribute(entity, AvalaraTaxDefaults.EntityUseCodeAttribute, entityUseCode);
            }
        }
        /// <summary>
        /// Handle model received event
        /// </summary>
        /// <param name="eventMessage">Event message</param>
        public void HandleEvent(ModelReceivedEvent <BaseNopModel> eventMessage)
        {
            //get entity by received model
            var entity = eventMessage.Model switch
            {
                CustomerModel customerModel => (BaseEntity)_customerService.GetCustomerById(customerModel.Id),
                CustomerRoleModel customerRoleModel => _customerService.GetCustomerRoleById(customerRoleModel.Id),
                ProductModel productModel => _productService.GetProductById(productModel.Id),
                CheckoutAttributeModel checkoutAttributeModel => _checkoutAttributeService.GetCheckoutAttributeById(checkoutAttributeModel.Id),
                _ => null
            };

            if (entity == null)
            {
                return;
            }

            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return;
            }

            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return;
            }

            //whether there is a form value for the entity use code
            if (_httpContextAccessor.HttpContext.Request.Form.TryGetValue(AvalaraTaxDefaults.EntityUseCodeAttribute, out var entityUseCodeValue) &&
                !StringValues.IsNullOrEmpty(entityUseCodeValue))
            {
                //save attribute
                var entityUseCode = !entityUseCodeValue.ToString().Equals(Guid.Empty.ToString()) ? entityUseCodeValue.ToString() : null;
                _genericAttributeService.SaveAttribute(entity, AvalaraTaxDefaults.EntityUseCodeAttribute, entityUseCode);
            }
        }
        /// <summary>
        /// Prepare tax details by Avalara tax service
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        private void PrepareTaxDetails(IList <ShoppingCartItem> cart)
        {
            //ensure that Avalara tax provider is active
            var taxProvider = _taxPluginManager
                              .LoadPluginBySystemName(AvalaraTaxDefaults.SystemName, _workContext.CurrentCustomer, _storeContext.CurrentStore.Id)
                              as AvalaraTaxProvider;

            if (!_taxPluginManager.IsPluginActive(taxProvider))
            {
                return;
            }

            //create dummy order for the tax request
            var order = new Order {
                Customer = _workContext.CurrentCustomer
            };

            //addresses
            order.BillingAddress  = _workContext.CurrentCustomer.BillingAddress;
            order.ShippingAddress = _workContext.CurrentCustomer.ShippingAddress;
            if (_shippingSettings.AllowPickupInStore)
            {
                var pickupPoint = _genericAttributeService.GetAttribute <PickupPoint>(_workContext.CurrentCustomer,
                                                                                      NopCustomerDefaults.SelectedPickupPointAttribute, _storeContext.CurrentStore.Id);
                if (pickupPoint != null)
                {
                    var country = _countryService.GetCountryByTwoLetterIsoCode(pickupPoint.CountryCode);
                    order.PickupAddress = new Address
                    {
                        Address1      = pickupPoint.Address,
                        City          = pickupPoint.City,
                        Country       = country,
                        StateProvince = _stateProvinceService.GetStateProvinceByAbbreviation(pickupPoint.StateAbbreviation, country?.Id),
                        ZipPostalCode = pickupPoint.ZipPostalCode,
                        CreatedOnUtc  = DateTime.UtcNow,
                    };
                }
            }

            //checkout attributes
            order.CheckoutAttributesXml = _genericAttributeService.GetAttribute <string>(_workContext.CurrentCustomer,
                                                                                         NopCustomerDefaults.CheckoutAttributes, _storeContext.CurrentStore.Id);

            //shipping method
            var shippingRateComputationMethods = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id);

            order.OrderShippingExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, false, shippingRateComputationMethods) ?? 0;
            order.ShippingMethod       = _genericAttributeService.GetAttribute <ShippingOption>(_workContext.CurrentCustomer,
                                                                                                NopCustomerDefaults.SelectedShippingOptionAttribute, _storeContext.CurrentStore.Id)?.Name;

            //payment method
            var paymentMethod = _genericAttributeService.GetAttribute <string>(_workContext.CurrentCustomer,
                                                                               NopCustomerDefaults.SelectedPaymentMethodAttribute, _storeContext.CurrentStore.Id);
            var paymentFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethod);

            order.PaymentMethodAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentFee, false, _workContext.CurrentCustomer);
            order.PaymentMethodSystemName           = paymentMethod;

            //add discount amount
            _orderTotalCalculationService.GetShoppingCartSubTotal(cart, false, out var orderSubTotalDiscountExclTax, out _, out _, out _);
            order.OrderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax;

            //create dummy order items
            foreach (var cartItem in cart)
            {
                var orderItem = new OrderItem
                {
                    AttributesXml = cartItem.AttributesXml,
                    Product       = cartItem.Product,
                    Quantity      = cartItem.Quantity
                };

                var itemSubtotal = _priceCalculationService.GetSubTotal(cartItem, true, out _, out _, out _);
                orderItem.PriceExclTax = _taxService.GetProductPrice(cartItem.Product, itemSubtotal, false, _workContext.CurrentCustomer, out _);

                order.OrderItems.Add(orderItem);
            }

            //get tax details
            var taxTransaction = taxProvider.CreateOrderTaxTransaction(order, false);

            if (taxTransaction == null)
            {
                return;
            }

            //and save it for the further usage
            var taxDetails = new TaxDetails {
                TaxTotal = taxTransaction.totalTax
            };

            foreach (var item in taxTransaction.summary)
            {
                if (!item.rate.HasValue || !item.tax.HasValue)
                {
                    continue;
                }

                var taxRate  = item.rate.Value * 100;
                var taxValue = item.tax.Value;

                if (!taxDetails.TaxRates.ContainsKey(taxRate))
                {
                    taxDetails.TaxRates.Add(taxRate, taxValue);
                }
                else
                {
                    taxDetails.TaxRates[taxRate] = taxDetails.TaxRates[taxRate] + taxValue;
                }
            }
            _httpContextAccessor.HttpContext.Session.Set(AvalaraTaxDefaults.TaxDetailsSessionValue, taxDetails);
        }
        /// <summary>
        /// Invoke the widget view component
        /// </summary>
        /// <param name="widgetZone">Widget zone</param>
        /// <param name="additionalData">Additional parameters</param>
        /// <returns>View component result</returns>
        public IViewComponentResult Invoke(string widgetZone, object additionalData)
        {
            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName, _workContext.CurrentCustomer, _storeContext.CurrentStore.Id))
            {
                return(Content(string.Empty));
            }

            //ensure that it's a proper widget zone
            if (!widgetZone.Equals(PublicWidgetZones.CheckoutConfirmTop) && !widgetZone.Equals(PublicWidgetZones.OpCheckoutConfirmTop))
            {
                return(Content(string.Empty));
            }

            //ensure thet address validation is enabled
            if (!_avalaraTaxSettings.ValidateAddress)
            {
                return(Content(string.Empty));
            }

            //validate entered by customer addresses only
            var addressId = _taxSettings.TaxBasedOn == TaxBasedOn.BillingAddress
                ? _workContext.CurrentCustomer.BillingAddressId
                : _taxSettings.TaxBasedOn == TaxBasedOn.ShippingAddress
                ? _workContext.CurrentCustomer.ShippingAddressId
                : null;

            var address = _addressService.GetAddressById(addressId ?? 0);

            if (address == null)
            {
                return(Content(string.Empty));
            }

            //validate address
            var validationResult = _avalaraTaxManager.ValidateAddress(new AddressValidationInfo
            {
                city       = CommonHelper.EnsureMaximumLength(address.City, 50),
                country    = CommonHelper.EnsureMaximumLength(_countryService.GetCountryByAddress(address)?.TwoLetterIsoCode, 2),
                line1      = CommonHelper.EnsureMaximumLength(address.Address1, 50),
                line2      = CommonHelper.EnsureMaximumLength(address.Address2, 100),
                postalCode = CommonHelper.EnsureMaximumLength(address.ZipPostalCode, 11),
                region     = CommonHelper.EnsureMaximumLength(_stateProvinceService.GetStateProvinceByAddress(address)?.Abbreviation, 3),
                textCase   = TextCase.Mixed
            });

            //whether there are errors in validation result
            var errorDetails = validationResult.messages?
                               .Where(message => message.severity.Equals("Error", StringComparison.InvariantCultureIgnoreCase))
                               .Select(message => message.details) ?? new List <string>();

            if (errorDetails.Any())
            {
                var errorMessage = errorDetails.Aggregate(string.Empty, (message, errorDetail) => $"{message}{errorDetail}; ");

                //log errors
                _logger.Error($"Avalara tax provider error. {errorMessage}", customer: _workContext.CurrentCustomer);

                //and display error message to customer
                return(View("~/Plugins/Tax.Avalara/Views/Checkout/AddressValidation.cshtml", new AddressValidationModel
                {
                    Message = string.Format(_localizationService.GetResource("Plugins.Tax.Avalara.AddressValidation.Error"), WebUtility.HtmlEncode(errorMessage)),
                    IsError = true
                }));
            }

            //if there are no errors and no validated addresses, nothing to display
            if (!validationResult.validatedAddresses?.Any() ?? true)
            {
                return(Content(string.Empty));
            }

            //get validated address info
            var validatedAddressInfo = validationResult.validatedAddresses.FirstOrDefault();

            //create new address as a copy of address to validate and with details of the validated one
            var validatedAddress = _addressService.CloneAddress(address);

            validatedAddress.City            = validatedAddressInfo.city;
            validatedAddress.CountryId       = _countryService.GetCountryByTwoLetterIsoCode(validatedAddressInfo.country)?.Id;
            validatedAddress.Address1        = validatedAddressInfo.line1;
            validatedAddress.Address2        = validatedAddressInfo.line2;
            validatedAddress.ZipPostalCode   = validatedAddressInfo.postalCode;
            validatedAddress.StateProvinceId = _stateProvinceService.GetStateProvinceByAbbreviation(validatedAddressInfo.region)?.Id;

            //try to find an existing address with the same values
            var existingAddress = _addressService.FindAddress(_customerService.GetAddressesByCustomerId(_workContext.CurrentCustomer.Id).ToList(),
                                                              validatedAddress.FirstName, validatedAddress.LastName, validatedAddress.PhoneNumber,
                                                              validatedAddress.Email, validatedAddress.FaxNumber, validatedAddress.Company,
                                                              validatedAddress.Address1, validatedAddress.Address2, validatedAddress.City,
                                                              validatedAddress.County, validatedAddress.StateProvinceId, validatedAddress.ZipPostalCode,
                                                              validatedAddress.CountryId, validatedAddress.CustomAttributes);

            //if the found address is the same as address to validate, nothing to display
            if (address.Id == existingAddress?.Id)
            {
                return(Content(string.Empty));
            }

            //otherwise display to customer a confirmation dialog about address updating
            var model = new AddressValidationModel();

            if (existingAddress == null)
            {
                _addressService.InsertAddress(validatedAddress);
                model.AddressId    = validatedAddress.Id;
                model.IsNewAddress = true;
            }
            else
            {
                model.AddressId = existingAddress.Id;
            }

            model.Message = string.Format(_localizationService.GetResource("Plugins.Tax.Avalara.AddressValidation.Confirm"),
                                          GetAddressLine(address), GetAddressLine(existingAddress ?? validatedAddress));

            return(View("~/Plugins/Tax.Avalara/Views/Checkout/AddressValidation.cshtml", model));
        }
        public IActionResult ExportProducts(string selectedIds)
        {
            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return(RedirectToAction("List", "Product"));
            }

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

            //prepare exported items
            var productIds    = selectedIds?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(id => Convert.ToInt32(id)).ToArray();
            var exportedItems = new List <ItemModel>();

            foreach (var product in _productService.GetProductsByIds(productIds))
            {
                //find product combinations
                var combinations = _productAttributeService.GetAllProductAttributeCombinations(product.Id)
                                   .Where(combination => !string.IsNullOrEmpty(combination.Sku));

                //export items with specified SKU only
                if (string.IsNullOrEmpty(product.Sku) && !combinations.Any())
                {
                    continue;
                }

                //prepare common properties
                var taxCategory = _taxCategoryService.GetTaxCategoryById(product.TaxCategoryId);
                var taxCode     = CommonHelper.EnsureMaximumLength(taxCategory?.Name, 25);
                var description = CommonHelper.EnsureMaximumLength(product.ShortDescription ?? product.Name, 255);

                //add the product as exported item
                if (!string.IsNullOrEmpty(product.Sku))
                {
                    exportedItems.Add(new ItemModel
                    {
                        createdDate = DateTime.UtcNow,
                        description = description,
                        itemCode    = CommonHelper.EnsureMaximumLength(product.Sku, 50),
                        taxCode     = taxCode
                    });
                }

                //add product combinations
                exportedItems.AddRange(combinations.Select(combination => new ItemModel
                {
                    createdDate = DateTime.UtcNow,
                    description = description,
                    itemCode    = CommonHelper.EnsureMaximumLength(combination.Sku, 50),
                    taxCode     = taxCode
                }));
            }

            //get existing items
            var existingItemCodes = _avalaraTaxManager.GetItems()?.Select(item => item.itemCode).ToList() ?? new List <string>();

            //remove duplicates
            exportedItems = exportedItems.Where(item => !existingItemCodes.Contains(item.itemCode)).Distinct().ToList();

            //export items
            if (exportedItems.Any())
            {
                //create items and get the result
                var result = _avalaraTaxManager.CreateItems(exportedItems)?.Count;

                //display results
                if (result.HasValue && result > 0)
                {
                    _notificationService.SuccessNotification(string.Format(_localizationService.GetResource("Plugins.Tax.Avalara.Items.Export.Success"), result));
                }
                else
                {
                    _notificationService.ErrorNotification(_localizationService.GetResource("PPlugins.Tax.Avalara.Items.Export.Error"));
                }
            }
            else
            {
                _notificationService.SuccessNotification(_localizationService.GetResource("Plugins.Tax.Avalara.Items.Export.AlreadyExported"));
            }

            return(RedirectToAction("List", "Product"));
        }
Example #14
0
        /// <summary>
        /// Invoke the widget view component
        /// </summary>
        /// <param name="widgetZone">Widget zone</param>
        /// <param name="additionalData">Additional parameters</param>
        /// <returns>View component result</returns>
        public IViewComponentResult Invoke(string widgetZone, object additionalData)
        {
            //ensure that model is passed
            if (!(additionalData is BaseSmiEntityModel entityModel))
            {
                return(Content(string.Empty));
            }

            //ensure that Avalara tax provider is active
            if (!_taxPluginManager.IsPluginActive(AvalaraTaxDefaults.SystemName))
            {
                return(Content(string.Empty));
            }

            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return(Content(string.Empty));
            }

            //ensure that it's a proper widget zone
            if (!widgetZone.Equals(AdminWidgetZones.CustomerDetailsBlock) &&
                !widgetZone.Equals(AdminWidgetZones.CustomerRoleDetailsTop) &&
                !widgetZone.Equals(AdminWidgetZones.ProductDetailsBlock) &&
                !widgetZone.Equals(AdminWidgetZones.CheckoutAttributeDetailsBlock))
            {
                return(Content(string.Empty));
            }

            //get Avalara pre-defined entity use codes
            var cacheKey             = _cacheKeyService.PrepareKeyForDefaultCache(AvalaraTaxDefaults.EntityUseCodesCacheKey);
            var cachedEntityUseCodes = _staticCacheManager.Get(cacheKey, () => _avalaraTaxManager.GetEntityUseCodes());
            var entityUseCodes       = cachedEntityUseCodes?.Select(useCode => new SelectListItem
            {
                Value = useCode.code,
                Text  = $"{useCode.name} ({string.Join(", ", useCode.validCountries)})"
            }).ToList() ?? new List <SelectListItem>();

            //add the special item for 'undefined' with empty guid value
            var defaultValue = Guid.Empty.ToString();

            entityUseCodes.Insert(0, new SelectListItem
            {
                Value = defaultValue,
                Text  = _localizationService.GetResource("Plugins.Tax.Avalara.Fields.EntityUseCode.None")
            });

            //prepare model
            var model = new EntityUseCodeModel
            {
                Id             = entityModel.Id,
                EntityUseCodes = entityUseCodes
            };

            //get entity by the model identifier
            BaseEntity entity = null;

            if (widgetZone.Equals(AdminWidgetZones.CustomerDetailsBlock))
            {
                model.PrecedingElementId = nameof(CustomerModel.IsTaxExempt);
                entity = _customerService.GetCustomerById(entityModel.Id);
            }

            if (widgetZone.Equals(AdminWidgetZones.CustomerRoleDetailsTop))
            {
                model.PrecedingElementId = nameof(CustomerRoleModel.TaxExempt);
                entity = _customerService.GetCustomerRoleById(entityModel.Id);
            }

            if (widgetZone.Equals(AdminWidgetZones.ProductDetailsBlock))
            {
                model.PrecedingElementId = nameof(ProductModel.IsTaxExempt);
                entity = _productService.GetProductById(entityModel.Id);
            }

            if (widgetZone.Equals(AdminWidgetZones.CheckoutAttributeDetailsBlock))
            {
                model.PrecedingElementId = nameof(CheckoutAttributeModel.IsTaxExempt);
                entity = _checkoutAttributeService.GetCheckoutAttributeById(entityModel.Id);
            }

            //try to get previously saved entity use code
            model.AvalaraEntityUseCode = entity == null ? defaultValue :
                                         _genericAttributeService.GetAttribute <string>(entity, AvalaraTaxDefaults.EntityUseCodeAttribute);

            return(View("~/Plugins/Tax.Avalara/Views/EntityUseCode/EntityUseCode.cshtml", model));
        }
        /// <summary>
        /// Prepare plugins enabled warning model
        /// </summary>
        /// <param name="models">List of system warning models</param>
        protected virtual void PreparePluginsEnabledWarningModel(List <SystemWarningModel> models)
        {
            var plugins = _pluginService.GetPlugins <IPlugin>();

            var notEnabled            = new List <string>();
            var notEnabledSystemNames = new List <string>();

            foreach (var plugin in plugins)
            {
                var isEnabled = true;

                switch (plugin)
                {
                case IPaymentMethod paymentMethod:
                    isEnabled = _paymentPluginManager.IsPluginActive(paymentMethod);
                    break;

                case IShippingRateComputationMethod shippingRateComputationMethod:
                    isEnabled = _shippingPluginManager.IsPluginActive(shippingRateComputationMethod);
                    break;

                case IPickupPointProvider pickupPointProvider:
                    isEnabled = _pickupPluginManager.IsPluginActive(pickupPointProvider);
                    break;

                case ITaxProvider taxProvider:
                    isEnabled = _taxPluginManager.IsPluginActive(taxProvider);
                    break;

                case IExternalAuthenticationMethod externalAuthenticationMethod:
                    isEnabled = _authenticationPluginManager.IsPluginActive(externalAuthenticationMethod);
                    break;

                case IWidgetPlugin widgetPlugin:
                    isEnabled = _widgetPluginManager.IsPluginActive(widgetPlugin);
                    break;

                case IExchangeRateProvider exchangeRateProvider:
                    isEnabled = _exchangeRatePluginManager.IsPluginActive(exchangeRateProvider);
                    break;
                }

                if (isEnabled)
                {
                    continue;
                }

                notEnabled.Add(plugin.PluginDescriptor.FriendlyName);
                notEnabledSystemNames.Add(plugin.PluginDescriptor.SystemName);
            }

            if (notEnabled.Any())
            {
                //get URL helper
                var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);

                models.Add(new SystemWarningModel
                {
                    Level      = SystemWarningLevel.Warning,
                    DontEncode = true,
                    Text       = $"{_localizationService.GetResource("Admin.System.Warnings.PluginNotEnabled")}: {string.Join(", ", notEnabled)} (<a href=\"{urlHelper.Action("UninstallAndDeleteUnusedPlugins", "Plugin", new { names=notEnabledSystemNames.ToArray() })}\">{_localizationService.GetResource("Admin.System.Warnings.PluginNotEnabled.AutoFixAndRestart")}</a>)"
                });
            }
        }