Пример #1
0
        public async Task <bool> IsAddressValidAsync(AddressValidationModel addressModel)
        {
            var isAddressValid = false;

            try
            {
                isAddressValid = await _partnerOperations.UserPartnerOperations.Validations.IsAddressValidAsync(
                    new Address
                {
                    AddressLine1 = addressModel.AddressLine1,
                    AddressLine2 = addressModel.AddressLine2,
                    City         = addressModel.City,
                    State        = addressModel.State,
                    Country      = addressModel.Country,
                    PostalCode   = addressModel.PostalCode,
                    PhoneNumber  = addressModel.PhoneNumber,
                });
            }
            catch (Exception ex)
            {
                this.Log().Error("Error validating user address", ex);
            }
            return(isAddressValid);
        }
        /// <summary>
        /// Invoke the widget view component
        /// </summary>
        /// <param name="widgetZone">Widget zone</param>
        /// <param name="additionalData">Additional parameters</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the view component result
        /// </returns>
        public async Task <IViewComponentResult> InvokeAsync(string widgetZone, object additionalData)
        {
            //ensure that Avalara tax provider is active
            var customer = await _workContext.GetCurrentCustomerAsync();

            if (!await _taxPluginManager.IsPluginActiveAsync(AvalaraTaxDefaults.SystemName, customer))
            {
                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
                ? customer.BillingAddressId
                : _taxSettings.TaxBasedOn == TaxBasedOn.ShippingAddress
                ? customer.ShippingAddressId
                : null;

            var address = await _addressService.GetAddressByIdAsync(addressId ?? 0);

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

            //validate address
            var validationResult = await _avalaraTaxManager.ValidateAddressAsync(address);

            //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())
            {
                //display error message to customer
                return(View("~/Plugins/Tax.Avalara/Views/Checkout/AddressValidation.cshtml", new AddressValidationModel
                {
                    Message = string.Format(await _localizationService.GetResourceAsync("Plugins.Tax.Avalara.AddressValidation.Error"),
                                            WebUtility.HtmlEncode(string.Join("; ", errorDetails))),
                    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       = (await _countryService.GetCountryByTwoLetterIsoCodeAsync(validatedAddressInfo.country))?.Id;
            validatedAddress.Address1        = validatedAddressInfo.line1;
            validatedAddress.Address2        = validatedAddressInfo.line2;
            validatedAddress.ZipPostalCode   = validatedAddressInfo.postalCode;
            validatedAddress.StateProvinceId = (await _stateProvinceService.GetStateProvinceByAbbreviationAsync(validatedAddressInfo.region))?.Id;

            //try to find an existing address with the same values
            var existingAddress = _addressService.FindAddress((await _customerService.GetAddressesByCustomerIdAsync(customer.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)
            {
                await _addressService.InsertAddressAsync(validatedAddress);

                model.AddressId    = validatedAddress.Id;
                model.IsNewAddress = true;
            }
            else
            {
                model.AddressId = existingAddress.Id;
            }

            async Task <string> getAddressLineAsync(Address address) =>
            WebUtility.HtmlEncode($"{(!string.IsNullOrEmpty(address.Address1) ? $"{address.Address1}, " : string.Empty)}" +
                                  $"{(!string.IsNullOrEmpty(address.Address2) ? $"{address.Address2}, " : string.Empty)}" +
                                  $"{(!string.IsNullOrEmpty(address.City) ? $"{address.City}, " : string.Empty)}" +
                                  $"{(await _stateProvinceService.GetStateProvinceByAddressAsync(address) is StateProvince stateProvince ? $"{stateProvince.Name}, " : string.Empty)}" +
                                  $"{(await _countryService.GetCountryByAddressAsync(address) is Country country ? $"{country.Name}, " : string.Empty)}" +
                                  $"{(!string.IsNullOrEmpty(address.ZipPostalCode) ? $"{address.ZipPostalCode}, " : string.Empty)}"
                                  .TrimEnd(' ').TrimEnd(','));

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

            return(View("~/Plugins/Tax.Avalara/Views/Checkout/AddressValidation.cshtml", model));
        }
        /// <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));
        }