Try your search with a different keyword or use * as a wildcard.
using System.Globalization;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Forums;
using Nop.Core.Domain.Gdpr;
using Nop.Core.Domain.Messages;
using Nop.Core.Domain.Tax;
using Nop.Core.Events;
using Nop.Services.Attributes;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.ExportImport;
using Nop.Services.Forums;
using Nop.Services.Gdpr;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Messages;
using Nop.Services.Orders;
using Nop.Services.Security;
using Nop.Services.Stores;
using Nop.Services.Tax;
using Nop.Web.Areas.Admin.Factories;
using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions;
using Nop.Web.Areas.Admin.Models.Customers;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc;
using Nop.Web.Framework.Mvc.Filters;
namespace Nop.Web.Areas.Admin.Controllers;
public partial class CustomerController : BaseAdminController
{
#region Fields
protected readonly CustomerSettings _customerSettings;
protected readonly DateTimeSettings _dateTimeSettings;
protected readonly EmailAccountSettings _emailAccountSettings;
protected readonly ForumSettings _forumSettings;
protected readonly GdprSettings _gdprSettings;
protected readonly IAddressService _addressService;
protected readonly IAttributeParser _addressAttributeParser;
protected readonly IAttributeParser _customerAttributeParser;
protected readonly IAttributeService _customerAttributeService;
protected readonly ICustomerActivityService _customerActivityService;
protected readonly ICustomerModelFactory _customerModelFactory;
protected readonly ICustomerRegistrationService _customerRegistrationService;
protected readonly ICustomerService _customerService;
protected readonly IDateTimeHelper _dateTimeHelper;
protected readonly IEmailAccountService _emailAccountService;
protected readonly IEventPublisher _eventPublisher;
protected readonly IExportManager _exportManager;
protected readonly IForumService _forumService;
protected readonly IGdprService _gdprService;
protected readonly IGenericAttributeService _genericAttributeService;
protected readonly IImportManager _importManager;
protected readonly ILocalizationService _localizationService;
protected readonly INewsLetterSubscriptionService _newsLetterSubscriptionService;
protected readonly INotificationService _notificationService;
protected readonly IPermissionService _permissionService;
protected readonly IQueuedEmailService _queuedEmailService;
protected readonly IRewardPointService _rewardPointService;
protected readonly IStoreContext _storeContext;
protected readonly IStoreService _storeService;
protected readonly ITaxService _taxService;
protected readonly IWorkContext _workContext;
protected readonly IWorkflowMessageService _workflowMessageService;
protected readonly TaxSettings _taxSettings;
private static readonly char[] _separator = [','];
#endregion
#region Ctor
public CustomerController(CustomerSettings customerSettings,
DateTimeSettings dateTimeSettings,
EmailAccountSettings emailAccountSettings,
ForumSettings forumSettings,
GdprSettings gdprSettings,
IAddressService addressService,
IAttributeParser addressAttributeParser,
IAttributeParser customerAttributeParser,
IAttributeService customerAttributeService,
ICustomerActivityService customerActivityService,
ICustomerModelFactory customerModelFactory,
ICustomerRegistrationService customerRegistrationService,
ICustomerService customerService,
IDateTimeHelper dateTimeHelper,
IEmailAccountService emailAccountService,
IEventPublisher eventPublisher,
IExportManager exportManager,
IForumService forumService,
IGdprService gdprService,
IGenericAttributeService genericAttributeService,
IImportManager importManager,
ILocalizationService localizationService,
INewsLetterSubscriptionService newsLetterSubscriptionService,
INotificationService notificationService,
IPermissionService permissionService,
IQueuedEmailService queuedEmailService,
IRewardPointService rewardPointService,
IStoreContext storeContext,
IStoreService storeService,
ITaxService taxService,
IWorkContext workContext,
IWorkflowMessageService workflowMessageService,
TaxSettings taxSettings)
{
_customerSettings = customerSettings;
_dateTimeSettings = dateTimeSettings;
_emailAccountSettings = emailAccountSettings;
_forumSettings = forumSettings;
_gdprSettings = gdprSettings;
_addressService = addressService;
_addressAttributeParser = addressAttributeParser;
_customerAttributeParser = customerAttributeParser;
_customerAttributeService = customerAttributeService;
_customerActivityService = customerActivityService;
_customerModelFactory = customerModelFactory;
_customerRegistrationService = customerRegistrationService;
_customerService = customerService;
_dateTimeHelper = dateTimeHelper;
_emailAccountService = emailAccountService;
_eventPublisher = eventPublisher;
_exportManager = exportManager;
_forumService = forumService;
_gdprService = gdprService;
_genericAttributeService = genericAttributeService;
_importManager = importManager;
_localizationService = localizationService;
_newsLetterSubscriptionService = newsLetterSubscriptionService;
_notificationService = notificationService;
_permissionService = permissionService;
_queuedEmailService = queuedEmailService;
_rewardPointService = rewardPointService;
_storeContext = storeContext;
_storeService = storeService;
_taxService = taxService;
_workContext = workContext;
_workflowMessageService = workflowMessageService;
_taxSettings = taxSettings;
}
#endregion
#region Utilities
protected virtual async Task ValidateCustomerRolesAsync(IList customerRoles, IList existingCustomerRoles)
{
ArgumentNullException.ThrowIfNull(customerRoles);
ArgumentNullException.ThrowIfNull(existingCustomerRoles);
//check ACL permission to manage customer roles
var rolesToAdd = customerRoles.Except(existingCustomerRoles, new CustomerRoleComparerByName());
var rolesToDelete = existingCustomerRoles.Except(customerRoles, new CustomerRoleComparerByName());
if (rolesToAdd.Any(role => role.SystemName != NopCustomerDefaults.RegisteredRoleName) || rolesToDelete.Any())
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageAcl))
return await _localizationService.GetResourceAsync("Admin.Customers.Customers.CustomerRolesManagingError");
}
//ensure a customer is not added to both 'Guests' and 'Registered' customer roles
//ensure that a customer is in at least one required role ('Guests' and 'Registered')
var isInGuestsRole = customerRoles.FirstOrDefault(cr => cr.SystemName == NopCustomerDefaults.GuestsRoleName) != null;
var isInRegisteredRole = customerRoles.FirstOrDefault(cr => cr.SystemName == NopCustomerDefaults.RegisteredRoleName) != null;
if (isInGuestsRole && isInRegisteredRole)
return await _localizationService.GetResourceAsync("Admin.Customers.Customers.GuestsAndRegisteredRolesError");
if (!isInGuestsRole && !isInRegisteredRole)
return await _localizationService.GetResourceAsync("Admin.Customers.Customers.AddCustomerToGuestsOrRegisteredRoleError");
//no errors
return string.Empty;
}
protected virtual async Task ParseCustomCustomerAttributesAsync(IFormCollection form)
{
ArgumentNullException.ThrowIfNull(form);
var attributesXml = string.Empty;
var customerAttributes = await _customerAttributeService.GetAllAttributesAsync();
foreach (var attribute in customerAttributes)
{
var controlId = $"{NopCustomerServicesDefaults.CustomerAttributePrefix}{attribute.Id}";
StringValues ctrlAttributes;
switch (attribute.AttributeControlType)
{
case AttributeControlType.DropdownList:
case AttributeControlType.RadioList:
ctrlAttributes = form[controlId];
if (!StringValues.IsNullOrEmpty(ctrlAttributes))
{
var selectedAttributeId = int.Parse(ctrlAttributes);
if (selectedAttributeId > 0)
attributesXml = _customerAttributeParser.AddAttribute(attributesXml,
attribute, selectedAttributeId.ToString());
}
break;
case AttributeControlType.Checkboxes:
var cblAttributes = form[controlId];
if (!StringValues.IsNullOrEmpty(cblAttributes))
{
foreach (var item in cblAttributes.ToString()
.Split(_separator, StringSplitOptions.RemoveEmptyEntries))
{
var selectedAttributeId = int.Parse(item);
if (selectedAttributeId > 0)
attributesXml = _customerAttributeParser.AddAttribute(attributesXml,
attribute, selectedAttributeId.ToString());
}
}
break;
case AttributeControlType.ReadonlyCheckboxes:
//load read-only (already server-side selected) values
var attributeValues = await _customerAttributeService.GetAttributeValuesAsync(attribute.Id);
foreach (var selectedAttributeId in attributeValues
.Where(v => v.IsPreSelected)
.Select(v => v.Id)
.ToList())
{
attributesXml = _customerAttributeParser.AddAttribute(attributesXml,
attribute, selectedAttributeId.ToString());
}
break;
case AttributeControlType.TextBox:
case AttributeControlType.MultilineTextbox:
ctrlAttributes = form[controlId];
if (!StringValues.IsNullOrEmpty(ctrlAttributes))
{
var enteredText = ctrlAttributes.ToString().Trim();
attributesXml = _customerAttributeParser.AddAttribute(attributesXml,
attribute, enteredText);
}
break;
case AttributeControlType.Datepicker:
case AttributeControlType.ColorSquares:
case AttributeControlType.ImageSquares:
case AttributeControlType.FileUpload:
//not supported customer attributes
default:
break;
}
}
return attributesXml;
}
protected virtual async Task SecondAdminAccountExistsAsync(Customer customer)
{
var customers = await _customerService.GetAllCustomersAsync(customerRoleIds: [(await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.AdministratorsRoleName)).Id]);
return customers.Any(c => c.Active && c.Id != customer.Id);
}
#endregion
#region Customers
public virtual IActionResult Index()
{
return RedirectToAction("List");
}
public virtual async Task List()
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//prepare model
var model = await _customerModelFactory.PrepareCustomerSearchModelAsync(new CustomerSearchModel());
return View(model);
}
[HttpPost]
public virtual async Task CustomerList(CustomerSearchModel searchModel)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return await AccessDeniedDataTablesJson();
//prepare model
var model = await _customerModelFactory.PrepareCustomerListModelAsync(searchModel);
return Json(model);
}
public virtual async Task Create()
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//prepare model
var model = await _customerModelFactory.PrepareCustomerModelAsync(new CustomerModel(), null);
return View(model);
}
[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
[FormValueRequired("save", "save-continue")]
public virtual async Task Create(CustomerModel model, bool continueEditing, IFormCollection form)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
if (!string.IsNullOrWhiteSpace(model.Email) && await _customerService.GetCustomerByEmailAsync(model.Email) != null)
ModelState.AddModelError(string.Empty, "Email is already registered");
if (!string.IsNullOrWhiteSpace(model.Username) && _customerSettings.UsernamesEnabled &&
await _customerService.GetCustomerByUsernameAsync(model.Username) != null)
{
ModelState.AddModelError(string.Empty, "Username is already registered");
}
//validate customer roles
var allCustomerRoles = await _customerService.GetAllCustomerRolesAsync(true);
var newCustomerRoles = new List();
foreach (var customerRole in allCustomerRoles)
if (model.SelectedCustomerRoleIds.Contains(customerRole.Id))
newCustomerRoles.Add(customerRole);
var customerRolesError = await ValidateCustomerRolesAsync(newCustomerRoles, new List());
if (!string.IsNullOrEmpty(customerRolesError))
{
ModelState.AddModelError(string.Empty, customerRolesError);
_notificationService.ErrorNotification(customerRolesError);
}
// Ensure that valid email address is entered if Registered role is checked to avoid registered customers with empty email address
if (newCustomerRoles.Any() && newCustomerRoles.FirstOrDefault(c => c.SystemName == NopCustomerDefaults.RegisteredRoleName) != null &&
!CommonHelper.IsValidEmail(model.Email))
{
ModelState.AddModelError(string.Empty, await _localizationService.GetResourceAsync("Admin.Customers.Customers.ValidEmailRequiredRegisteredRole"));
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.ValidEmailRequiredRegisteredRole"));
}
//custom customer attributes
var customerAttributesXml = await ParseCustomCustomerAttributesAsync(form);
if (newCustomerRoles.Any() && newCustomerRoles.FirstOrDefault(c => c.SystemName == NopCustomerDefaults.RegisteredRoleName) != null)
{
var customerAttributeWarnings = await _customerAttributeParser.GetAttributeWarningsAsync(customerAttributesXml);
foreach (var error in customerAttributeWarnings)
{
ModelState.AddModelError(string.Empty, error);
}
}
if (ModelState.IsValid)
{
//fill entity from model
var customer = model.ToEntity();
var currentStore = await _storeContext.GetCurrentStoreAsync();
customer.CustomerGuid = Guid.NewGuid();
customer.CreatedOnUtc = DateTime.UtcNow;
customer.LastActivityDateUtc = DateTime.UtcNow;
customer.RegisteredInStoreId = currentStore.Id;
//form fields
if (_dateTimeSettings.AllowCustomersToSetTimeZone)
customer.TimeZoneId = model.TimeZoneId;
if (_customerSettings.GenderEnabled)
customer.Gender = model.Gender;
if (_customerSettings.FirstNameEnabled)
customer.FirstName = model.FirstName;
if (_customerSettings.LastNameEnabled)
customer.LastName = model.LastName;
if (_customerSettings.DateOfBirthEnabled)
customer.DateOfBirth = model.DateOfBirth;
if (_customerSettings.CompanyEnabled)
customer.Company = model.Company;
if (_customerSettings.StreetAddressEnabled)
customer.StreetAddress = model.StreetAddress;
if (_customerSettings.StreetAddress2Enabled)
customer.StreetAddress2 = model.StreetAddress2;
if (_customerSettings.ZipPostalCodeEnabled)
customer.ZipPostalCode = model.ZipPostalCode;
if (_customerSettings.CityEnabled)
customer.City = model.City;
if (_customerSettings.CountyEnabled)
customer.County = model.County;
if (_customerSettings.CountryEnabled)
customer.CountryId = model.CountryId;
if (_customerSettings.CountryEnabled && _customerSettings.StateProvinceEnabled)
customer.StateProvinceId = model.StateProvinceId;
if (_customerSettings.PhoneEnabled)
customer.Phone = model.Phone;
if (_customerSettings.FaxEnabled)
customer.Fax = model.Fax;
customer.CustomCustomerAttributesXML = customerAttributesXml;
await _customerService.InsertCustomerAsync(customer);
//newsletter subscriptions
if (!string.IsNullOrEmpty(customer.Email))
{
var allStores = await _storeService.GetAllStoresAsync();
foreach (var store in allStores)
{
var newsletterSubscription = await _newsLetterSubscriptionService
.GetNewsLetterSubscriptionByEmailAndStoreIdAsync(customer.Email, store.Id);
if (model.SelectedNewsletterSubscriptionStoreIds != null &&
model.SelectedNewsletterSubscriptionStoreIds.Contains(store.Id))
{
//subscribed
if (newsletterSubscription == null)
{
await _newsLetterSubscriptionService.InsertNewsLetterSubscriptionAsync(new NewsLetterSubscription
{
NewsLetterSubscriptionGuid = Guid.NewGuid(),
Email = customer.Email,
Active = true,
StoreId = store.Id,
LanguageId = customer.LanguageId ?? store.DefaultLanguageId,
CreatedOnUtc = DateTime.UtcNow
});
}
}
else
{
//not subscribed
if (newsletterSubscription != null)
{
await _newsLetterSubscriptionService.DeleteNewsLetterSubscriptionAsync(newsletterSubscription);
}
}
}
}
//password
if (!string.IsNullOrWhiteSpace(model.Password))
{
var changePassRequest = new ChangePasswordRequest(model.Email, false, _customerSettings.DefaultPasswordFormat, model.Password);
var changePassResult = await _customerRegistrationService.ChangePasswordAsync(changePassRequest);
if (!changePassResult.Success)
{
foreach (var changePassError in changePassResult.Errors)
_notificationService.ErrorNotification(changePassError);
}
}
//customer roles
foreach (var customerRole in newCustomerRoles)
{
//ensure that the current customer cannot add to "Administrators" system role if he's not an admin himself
if (customerRole.SystemName == NopCustomerDefaults.AdministratorsRoleName && !await _customerService.IsAdminAsync(await _workContext.GetCurrentCustomerAsync()))
continue;
await _customerService.AddCustomerRoleMappingAsync(new CustomerCustomerRoleMapping { CustomerId = customer.Id, CustomerRoleId = customerRole.Id });
}
await _customerService.UpdateCustomerAsync(customer);
//ensure that a customer with a vendor associated is not in "Administrators" role
//otherwise, he won't have access to other functionality in admin area
if (await _customerService.IsAdminAsync(customer) && customer.VendorId > 0)
{
customer.VendorId = 0;
await _customerService.UpdateCustomerAsync(customer);
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.AdminCouldNotbeVendor"));
}
//ensure that a customer in the Vendors role has a vendor account associated.
//otherwise, he will have access to ALL products
if (await _customerService.IsVendorAsync(customer) && customer.VendorId == 0)
{
var vendorRole = await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.VendorsRoleName);
await _customerService.RemoveCustomerRoleMappingAsync(customer, vendorRole);
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.CannotBeInVendoRoleWithoutVendorAssociated"));
}
//activity log
await _customerActivityService.InsertActivityAsync("AddNewCustomer",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.AddNewCustomer"), customer.Id), customer);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.Added"));
if (!continueEditing)
return RedirectToAction("List");
return RedirectToAction("Edit", new { id = customer.Id });
}
//prepare model
model = await _customerModelFactory.PrepareCustomerModelAsync(model, null, true);
//if we got this far, something failed, redisplay form
return View(model);
}
public virtual async Task Edit(int id)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(id);
if (customer == null || customer.Deleted)
return RedirectToAction("List");
//prepare model
var model = await _customerModelFactory.PrepareCustomerModelAsync(null, customer);
return View(model);
}
[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
[FormValueRequired("save", "save-continue")]
public virtual async Task Edit(CustomerModel model, bool continueEditing, IFormCollection form)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null || customer.Deleted)
return RedirectToAction("List");
//validate customer roles
var allCustomerRoles = await _customerService.GetAllCustomerRolesAsync(true);
var newCustomerRoles = new List();
foreach (var customerRole in allCustomerRoles)
if (model.SelectedCustomerRoleIds.Contains(customerRole.Id))
newCustomerRoles.Add(customerRole);
var customerRolesError = await ValidateCustomerRolesAsync(newCustomerRoles, await _customerService.GetCustomerRolesAsync(customer));
if (!string.IsNullOrEmpty(customerRolesError))
{
ModelState.AddModelError(string.Empty, customerRolesError);
_notificationService.ErrorNotification(customerRolesError);
}
// Ensure that valid email address is entered if Registered role is checked to avoid registered customers with empty email address
if (newCustomerRoles.Any() && newCustomerRoles.FirstOrDefault(c => c.SystemName == NopCustomerDefaults.RegisteredRoleName) != null &&
!CommonHelper.IsValidEmail(model.Email))
{
ModelState.AddModelError(string.Empty, await _localizationService.GetResourceAsync("Admin.Customers.Customers.ValidEmailRequiredRegisteredRole"));
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.ValidEmailRequiredRegisteredRole"));
}
//custom customer attributes
var customerAttributesXml = await ParseCustomCustomerAttributesAsync(form);
if (newCustomerRoles.Any() && newCustomerRoles.FirstOrDefault(c => c.SystemName == NopCustomerDefaults.RegisteredRoleName) != null)
{
var customerAttributeWarnings = await _customerAttributeParser.GetAttributeWarningsAsync(customerAttributesXml);
foreach (var error in customerAttributeWarnings)
{
ModelState.AddModelError(string.Empty, error);
}
}
if (ModelState.IsValid)
{
try
{
customer.AdminComment = model.AdminComment;
customer.IsTaxExempt = model.IsTaxExempt;
//prevent deactivation of the last active administrator
if (!await _customerService.IsAdminAsync(customer) || model.Active || await SecondAdminAccountExistsAsync(customer))
customer.Active = model.Active;
else
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.AdminAccountShouldExists.Deactivate"));
//email
if (!string.IsNullOrWhiteSpace(model.Email))
await _customerRegistrationService.SetEmailAsync(customer, model.Email, false);
else
customer.Email = model.Email;
//username
if (_customerSettings.UsernamesEnabled)
{
if (!string.IsNullOrWhiteSpace(model.Username))
await _customerRegistrationService.SetUsernameAsync(customer, model.Username);
else
customer.Username = model.Username;
}
//VAT number
if (_taxSettings.EuVatEnabled)
{
var prevVatNumber = customer.VatNumber;
customer.VatNumber = model.VatNumber;
//set VAT number status
if (!string.IsNullOrEmpty(model.VatNumber))
{
if (!model.VatNumber.Equals(prevVatNumber, StringComparison.InvariantCultureIgnoreCase))
{
customer.VatNumberStatusId = (int)(await _taxService.GetVatNumberStatusAsync(model.VatNumber)).vatNumberStatus;
}
}
else
customer.VatNumberStatusId = (int)VatNumberStatus.Empty;
}
//vendor
customer.VendorId = model.VendorId;
//form fields
if (_dateTimeSettings.AllowCustomersToSetTimeZone)
customer.TimeZoneId = model.TimeZoneId;
if (_customerSettings.GenderEnabled)
customer.Gender = model.Gender;
if (_customerSettings.FirstNameEnabled)
customer.FirstName = model.FirstName;
if (_customerSettings.LastNameEnabled)
customer.LastName = model.LastName;
if (_customerSettings.DateOfBirthEnabled)
customer.DateOfBirth = model.DateOfBirth;
if (_customerSettings.CompanyEnabled)
customer.Company = model.Company;
if (_customerSettings.StreetAddressEnabled)
customer.StreetAddress = model.StreetAddress;
if (_customerSettings.StreetAddress2Enabled)
customer.StreetAddress2 = model.StreetAddress2;
if (_customerSettings.ZipPostalCodeEnabled)
customer.ZipPostalCode = model.ZipPostalCode;
if (_customerSettings.CityEnabled)
customer.City = model.City;
if (_customerSettings.CountyEnabled)
customer.County = model.County;
if (_customerSettings.CountryEnabled)
customer.CountryId = model.CountryId;
if (_customerSettings.CountryEnabled && _customerSettings.StateProvinceEnabled)
customer.StateProvinceId = model.StateProvinceId;
if (_customerSettings.PhoneEnabled)
customer.Phone = model.Phone;
if (_customerSettings.FaxEnabled)
customer.Fax = model.Fax;
//custom customer attributes
customer.CustomCustomerAttributesXML = customerAttributesXml;
//newsletter subscriptions
if (!string.IsNullOrEmpty(customer.Email))
{
var allStores = await _storeService.GetAllStoresAsync();
foreach (var store in allStores)
{
var newsletterSubscription = await _newsLetterSubscriptionService
.GetNewsLetterSubscriptionByEmailAndStoreIdAsync(customer.Email, store.Id);
if (model.SelectedNewsletterSubscriptionStoreIds != null &&
model.SelectedNewsletterSubscriptionStoreIds.Contains(store.Id))
{
//subscribed
if (newsletterSubscription == null)
{
await _newsLetterSubscriptionService.InsertNewsLetterSubscriptionAsync(new NewsLetterSubscription
{
NewsLetterSubscriptionGuid = Guid.NewGuid(),
Email = customer.Email,
Active = true,
StoreId = store.Id,
LanguageId = customer.LanguageId ?? store.DefaultLanguageId,
CreatedOnUtc = DateTime.UtcNow
});
}
}
else
{
//not subscribed
if (newsletterSubscription != null)
{
await _newsLetterSubscriptionService.DeleteNewsLetterSubscriptionAsync(newsletterSubscription);
}
}
}
}
var currentCustomerRoleIds = await _customerService.GetCustomerRoleIdsAsync(customer, true);
//customer roles
foreach (var customerRole in allCustomerRoles)
{
//ensure that the current customer cannot add/remove to/from "Administrators" system role
//if he's not an admin himself
if (customerRole.SystemName == NopCustomerDefaults.AdministratorsRoleName &&
!await _customerService.IsAdminAsync(await _workContext.GetCurrentCustomerAsync()))
continue;
if (model.SelectedCustomerRoleIds.Contains(customerRole.Id))
{
//new role
if (currentCustomerRoleIds.All(roleId => roleId != customerRole.Id))
await _customerService.AddCustomerRoleMappingAsync(new CustomerCustomerRoleMapping { CustomerId = customer.Id, CustomerRoleId = customerRole.Id });
}
else
{
//prevent attempts to delete the administrator role from the user, if the user is the last active administrator
if (customerRole.SystemName == NopCustomerDefaults.AdministratorsRoleName && !await SecondAdminAccountExistsAsync(customer))
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.AdminAccountShouldExists.DeleteRole"));
continue;
}
//remove role
if (currentCustomerRoleIds.Any(roleId => roleId == customerRole.Id))
await _customerService.RemoveCustomerRoleMappingAsync(customer, customerRole);
}
}
await _customerService.UpdateCustomerAsync(customer);
//ensure that a customer with a vendor associated is not in "Administrators" role
//otherwise, he won't have access to the other functionality in admin area
if (await _customerService.IsAdminAsync(customer) && customer.VendorId > 0)
{
customer.VendorId = 0;
await _customerService.UpdateCustomerAsync(customer);
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.AdminCouldNotbeVendor"));
}
//ensure that a customer in the Vendors role has a vendor account associated.
//otherwise, he will have access to ALL products
if (await _customerService.IsVendorAsync(customer) && customer.VendorId == 0)
{
var vendorRole = await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.VendorsRoleName);
await _customerService.RemoveCustomerRoleMappingAsync(customer, vendorRole);
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.CannotBeInVendoRoleWithoutVendorAssociated"));
}
//activity log
await _customerActivityService.InsertActivityAsync("EditCustomer",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.EditCustomer"), customer.Id), customer);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.Updated"));
if (!continueEditing)
return RedirectToAction("List");
return RedirectToAction("Edit", new { id = customer.Id });
}
catch (Exception exc)
{
_notificationService.ErrorNotification(exc.Message);
}
}
//prepare model
model = await _customerModelFactory.PrepareCustomerModelAsync(model, customer, true);
//if we got this far, something failed, redisplay form
return View(model);
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("changepassword")]
public virtual async Task ChangePassword(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
//ensure that the current customer cannot change passwords of "Administrators" if he's not an admin himself
if (await _customerService.IsAdminAsync(customer) && !await _customerService.IsAdminAsync(await _workContext.GetCurrentCustomerAsync()))
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.OnlyAdminCanChangePassword"));
return RedirectToAction("Edit", new { id = customer.Id });
}
var changePassRequest = new ChangePasswordRequest(customer.Email,
false, _customerSettings.DefaultPasswordFormat, model.Password);
var changePassResult = await _customerRegistrationService.ChangePasswordAsync(changePassRequest);
if (changePassResult.Success)
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.PasswordChanged"));
else
foreach (var error in changePassResult.Errors)
_notificationService.ErrorNotification(error);
return RedirectToAction("Edit", new { id = customer.Id });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("markVatNumberAsValid")]
public virtual async Task MarkVatNumberAsValid(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
customer.VatNumberStatusId = (int)VatNumberStatus.Valid;
await _customerService.UpdateCustomerAsync(customer);
return RedirectToAction("Edit", new { id = customer.Id });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("markVatNumberAsInvalid")]
public virtual async Task MarkVatNumberAsInvalid(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
customer.VatNumberStatusId = (int)VatNumberStatus.Invalid;
await _customerService.UpdateCustomerAsync(customer);
return RedirectToAction("Edit", new { id = customer.Id });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("remove-affiliate")]
public virtual async Task RemoveAffiliate(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
customer.AffiliateId = 0;
await _customerService.UpdateCustomerAsync(customer);
return RedirectToAction("Edit", new { id = customer.Id });
}
[HttpPost]
public virtual async Task RemoveBindMFA(int id)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(id);
if (customer == null)
return RedirectToAction("List");
await _genericAttributeService.SaveAttributeAsync(customer, NopCustomerDefaults.SelectedMultiFactorAuthenticationProviderAttribute, string.Empty);
//raise event
await _eventPublisher.PublishAsync(new CustomerChangeMultiFactorAuthenticationProviderEvent(customer));
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.UnbindMFAProvider"));
return RedirectToAction("Edit", new { id = customer.Id });
}
[HttpPost]
public virtual async Task Delete(int id)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(id);
if (customer == null)
return RedirectToAction("List");
try
{
//prevent attempts to delete the user, if it is the last active administrator
if (await _customerService.IsAdminAsync(customer) && !await SecondAdminAccountExistsAsync(customer))
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.AdminAccountShouldExists.DeleteAdministrator"));
return RedirectToAction("Edit", new { id = customer.Id });
}
//ensure that the current customer cannot delete "Administrators" if he's not an admin himself
if (await _customerService.IsAdminAsync(customer) && !await _customerService.IsAdminAsync(await _workContext.GetCurrentCustomerAsync()))
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.OnlyAdminCanDeleteAdmin"));
return RedirectToAction("Edit", new { id = customer.Id });
}
//delete
await _customerService.DeleteCustomerAsync(customer);
//remove newsletter subscription (if exists)
foreach (var store in await _storeService.GetAllStoresAsync())
{
var subscription = await _newsLetterSubscriptionService.GetNewsLetterSubscriptionByEmailAndStoreIdAsync(customer.Email, store.Id);
if (subscription != null)
await _newsLetterSubscriptionService.DeleteNewsLetterSubscriptionAsync(subscription);
}
//activity log
await _customerActivityService.InsertActivityAsync("DeleteCustomer",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.DeleteCustomer"), customer.Id), customer);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.Deleted"));
return RedirectToAction("List");
}
catch (Exception exc)
{
_notificationService.ErrorNotification(exc.Message);
return RedirectToAction("Edit", new { id = customer.Id });
}
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("impersonate")]
public virtual async Task Impersonate(int id)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.AllowCustomerImpersonation))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(id);
if (customer == null)
return RedirectToAction("List");
if (!customer.Active)
{
_notificationService.WarningNotification(
await _localizationService.GetResourceAsync("Admin.Customers.Customers.Impersonate.Inactive"));
return RedirectToAction("Edit", customer.Id);
}
//ensure that a non-admin user cannot impersonate as an administrator
//otherwise, that user can simply impersonate as an administrator and gain additional administrative privileges
var currentCustomer = await _workContext.GetCurrentCustomerAsync();
if (!await _customerService.IsAdminAsync(currentCustomer) && await _customerService.IsAdminAsync(customer))
{
_notificationService.ErrorNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.NonAdminNotImpersonateAsAdminError"));
return RedirectToAction("Edit", customer.Id);
}
//activity log
await _customerActivityService.InsertActivityAsync("Impersonation.Started",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.Impersonation.Started.StoreOwner"), customer.Email, customer.Id), customer);
await _customerActivityService.InsertActivityAsync(customer, "Impersonation.Started",
string.Format(await _localizationService.GetResourceAsync("ActivityLog.Impersonation.Started.Customer"), currentCustomer.Email, currentCustomer.Id), currentCustomer);
//ensure login is not required
customer.RequireReLogin = false;
await _customerService.UpdateCustomerAsync(customer);
await _genericAttributeService.SaveAttributeAsync(currentCustomer, NopCustomerDefaults.ImpersonatedCustomerIdAttribute, customer.Id);
return RedirectToAction("Index", "Home", new { area = string.Empty });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("send-welcome-message")]
public virtual async Task SendWelcomeMessage(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
await _workflowMessageService.SendCustomerWelcomeMessageAsync(customer, (await _workContext.GetWorkingLanguageAsync()).Id);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.SendWelcomeMessage.Success"));
return RedirectToAction("Edit", new { id = customer.Id });
}
[HttpPost, ActionName("Edit")]
[FormValueRequired("resend-activation-message")]
public virtual async Task ReSendActivationMessage(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
//email validation message
await _genericAttributeService.SaveAttributeAsync(customer, NopCustomerDefaults.AccountActivationTokenAttribute, Guid.NewGuid().ToString());
await _workflowMessageService.SendCustomerEmailValidationMessageAsync(customer, (await _workContext.GetWorkingLanguageAsync()).Id);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.ReSendActivationMessage.Success"));
return RedirectToAction("Edit", new { id = customer.Id });
}
public virtual async Task SendEmail(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
try
{
if (string.IsNullOrWhiteSpace(customer.Email))
throw new NopException("Customer email is empty");
if (!CommonHelper.IsValidEmail(customer.Email))
throw new NopException("Customer email is not valid");
if (string.IsNullOrWhiteSpace(model.SendEmail.Subject))
throw new NopException("Email subject is empty");
if (string.IsNullOrWhiteSpace(model.SendEmail.Body))
throw new NopException("Email body is empty");
var emailAccount = (await _emailAccountService.GetEmailAccountByIdAsync(_emailAccountSettings.DefaultEmailAccountId)
?? (await _emailAccountService.GetAllEmailAccountsAsync()).FirstOrDefault())
?? throw new NopException("Email account can't be loaded");
var email = new QueuedEmail
{
Priority = QueuedEmailPriority.High,
EmailAccountId = emailAccount.Id,
FromName = emailAccount.DisplayName,
From = emailAccount.Email,
ToName = await _customerService.GetCustomerFullNameAsync(customer),
To = customer.Email,
Subject = model.SendEmail.Subject,
Body = model.SendEmail.Body,
CreatedOnUtc = DateTime.UtcNow,
DontSendBeforeDateUtc = model.SendEmail.SendImmediately || !model.SendEmail.DontSendBeforeDate.HasValue ?
null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(model.SendEmail.DontSendBeforeDate.Value)
};
await _queuedEmailService.InsertQueuedEmailAsync(email);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.SendEmail.Queued"));
}
catch (Exception exc)
{
_notificationService.ErrorNotification(exc.Message);
}
return RedirectToAction("Edit", new { id = customer.Id });
}
public virtual async Task SendPm(CustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.Id);
if (customer == null)
return RedirectToAction("List");
try
{
if (!_forumSettings.AllowPrivateMessages)
throw new NopException("Private messages are disabled");
if (await _customerService.IsGuestAsync(customer))
throw new NopException("Customer should be registered");
if (string.IsNullOrWhiteSpace(model.SendPm.Subject))
throw new NopException(await _localizationService.GetResourceAsync("PrivateMessages.SubjectCannotBeEmpty"));
if (string.IsNullOrWhiteSpace(model.SendPm.Message))
throw new NopException(await _localizationService.GetResourceAsync("PrivateMessages.MessageCannotBeEmpty"));
var store = await _storeContext.GetCurrentStoreAsync();
var privateMessage = new PrivateMessage
{
StoreId = store.Id,
ToCustomerId = customer.Id,
FromCustomerId = customer.Id,
Subject = model.SendPm.Subject,
Text = model.SendPm.Message,
IsDeletedByAuthor = false,
IsDeletedByRecipient = false,
IsRead = false,
CreatedOnUtc = DateTime.UtcNow
};
await _forumService.InsertPrivateMessageAsync(privateMessage);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.SendPM.Sent"));
}
catch (Exception exc)
{
_notificationService.ErrorNotification(exc.Message);
}
return RedirectToAction("Edit", new { id = customer.Id });
}
#endregion
#region Reward points history
[HttpPost]
public virtual async Task RewardPointsHistorySelect(CustomerRewardPointsSearchModel searchModel)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return await AccessDeniedDataTablesJson();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(searchModel.CustomerId)
?? throw new ArgumentException("No customer found with the specified id");
//prepare model
var model = await _customerModelFactory.PrepareRewardPointsListModelAsync(searchModel, customer);
return Json(model);
}
public virtual async Task RewardPointsHistoryAdd(AddRewardPointsToCustomerModel model)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return await AccessDeniedDataTablesJson();
//prevent adding a new row with zero value
if (model.Points == 0)
return ErrorJson(await _localizationService.GetResourceAsync("Admin.Customers.Customers.RewardPoints.AddingZeroValueNotAllowed"));
//prevent adding negative point validity for point reduction
if (model.Points < 0 && model.PointsValidity.HasValue)
return ErrorJson(await _localizationService.GetResourceAsync("Admin.Customers.Customers.RewardPoints.Fields.AddNegativePointsValidity"));
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.CustomerId);
if (customer == null)
return ErrorJson("Customer cannot be loaded");
//check whether delay is set
DateTime? activatingDate = null;
if (!model.ActivatePointsImmediately && model.ActivationDelay > 0)
{
var delayPeriod = (RewardPointsActivatingDelayPeriod)model.ActivationDelayPeriodId;
var delayInHours = delayPeriod.ToHours(model.ActivationDelay);
activatingDate = DateTime.UtcNow.AddHours(delayInHours);
}
//whether points validity is set
DateTime? endDate = null;
if (model.PointsValidity > 0)
endDate = (activatingDate ?? DateTime.UtcNow).AddDays(model.PointsValidity.Value);
//add reward points
await _rewardPointService.AddRewardPointsHistoryEntryAsync(customer, model.Points, model.StoreId, model.Message,
activatingDate: activatingDate, endDate: endDate);
return Json(new { Result = true });
}
#endregion
#region Addresses
[HttpPost]
public virtual async Task AddressesSelect(CustomerAddressSearchModel searchModel)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return await AccessDeniedDataTablesJson();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(searchModel.CustomerId)
?? throw new ArgumentException("No customer found with the specified id");
//prepare model
var model = await _customerModelFactory.PrepareCustomerAddressListModelAsync(searchModel, customer);
return Json(model);
}
[HttpPost]
public virtual async Task AddressDelete(int id, int customerId)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return await AccessDeniedDataTablesJson();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(customerId)
?? throw new ArgumentException("No customer found with the specified id", nameof(customerId));
//try to get an address with the specified id
var address = await _customerService.GetCustomerAddressAsync(customer.Id, id);
if (address == null)
return Content("No address found with the specified id");
await _customerService.RemoveCustomerAddressAsync(customer, address);
await _customerService.UpdateCustomerAsync(customer);
//now delete the address record
await _addressService.DeleteAddressAsync(address);
return new NullJsonResult();
}
public virtual async Task AddressCreate(int customerId)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(customerId);
if (customer == null)
return RedirectToAction("List");
//prepare model
var model = await _customerModelFactory.PrepareCustomerAddressModelAsync(new CustomerAddressModel(), customer, null);
return View(model);
}
[HttpPost]
public virtual async Task AddressCreate(CustomerAddressModel model, IFormCollection form)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.CustomerId);
if (customer == null)
return RedirectToAction("List");
//custom address attributes
var customAttributes = await _addressAttributeParser.ParseCustomAttributesAsync(form, NopCommonDefaults.AddressAttributeControlName);
var customAttributeWarnings = await _addressAttributeParser.GetAttributeWarningsAsync(customAttributes);
foreach (var error in customAttributeWarnings)
{
ModelState.AddModelError(string.Empty, error);
}
if (ModelState.IsValid)
{
var address = model.Address.ToEntity();
address.CustomAttributes = customAttributes;
address.CreatedOnUtc = DateTime.UtcNow;
//some validation
if (address.CountryId == 0)
address.CountryId = null;
if (address.StateProvinceId == 0)
address.StateProvinceId = null;
await _addressService.InsertAddressAsync(address);
await _customerService.InsertCustomerAddressAsync(customer, address);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.Addresses.Added"));
return RedirectToAction("AddressEdit", new { addressId = address.Id, customerId = model.CustomerId });
}
//prepare model
model = await _customerModelFactory.PrepareCustomerAddressModelAsync(model, customer, null, true);
//if we got this far, something failed, redisplay form
return View(model);
}
public virtual async Task AddressEdit(int addressId, int customerId)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(customerId);
if (customer == null)
return RedirectToAction("List");
//try to get an address with the specified id
var address = await _addressService.GetAddressByIdAsync(addressId);
if (address == null)
return RedirectToAction("Edit", new { id = customer.Id });
//prepare model
var model = await _customerModelFactory.PrepareCustomerAddressModelAsync(null, customer, address);
return View(model);
}
[HttpPost]
public virtual async Task AddressEdit(CustomerAddressModel model, IFormCollection form)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(model.CustomerId);
if (customer == null)
return RedirectToAction("List");
//try to get an address with the specified id
var address = await _addressService.GetAddressByIdAsync(model.Address.Id);
if (address == null)
return RedirectToAction("Edit", new { id = customer.Id });
//custom address attributes
var customAttributes = await _addressAttributeParser.ParseCustomAttributesAsync(form, NopCommonDefaults.AddressAttributeControlName);
var customAttributeWarnings = await _addressAttributeParser.GetAttributeWarningsAsync(customAttributes);
foreach (var error in customAttributeWarnings)
{
ModelState.AddModelError(string.Empty, error);
}
if (ModelState.IsValid)
{
address = model.Address.ToEntity(address);
address.CustomAttributes = customAttributes;
await _addressService.UpdateAddressAsync(address);
_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Customers.Customers.Addresses.Updated"));
return RedirectToAction("AddressEdit", new { addressId = model.Address.Id, customerId = model.CustomerId });
}
//prepare model
model = await _customerModelFactory.PrepareCustomerAddressModelAsync(model, customer, address, true);
//if we got this far, something failed, redisplay form
return View(model);
}
#endregion
#region Orders
[HttpPost]
public virtual async Task OrderList(CustomerOrderSearchModel searchModel)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return await AccessDeniedDataTablesJson();
//try to get a customer with the specified id
var customer = await _customerService.GetCustomerByIdAsync(searchModel.CustomerId)
?? throw new ArgumentException("No customer found with the specified id");
//prepare model
var model = await _customerModelFactory.PrepareCustomerOrderListModelAsync(searchModel, customer);
return Json(model);
}
#endregion
#region Customer
public virtual async Task LoadCustomerStatistics(string period)
{
if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCustomers))
return Content(string.Empty);
var result = new List