Try your search with a different keyword or use * as a wildcard.
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Nop.Core;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Directory;
using Nop.Core.Domain.Tax;
using Nop.Plugin.Tax.Avalara.Models.Checkout;
using Nop.Plugin.Tax.Avalara.Services;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Localization;
using Nop.Services.Tax;
using Nop.Web.Framework.Components;
using Nop.Web.Framework.Infrastructure;
namespace Nop.Plugin.Tax.Avalara.Components;
///
/// Represents a view component to validate entered address and display a confirmation dialog on the checkout page
///
public class AddressValidationViewComponent : NopViewComponent
{
#region Fields
protected readonly AvalaraTaxManager _avalaraTaxManager;
protected readonly AvalaraTaxSettings _avalaraTaxSettings;
protected readonly IAddressService _addressService;
protected readonly ICountryService _countryService;
protected readonly ICustomerService _customerService;
protected readonly ILocalizationService _localizationService;
protected readonly IStateProvinceService _stateProvinceService;
protected readonly ITaxPluginManager _taxPluginManager;
protected readonly IWorkContext _workContext;
protected readonly TaxSettings _taxSettings;
#endregion
#region Ctor
public AddressValidationViewComponent(AvalaraTaxManager avalaraTaxManager,
AvalaraTaxSettings avalaraTaxSettings,
IAddressService addressService,
ICountryService countryService,
ICustomerService customerService,
ILocalizationService localizationService,
IStateProvinceService stateProvinceService,
ITaxPluginManager taxPluginManager,
IWorkContext workContext,
TaxSettings taxSettings)
{
_avalaraTaxManager = avalaraTaxManager;
_avalaraTaxSettings = avalaraTaxSettings;
_addressService = addressService;
_countryService = countryService;
_customerService = customerService;
_localizationService = localizationService;
_stateProvinceService = stateProvinceService;
_taxPluginManager = taxPluginManager;
_workContext = workContext;
_taxSettings = taxSettings;
}
#endregion
#region Methods
///
/// Invoke the widget view component
///
/// Widget zone
/// Additional parameters
///
/// A task that represents the asynchronous operation
/// The task result contains the view component result
///
public async Task 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();
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.First();
//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 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);
}
#endregion
}