Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

CustomerModelFactory.cs

using System.Text;
using Microsoft.AspNetCore.Mvc.Rendering;
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.Media;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Tax;
using Nop.Services.Affiliates;
using Nop.Services.Attributes;
using Nop.Services.Authentication.External;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Gdpr;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Media;
using Nop.Services.Messages;
using Nop.Services.Orders;
using Nop.Services.Stores;
using Nop.Services.Tax;
using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions;
using Nop.Web.Areas.Admin.Models.Common;
using Nop.Web.Areas.Admin.Models.Customers;
using Nop.Web.Areas.Admin.Models.ShoppingCart;
using Nop.Web.Framework.Factories;
using Nop.Web.Framework.Models.Extensions;

namespace Nop.Web.Areas.Admin.Factories;

/// 
/// Represents the customer model factory implementation
/// 
public partial class CustomerModelFactory : ICustomerModelFactory
{
    #region Fields

    protected readonly AddressSettings _addressSettings;
    protected readonly CustomerSettings _customerSettings;
    protected readonly DateTimeSettings _dateTimeSettings;
    protected readonly GdprSettings _gdprSettings;
    protected readonly ForumSettings _forumSettings;
    protected readonly IAclSupportedModelFactory _aclSupportedModelFactory;
    protected readonly IAddressModelFactory _addressModelFactory;
    protected readonly IAddressService _addressService;
    protected readonly IAffiliateService _affiliateService;
    protected readonly IAttributeFormatter _addressAttributeFormatter;
    protected readonly IAttributeParser _customerAttributeParser;
    protected readonly IAttributeService _customerAttributeService;
    protected readonly IAuthenticationPluginManager _authenticationPluginManager;
    protected readonly IBackInStockSubscriptionService _backInStockSubscriptionService;
    protected readonly IBaseAdminModelFactory _baseAdminModelFactory;
    protected readonly ICountryService _countryService;
    protected readonly ICustomerActivityService _customerActivityService;
    protected readonly ICustomerService _customerService;
    protected readonly IDateTimeHelper _dateTimeHelper;
    protected readonly IExternalAuthenticationService _externalAuthenticationService;
    protected readonly IGdprService _gdprService;
    protected readonly IGenericAttributeService _genericAttributeService;
    protected readonly IGeoLookupService _geoLookupService;
    protected readonly ILocalizationService _localizationService;
    protected readonly INewsLetterSubscriptionService _newsLetterSubscriptionService;
    protected readonly IOrderService _orderService;
    protected readonly IPictureService _pictureService;
    protected readonly IPriceFormatter _priceFormatter;
    protected readonly IProductAttributeFormatter _productAttributeFormatter;
    protected readonly IProductService _productService;
    protected readonly IRewardPointService _rewardPointService;
    protected readonly IShoppingCartService _shoppingCartService;
    protected readonly IStateProvinceService _stateProvinceService;
    protected readonly IStoreContext _storeContext;
    protected readonly IStoreService _storeService;
    protected readonly ITaxService _taxService;
    protected readonly IWorkContext _workContext;
    protected readonly MediaSettings _mediaSettings;
    protected readonly RewardPointsSettings _rewardPointsSettings;
    protected readonly TaxSettings _taxSettings;

    #endregion

    #region Ctor

    public CustomerModelFactory(AddressSettings addressSettings,
        CustomerSettings customerSettings,
        DateTimeSettings dateTimeSettings,
        GdprSettings gdprSettings,
        ForumSettings forumSettings,
        IAclSupportedModelFactory aclSupportedModelFactory,
        IAddressModelFactory addressModelFactory,
        IAddressService addressService,
        IAffiliateService affiliateService,
        IAttributeFormatter addressAttributeFormatter,
        IAttributeParser customerAttributeParser,
        IAttributeService customerAttributeService,
        IAuthenticationPluginManager authenticationPluginManager,
        IBackInStockSubscriptionService backInStockSubscriptionService,
        IBaseAdminModelFactory baseAdminModelFactory,
        ICountryService countryService,
        ICustomerActivityService customerActivityService,
        ICustomerService customerService,
        IDateTimeHelper dateTimeHelper,
        IExternalAuthenticationService externalAuthenticationService,
        IGdprService gdprService,
        IGenericAttributeService genericAttributeService,
        IGeoLookupService geoLookupService,
        ILocalizationService localizationService,
        INewsLetterSubscriptionService newsLetterSubscriptionService,
        IOrderService orderService,
        IPictureService pictureService,
        IPriceFormatter priceFormatter,
        IProductAttributeFormatter productAttributeFormatter,
        IProductService productService,
        IRewardPointService rewardPointService,
        IShoppingCartService shoppingCartService,
        IStateProvinceService stateProvinceService,
        IStoreContext storeContext,
        IStoreService storeService,
        ITaxService taxService,
        IWorkContext workContext,
        MediaSettings mediaSettings,
        RewardPointsSettings rewardPointsSettings,
        TaxSettings taxSettings)
    {
        _addressSettings = addressSettings;
        _customerSettings = customerSettings;
        _dateTimeSettings = dateTimeSettings;
        _gdprSettings = gdprSettings;
        _forumSettings = forumSettings;
        _aclSupportedModelFactory = aclSupportedModelFactory;
        _addressModelFactory = addressModelFactory;
        _addressService = addressService;
        _affiliateService = affiliateService;
        _addressAttributeFormatter = addressAttributeFormatter;
        _customerAttributeParser = customerAttributeParser;
        _customerAttributeService = customerAttributeService;
        _authenticationPluginManager = authenticationPluginManager;
        _backInStockSubscriptionService = backInStockSubscriptionService;
        _baseAdminModelFactory = baseAdminModelFactory;
        _countryService = countryService;
        _customerActivityService = customerActivityService;
        _customerService = customerService;
        _dateTimeHelper = dateTimeHelper;
        _externalAuthenticationService = externalAuthenticationService;
        _gdprService = gdprService;
        _genericAttributeService = genericAttributeService;
        _geoLookupService = geoLookupService;
        _localizationService = localizationService;
        _newsLetterSubscriptionService = newsLetterSubscriptionService;
        _orderService = orderService;
        _pictureService = pictureService;
        _priceFormatter = priceFormatter;
        _productAttributeFormatter = productAttributeFormatter;
        _productService = productService;
        _rewardPointService = rewardPointService;
        _shoppingCartService = shoppingCartService;
        _stateProvinceService = stateProvinceService;
        _storeContext = storeContext;
        _storeService = storeService;
        _taxService = taxService;
        _workContext = workContext;
        _mediaSettings = mediaSettings;
        _rewardPointsSettings = rewardPointsSettings;
        _taxSettings = taxSettings;
    }

    #endregion

    #region Utilities

    /// 
    /// Prepare the reward points model to add to the customer
    /// 
    /// Reward points model to add to the customer
    /// A task that represents the asynchronous operation
    protected virtual async Task PrepareAddRewardPointsToCustomerModelAsync(AddRewardPointsToCustomerModel model)
    {
        ArgumentNullException.ThrowIfNull(model);

        var store = await _storeContext.GetCurrentStoreAsync();

        model.Message = string.Empty;
        model.ActivatePointsImmediately = true;
        model.StoreId = store.Id;

        //prepare available stores
        await _baseAdminModelFactory.PrepareStoresAsync(model.AvailableStores, false);
    }

    /// 
    /// Prepare customer associated external authorization models
    /// 
    /// List of customer associated external authorization models
    /// Customer
    /// A task that represents the asynchronous operation
    protected virtual async Task PrepareAssociatedExternalAuthModelsAsync(IList models, Customer customer)
    {
        ArgumentNullException.ThrowIfNull(models);

        ArgumentNullException.ThrowIfNull(customer);

        foreach (var record in await _externalAuthenticationService.GetCustomerExternalAuthenticationRecordsAsync(customer))
        {
            var method = await _authenticationPluginManager.LoadPluginBySystemNameAsync(record.ProviderSystemName);
            if (method == null)
                continue;

            models.Add(new CustomerAssociatedExternalAuthModel
            {
                Id = record.Id,
                Email = record.Email,
                ExternalIdentifier = !string.IsNullOrEmpty(record.ExternalDisplayIdentifier)
                    ? record.ExternalDisplayIdentifier : record.ExternalIdentifier,
                AuthMethodName = method.PluginDescriptor.FriendlyName
            });
        }
    }

    /// 
    /// Prepare customer attribute models
    /// 
    /// List of customer attribute models
    /// Customer
    /// A task that represents the asynchronous operation
    protected virtual async Task PrepareCustomerAttributeModelsAsync(IList models, Customer customer)
    {
        ArgumentNullException.ThrowIfNull(models);

        //get available customer attributes
        var customerAttributes = await _customerAttributeService.GetAllAttributesAsync();
        foreach (var attribute in customerAttributes)
        {
            var attributeModel = new CustomerModel.CustomerAttributeModel
            {
                Id = attribute.Id,
                Name = attribute.Name,
                IsRequired = attribute.IsRequired,
                AttributeControlType = attribute.AttributeControlType
            };

            if (attribute.ShouldHaveValues)
            {
                //values
                var attributeValues = await _customerAttributeService.GetAttributeValuesAsync(attribute.Id);
                foreach (var attributeValue in attributeValues)
                {
                    var attributeValueModel = new CustomerModel.CustomerAttributeValueModel
                    {
                        Id = attributeValue.Id,
                        Name = attributeValue.Name,
                        IsPreSelected = attributeValue.IsPreSelected
                    };
                    attributeModel.Values.Add(attributeValueModel);
                }
            }

            //set already selected attributes
            if (customer != null)
            {
                var selectedCustomerAttributes = customer.CustomCustomerAttributesXML;
                switch (attribute.AttributeControlType)
                {
                    case AttributeControlType.DropdownList:
                    case AttributeControlType.RadioList:
                    case AttributeControlType.Checkboxes:
                    {
                        if (!string.IsNullOrEmpty(selectedCustomerAttributes))
                        {
                            //clear default selection
                            foreach (var item in attributeModel.Values)
                                item.IsPreSelected = false;

                            //select new values
                            var selectedValues = await _customerAttributeParser.ParseAttributeValuesAsync(selectedCustomerAttributes);
                            foreach (var attributeValue in selectedValues)
                            foreach (var item in attributeModel.Values)
                                if (attributeValue.Id == item.Id)
                                    item.IsPreSelected = true;
                        }
                    }
                        break;
                    case AttributeControlType.ReadonlyCheckboxes:
                    {
                        //do nothing
                        //values are already pre-set
                    }
                        break;
                    case AttributeControlType.TextBox:
                    case AttributeControlType.MultilineTextbox:
                    {
                        if (!string.IsNullOrEmpty(selectedCustomerAttributes))
                        {
                            var enteredText = _customerAttributeParser.ParseValues(selectedCustomerAttributes, attribute.Id);
                            if (enteredText.Any())
                                attributeModel.DefaultValue = enteredText[0];
                        }
                    }
                        break;
                    case AttributeControlType.Datepicker:
                    case AttributeControlType.ColorSquares:
                    case AttributeControlType.ImageSquares:
                    case AttributeControlType.FileUpload:
                    default:
                        //not supported attribute control types
                        break;
                }
            }

            models.Add(attributeModel);
        }
    }

    /// 
    /// Prepare HTML string address
    /// 
    /// Address model
    /// Address
    /// A task that represents the asynchronous operation
    protected virtual async Task PrepareModelAddressHtmlAsync(AddressModel model, Address address)
    {
        ArgumentNullException.ThrowIfNull(model);

        var separator = "
"; var addressHtmlSb = new StringBuilder("
"); var languageId = (await _workContext.GetWorkingLanguageAsync()).Id; var (addressLine, _) = await _addressService.FormatAddressAsync(address, languageId, separator, true); addressHtmlSb.Append(addressLine); var customAttributesFormatted = await _addressAttributeFormatter.FormatAttributesAsync(address?.CustomAttributes); if (!string.IsNullOrEmpty(customAttributesFormatted)) { //already encoded addressHtmlSb.AppendFormat($"{separator}{customAttributesFormatted}"); } addressHtmlSb.Append("
"); model.AddressHtml = addressHtmlSb.ToString(); } /// /// Prepare reward points search model /// /// Reward points search model /// Customer /// Reward points search model protected virtual CustomerRewardPointsSearchModel PrepareRewardPointsSearchModel(CustomerRewardPointsSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare customer address search model /// /// Customer address search model /// Customer /// Customer address search model protected virtual CustomerAddressSearchModel PrepareCustomerAddressSearchModel(CustomerAddressSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare customer order search model /// /// Customer order search model /// Customer /// Customer order search model protected virtual CustomerOrderSearchModel PrepareCustomerOrderSearchModel(CustomerOrderSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare customer shopping cart search model /// /// Customer shopping cart search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer shopping cart search model /// protected virtual async Task PrepareCustomerShoppingCartSearchModelAsync(CustomerShoppingCartSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare available shopping cart types (search shopping cart by default) searchModel.ShoppingCartTypeId = (int)ShoppingCartType.ShoppingCart; await _baseAdminModelFactory.PrepareShoppingCartTypesAsync(searchModel.AvailableShoppingCartTypes, false); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare customer activity log search model /// /// Customer activity log search model /// Customer /// Customer activity log search model protected virtual CustomerActivityLogSearchModel PrepareCustomerActivityLogSearchModel(CustomerActivityLogSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare customer back in stock subscriptions search model /// /// Customer back in stock subscriptions search model /// Customer /// Customer back in stock subscriptions search model protected virtual CustomerBackInStockSubscriptionSearchModel PrepareCustomerBackInStockSubscriptionSearchModel( CustomerBackInStockSubscriptionSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare customer back in stock subscriptions search model /// /// Customer back in stock subscriptions search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer back in stock subscriptions search model /// protected virtual async Task PrepareCustomerAssociatedExternalAuthRecordsSearchModelAsync( CustomerAssociatedExternalAuthRecordsSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); searchModel.CustomerId = customer.Id; //prepare page parameters searchModel.SetGridPageSize(); //prepare external authentication records await PrepareAssociatedExternalAuthModelsAsync(searchModel.AssociatedExternalAuthRecords, customer); return searchModel; } #endregion #region Methods /// /// Prepare customer search model /// /// Customer search model /// /// A task that represents the asynchronous operation /// The task result contains the customer search model /// public virtual async Task PrepareCustomerSearchModelAsync(CustomerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); searchModel.UsernamesEnabled = _customerSettings.UsernamesEnabled; searchModel.AvatarEnabled = _customerSettings.AllowCustomersToUploadAvatars; searchModel.FirstNameEnabled = _customerSettings.FirstNameEnabled; searchModel.LastNameEnabled = _customerSettings.LastNameEnabled; searchModel.DateOfBirthEnabled = _customerSettings.DateOfBirthEnabled; searchModel.CompanyEnabled = _customerSettings.CompanyEnabled; searchModel.PhoneEnabled = _customerSettings.PhoneEnabled; searchModel.ZipPostalCodeEnabled = _customerSettings.ZipPostalCodeEnabled; //search registered customers by default var registeredRole = await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.RegisteredRoleName); if (registeredRole != null) searchModel.SelectedCustomerRoleIds.Add(registeredRole.Id); //prepare available customer roles await _aclSupportedModelFactory.PrepareModelCustomerRolesAsync(searchModel); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare paged customer list model /// /// Customer search model /// /// A task that represents the asynchronous operation /// The task result contains the customer list model /// public virtual async Task PrepareCustomerListModelAsync(CustomerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter customers _ = int.TryParse(searchModel.SearchDayOfBirth, out var dayOfBirth); _ = int.TryParse(searchModel.SearchMonthOfBirth, out var monthOfBirth); var createdFromUtc = !searchModel.SearchRegistrationDateFrom.HasValue ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.SearchRegistrationDateFrom.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()); var createdToUtc = !searchModel.SearchRegistrationDateTo.HasValue ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.SearchRegistrationDateTo.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()).AddDays(1); var lastActivityFromUtc = !searchModel.SearchLastActivityFrom.HasValue ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.SearchLastActivityFrom.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()); var lastActivityToUtc = !searchModel.SearchLastActivityTo.HasValue ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.SearchLastActivityTo.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()).AddDays(1); //exclude guests from the result when filter "by registration date" is used if (createdFromUtc.HasValue || createdToUtc.HasValue) { if (!searchModel.SelectedCustomerRoleIds.Any()) { var customerRoles = await _customerService.GetAllCustomerRolesAsync(showHidden: true); searchModel.SelectedCustomerRoleIds = customerRoles .Where(cr => cr.SystemName != NopCustomerDefaults.GuestsRoleName).Select(cr => cr.Id).ToList(); } else { var guestRole = await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.GuestsRoleName); if (guestRole != null) searchModel.SelectedCustomerRoleIds.Remove(guestRole.Id); } } //get customers var customers = await _customerService.GetAllCustomersAsync(customerRoleIds: searchModel.SelectedCustomerRoleIds.ToArray(), email: searchModel.SearchEmail, username: searchModel.SearchUsername, firstName: searchModel.SearchFirstName, lastName: searchModel.SearchLastName, dayOfBirth: dayOfBirth, monthOfBirth: monthOfBirth, company: searchModel.SearchCompany, createdFromUtc: createdFromUtc, createdToUtc: createdToUtc, lastActivityFromUtc: lastActivityFromUtc, lastActivityToUtc: lastActivityToUtc, phone: searchModel.SearchPhone, zipPostalCode: searchModel.SearchZipPostalCode, ipAddress: searchModel.SearchIpAddress, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new CustomerListModel().PrepareToGridAsync(searchModel, customers, () => { return customers.SelectAwait(async customer => { //fill in model values from the entity var customerModel = customer.ToModel(); //convert dates to the user time customerModel.Email = (await _customerService.IsRegisteredAsync(customer)) ? customer.Email : await _localizationService.GetResourceAsync("Admin.Customers.Guest"); customerModel.FullName = await _customerService.GetCustomerFullNameAsync(customer); customerModel.Company = customer.Company; customerModel.Phone = customer.Phone; customerModel.ZipPostalCode = customer.ZipPostalCode; customerModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(customer.CreatedOnUtc, DateTimeKind.Utc); customerModel.LastActivityDate = await _dateTimeHelper.ConvertToUserTimeAsync(customer.LastActivityDateUtc, DateTimeKind.Utc); //fill in additional values (not existing in the entity) customerModel.CustomerRoleNames = string.Join(", ", (await _customerService.GetCustomerRolesAsync(customer)).Select(role => role.Name)); if (_customerSettings.AllowCustomersToUploadAvatars) { var avatarPictureId = await _genericAttributeService.GetAttributeAsync(customer, NopCustomerDefaults.AvatarPictureIdAttribute); customerModel.AvatarUrl = await _pictureService .GetPictureUrlAsync(avatarPictureId, _mediaSettings.AvatarPictureSize, _customerSettings.DefaultAvatarEnabled, defaultPictureType: PictureType.Avatar); } return customerModel; }); }); return model; } /// /// Prepare customer model /// /// Customer model /// Customer /// Whether to exclude populating of some properties of model /// /// A task that represents the asynchronous operation /// The task result contains the customer model /// public virtual async Task PrepareCustomerModelAsync(CustomerModel model, Customer customer, bool excludeProperties = false) { if (customer != null) { //fill in model values from the entity model ??= new CustomerModel(); model.Id = customer.Id; model.DisplayVatNumber = _taxSettings.EuVatEnabled; model.AllowSendingOfPrivateMessage = await _customerService.IsRegisteredAsync(customer) && _forumSettings.AllowPrivateMessages; model.AllowSendingOfWelcomeMessage = await _customerService.IsRegisteredAsync(customer) && _customerSettings.UserRegistrationType == UserRegistrationType.AdminApproval; model.AllowReSendingOfActivationMessage = await _customerService.IsRegisteredAsync(customer) && !customer.Active && _customerSettings.UserRegistrationType == UserRegistrationType.EmailValidation; model.GdprEnabled = _gdprSettings.GdprEnabled; model.MultiFactorAuthenticationProvider = await _genericAttributeService .GetAttributeAsync(customer, NopCustomerDefaults.SelectedMultiFactorAuthenticationProviderAttribute); //whether to fill in some of properties if (!excludeProperties) { model.Email = customer.Email; model.Username = customer.Username; model.VendorId = customer.VendorId; model.AdminComment = customer.AdminComment; model.IsTaxExempt = customer.IsTaxExempt; model.Active = customer.Active; model.FirstName = customer.FirstName; model.LastName = customer.LastName; model.Gender = customer.Gender; model.DateOfBirth = customer.DateOfBirth; model.Company = customer.Company; model.StreetAddress = customer.StreetAddress; model.StreetAddress2 = customer.StreetAddress2; model.ZipPostalCode = customer.ZipPostalCode; model.City = customer.City; model.County = customer.County; model.CountryId = customer.CountryId; model.StateProvinceId = customer.StateProvinceId; model.Phone = customer.Phone; model.Fax = customer.Fax; model.TimeZoneId = customer.TimeZoneId; model.VatNumber = customer.VatNumber; model.VatNumberStatusNote = await _localizationService.GetLocalizedEnumAsync(customer.VatNumberStatus); model.LastActivityDate = await _dateTimeHelper.ConvertToUserTimeAsync(customer.LastActivityDateUtc, DateTimeKind.Utc); model.LastIpAddress = customer.LastIpAddress; model.LastVisitedPage = await _genericAttributeService.GetAttributeAsync(customer, NopCustomerDefaults.LastVisitedPageAttribute); model.SelectedCustomerRoleIds = (await _customerService.GetCustomerRoleIdsAsync(customer)).ToList(); model.RegisteredInStore = (await _storeService.GetAllStoresAsync()) .FirstOrDefault(store => store.Id == customer.RegisteredInStoreId)?.Name ?? string.Empty; model.DisplayRegisteredInStore = model.Id > 0 && !string.IsNullOrEmpty(model.RegisteredInStore) && (await _storeService.GetAllStoresAsync()).Select(x => x.Id).Count() > 1; model.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(customer.CreatedOnUtc, DateTimeKind.Utc); //prepare model affiliate var affiliate = await _affiliateService.GetAffiliateByIdAsync(customer.AffiliateId); if (affiliate != null) { model.AffiliateId = affiliate.Id; model.AffiliateName = await _affiliateService.GetAffiliateFullNameAsync(affiliate); } //prepare model newsletter subscriptions if (!string.IsNullOrEmpty(customer.Email)) { model.SelectedNewsletterSubscriptionStoreIds = await (await _storeService.GetAllStoresAsync()) .WhereAwait(async store => await _newsLetterSubscriptionService.GetNewsLetterSubscriptionByEmailAndStoreIdAsync(customer.Email, store.Id) != null) .Select(store => store.Id).ToListAsync(); } } //prepare reward points model model.DisplayRewardPointsHistory = _rewardPointsSettings.Enabled; if (model.DisplayRewardPointsHistory) await PrepareAddRewardPointsToCustomerModelAsync(model.AddRewardPoints); //prepare nested search models PrepareRewardPointsSearchModel(model.CustomerRewardPointsSearchModel, customer); PrepareCustomerAddressSearchModel(model.CustomerAddressSearchModel, customer); PrepareCustomerOrderSearchModel(model.CustomerOrderSearchModel, customer); await PrepareCustomerShoppingCartSearchModelAsync(model.CustomerShoppingCartSearchModel, customer); PrepareCustomerActivityLogSearchModel(model.CustomerActivityLogSearchModel, customer); PrepareCustomerBackInStockSubscriptionSearchModel(model.CustomerBackInStockSubscriptionSearchModel, customer); await PrepareCustomerAssociatedExternalAuthRecordsSearchModelAsync(model.CustomerAssociatedExternalAuthRecordsSearchModel, customer); } else { //whether to fill in some of properties if (!excludeProperties) { //precheck Registered Role as a default role while creating a new customer through admin var registeredRole = await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.RegisteredRoleName); if (registeredRole != null) model.SelectedCustomerRoleIds.Add(registeredRole.Id); } } model.UsernamesEnabled = _customerSettings.UsernamesEnabled; model.AllowCustomersToSetTimeZone = _dateTimeSettings.AllowCustomersToSetTimeZone; model.FirstNameEnabled = _customerSettings.FirstNameEnabled; model.LastNameEnabled = _customerSettings.LastNameEnabled; model.GenderEnabled = _customerSettings.GenderEnabled; model.NeutralGenderEnabled = _customerSettings.NeutralGenderEnabled; model.DateOfBirthEnabled = _customerSettings.DateOfBirthEnabled; model.CompanyEnabled = _customerSettings.CompanyEnabled; model.StreetAddressEnabled = _customerSettings.StreetAddressEnabled; model.StreetAddress2Enabled = _customerSettings.StreetAddress2Enabled; model.ZipPostalCodeEnabled = _customerSettings.ZipPostalCodeEnabled; model.CityEnabled = _customerSettings.CityEnabled; model.CountyEnabled = _customerSettings.CountyEnabled; model.CountryEnabled = _customerSettings.CountryEnabled; model.StateProvinceEnabled = _customerSettings.StateProvinceEnabled; model.PhoneEnabled = _customerSettings.PhoneEnabled; model.FaxEnabled = _customerSettings.FaxEnabled; //set default values for the new model if (customer == null) { model.Active = true; model.DisplayVatNumber = false; } //prepare available vendors await _baseAdminModelFactory.PrepareVendorsAsync(model.AvailableVendors, defaultItemText: await _localizationService.GetResourceAsync("Admin.Customers.Customers.Fields.Vendor.None")); //prepare model customer attributes await PrepareCustomerAttributeModelsAsync(model.CustomerAttributes, customer); //prepare model stores for newsletter subscriptions model.AvailableNewsletterSubscriptionStores = (await _storeService.GetAllStoresAsync()).Select(store => new SelectListItem { Value = store.Id.ToString(), Text = store.Name, Selected = model.SelectedNewsletterSubscriptionStoreIds.Contains(store.Id) }).ToList(); //prepare model customer roles await _aclSupportedModelFactory.PrepareModelCustomerRolesAsync(model); //prepare available time zones await _baseAdminModelFactory.PrepareTimeZonesAsync(model.AvailableTimeZones, false); //prepare available countries and states if (_customerSettings.CountryEnabled) { await _baseAdminModelFactory.PrepareCountriesAsync(model.AvailableCountries); if (_customerSettings.StateProvinceEnabled) await _baseAdminModelFactory.PrepareStatesAndProvincesAsync(model.AvailableStates, model.CountryId == 0 ? null : (int?)model.CountryId); } return model; } /// /// Prepare paged reward points list model /// /// Reward points search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the reward points list model /// public virtual async Task PrepareRewardPointsListModelAsync(CustomerRewardPointsSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); //get reward points history var rewardPoints = await _rewardPointService.GetRewardPointsHistoryAsync(customer.Id, showNotActivated: true, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new CustomerRewardPointsListModel().PrepareToGridAsync(searchModel, rewardPoints, () => { return rewardPoints.SelectAwait(async historyEntry => { //fill in model values from the entity var rewardPointsHistoryModel = historyEntry.ToModel(); //convert dates to the user time var activatingDate = await _dateTimeHelper.ConvertToUserTimeAsync(historyEntry.CreatedOnUtc, DateTimeKind.Utc); rewardPointsHistoryModel.CreatedOn = activatingDate; rewardPointsHistoryModel.PointsBalance = historyEntry.PointsBalance.HasValue ? historyEntry.PointsBalance.ToString() : string.Format((await _localizationService.GetResourceAsync("Admin.Customers.Customers.RewardPoints.ActivatedLater")), activatingDate); rewardPointsHistoryModel.EndDate = !historyEntry.EndDateUtc.HasValue ? null : (DateTime?)(await _dateTimeHelper.ConvertToUserTimeAsync(historyEntry.EndDateUtc.Value, DateTimeKind.Utc)); //fill in additional values (not existing in the entity) rewardPointsHistoryModel.StoreName = (await _storeService.GetStoreByIdAsync(historyEntry.StoreId))?.Name ?? "Unknown"; return rewardPointsHistoryModel; }); }); return model; } /// /// Prepare paged customer address list model /// /// Customer address search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer address list model /// public virtual async Task PrepareCustomerAddressListModelAsync(CustomerAddressSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); //get customer addresses var addresses = (await _customerService.GetAddressesByCustomerIdAsync(customer.Id)) .OrderByDescending(address => address.CreatedOnUtc).ThenByDescending(address => address.Id).ToList() .ToPagedList(searchModel); //prepare list model var model = await new CustomerAddressListModel().PrepareToGridAsync(searchModel, addresses, () => { return addresses.SelectAwait(async address => { //fill in model values from the entity var addressModel = address.ToModel(); addressModel.CountryName = (await _countryService.GetCountryByAddressAsync(address))?.Name; addressModel.StateProvinceName = (await _stateProvinceService.GetStateProvinceByAddressAsync(address))?.Name; //fill in additional values (not existing in the entity) await PrepareModelAddressHtmlAsync(addressModel, address); return addressModel; }); }); return model; } /// /// Prepare customer address model /// /// Customer address model /// Customer /// Address /// Whether to exclude populating of some properties of model /// /// A task that represents the asynchronous operation /// The task result contains the customer address model /// public virtual async Task PrepareCustomerAddressModelAsync(CustomerAddressModel model, Customer customer, Address address, bool excludeProperties = false) { ArgumentNullException.ThrowIfNull(customer); if (address != null) { //fill in model values from the entity model ??= new CustomerAddressModel(); //whether to fill in some of properties if (!excludeProperties) model.Address = address.ToModel(model.Address); } model.CustomerId = customer.Id; //prepare address model await _addressModelFactory.PrepareAddressModelAsync(model.Address, address); model.Address.FirstNameRequired = true; model.Address.LastNameRequired = true; model.Address.EmailRequired = true; model.Address.CompanyRequired = _addressSettings.CompanyRequired; model.Address.CityRequired = _addressSettings.CityRequired; model.Address.CountyRequired = _addressSettings.CountyRequired; model.Address.StreetAddressRequired = _addressSettings.StreetAddressRequired; model.Address.StreetAddress2Required = _addressSettings.StreetAddress2Required; model.Address.ZipPostalCodeRequired = _addressSettings.ZipPostalCodeRequired; model.Address.PhoneRequired = _addressSettings.PhoneRequired; model.Address.FaxRequired = _addressSettings.FaxRequired; return model; } /// /// Prepare paged customer order list model /// /// Customer order search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer order list model /// public virtual async Task PrepareCustomerOrderListModelAsync(CustomerOrderSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); //get customer orders var orders = await _orderService.SearchOrdersAsync(customerId: customer.Id, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new CustomerOrderListModel().PrepareToGridAsync(searchModel, orders, () => { return orders.SelectAwait(async order => { //fill in model values from the entity var orderModel = order.ToModel(); //convert dates to the user time orderModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(order.CreatedOnUtc, DateTimeKind.Utc); //fill in additional values (not existing in the entity) orderModel.StoreName = (await _storeService.GetStoreByIdAsync(order.StoreId))?.Name ?? "Unknown"; orderModel.OrderStatus = await _localizationService.GetLocalizedEnumAsync(order.OrderStatus); orderModel.PaymentStatus = await _localizationService.GetLocalizedEnumAsync(order.PaymentStatus); orderModel.ShippingStatus = await _localizationService.GetLocalizedEnumAsync(order.ShippingStatus); orderModel.OrderTotal = await _priceFormatter.FormatPriceAsync(order.OrderTotal, true, false); return orderModel; }); }); return model; } /// /// Prepare paged customer shopping cart list model /// /// Customer shopping cart search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer shopping cart list model /// public virtual async Task PrepareCustomerShoppingCartListModelAsync(CustomerShoppingCartSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); //get customer shopping cart var shoppingCart = (await _shoppingCartService.GetShoppingCartAsync(customer, (ShoppingCartType)searchModel.ShoppingCartTypeId)) .ToPagedList(searchModel); //prepare list model var model = await new CustomerShoppingCartListModel().PrepareToGridAsync(searchModel, shoppingCart, () => { return shoppingCart.SelectAwait(async item => { //fill in model values from the entity var shoppingCartItemModel = item.ToModel(); var product = await _productService.GetProductByIdAsync(item.ProductId); //fill in additional values (not existing in the entity) shoppingCartItemModel.ProductName = product.Name; shoppingCartItemModel.Store = (await _storeService.GetStoreByIdAsync(item.StoreId))?.Name ?? "Unknown"; shoppingCartItemModel.AttributeInfo = await _productAttributeFormatter.FormatAttributesAsync(product, item.AttributesXml); var (unitPrice, _, _) = await _shoppingCartService.GetUnitPriceAsync(item, true); shoppingCartItemModel.UnitPrice = await _priceFormatter.FormatPriceAsync((await _taxService.GetProductPriceAsync(product, unitPrice)).price); shoppingCartItemModel.UnitPriceValue = (await _taxService.GetProductPriceAsync(product, unitPrice)).price; var (subTotal, _, _, _) = await _shoppingCartService.GetSubTotalAsync(item, true); shoppingCartItemModel.Total = await _priceFormatter.FormatPriceAsync((await _taxService.GetProductPriceAsync(product, subTotal)).price); shoppingCartItemModel.TotalValue = (await _taxService.GetProductPriceAsync(product, subTotal)).price; //convert dates to the user time shoppingCartItemModel.UpdatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(item.UpdatedOnUtc, DateTimeKind.Utc); return shoppingCartItemModel; }); }); return model; } /// /// Prepare paged customer activity log list model /// /// Customer activity log search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer activity log list model /// public virtual async Task PrepareCustomerActivityLogListModelAsync(CustomerActivityLogSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); //get customer activity log var activityLog = await _customerActivityService.GetAllActivitiesAsync(customerId: customer.Id, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new CustomerActivityLogListModel().PrepareToGridAsync(searchModel, activityLog, () => { return activityLog.SelectAwait(async logItem => { //fill in model values from the entity var customerActivityLogModel = logItem.ToModel(); //fill in additional values (not existing in the entity) customerActivityLogModel.ActivityLogTypeName = (await _customerActivityService.GetActivityTypeByIdAsync(logItem.ActivityLogTypeId))?.Name; //convert dates to the user time customerActivityLogModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(logItem.CreatedOnUtc, DateTimeKind.Utc); return customerActivityLogModel; }); }); return model; } /// /// Prepare paged customer back in stock subscriptions list model /// /// Customer back in stock subscriptions search model /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the customer back in stock subscriptions list model /// public virtual async Task PrepareCustomerBackInStockSubscriptionListModelAsync( CustomerBackInStockSubscriptionSearchModel searchModel, Customer customer) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(customer); //get customer back in stock subscriptions var subscriptions = await _backInStockSubscriptionService.GetAllSubscriptionsByCustomerIdAsync(customer.Id, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new CustomerBackInStockSubscriptionListModel().PrepareToGridAsync(searchModel, subscriptions, () => { return subscriptions.SelectAwait(async subscription => { //fill in model values from the entity var subscriptionModel = subscription.ToModel(); //convert dates to the user time subscriptionModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(subscription.CreatedOnUtc, DateTimeKind.Utc); //fill in additional values (not existing in the entity) subscriptionModel.StoreName = (await _storeService.GetStoreByIdAsync(subscription.StoreId))?.Name ?? "Unknown"; subscriptionModel.ProductName = (await _productService.GetProductByIdAsync(subscription.ProductId))?.Name ?? "Unknown"; return subscriptionModel; }); }); return model; } /// /// Prepare online customer search model /// /// Online customer search model /// /// A task that represents the asynchronous operation /// The task result contains the online customer search model /// public virtual Task PrepareOnlineCustomerSearchModelAsync(OnlineCustomerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare page parameters searchModel.SetGridPageSize(); return Task.FromResult(searchModel); } /// /// Prepare paged online customer list model /// /// Online customer search model /// /// A task that represents the asynchronous operation /// The task result contains the online customer list model /// public virtual async Task PrepareOnlineCustomerListModelAsync(OnlineCustomerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter customers var lastActivityFrom = DateTime.UtcNow.AddMinutes(-_customerSettings.OnlineCustomerMinutes); //get online customers var customers = await _customerService.GetOnlineCustomersAsync(customerRoleIds: null, lastActivityFromUtc: lastActivityFrom, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new OnlineCustomerListModel().PrepareToGridAsync(searchModel, customers, () => { return customers.SelectAwait(async customer => { //fill in model values from the entity var customerModel = customer.ToModel(); //convert dates to the user time customerModel.LastActivityDate = await _dateTimeHelper.ConvertToUserTimeAsync(customer.LastActivityDateUtc, DateTimeKind.Utc); //fill in additional values (not existing in the entity) customerModel.CustomerInfo = (await _customerService.IsRegisteredAsync(customer)) ? customer.Email : await _localizationService.GetResourceAsync("Admin.Customers.Guest"); customerModel.LastIpAddress = _customerSettings.StoreIpAddresses ? customer.LastIpAddress : await _localizationService.GetResourceAsync("Admin.Customers.OnlineCustomers.Fields.IPAddress.Disabled"); customerModel.Location = _geoLookupService.LookupCountryName(customer.LastIpAddress); customerModel.LastVisitedPage = _customerSettings.StoreLastVisitedPage ? await _genericAttributeService.GetAttributeAsync(customer, NopCustomerDefaults.LastVisitedPageAttribute) : await _localizationService.GetResourceAsync("Admin.Customers.OnlineCustomers.Fields.LastVisitedPage.Disabled"); return customerModel; }); }); return model; } /// /// Prepare GDPR request (log) search model /// /// GDPR request search model /// /// A task that represents the asynchronous operation /// The task result contains the gDPR request search model /// public virtual async Task PrepareGdprLogSearchModelAsync(GdprLogSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare request types await _baseAdminModelFactory.PrepareGdprRequestTypesAsync(searchModel.AvailableRequestTypes); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare paged GDPR request list model /// /// GDPR request search model /// /// A task that represents the asynchronous operation /// The task result contains the gDPR request list model /// public virtual async Task PrepareGdprLogListModelAsync(GdprLogSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); var customerId = 0; var customerInfo = ""; if (!string.IsNullOrEmpty(searchModel.SearchEmail)) { var customer = await _customerService.GetCustomerByEmailAsync(searchModel.SearchEmail); if (customer != null) customerId = customer.Id; else { customerInfo = searchModel.SearchEmail; } } //get requests var gdprLog = await _gdprService.GetAllLogAsync( customerId: customerId, customerInfo: customerInfo, requestType: searchModel.SearchRequestTypeId > 0 ? (GdprRequestType?)searchModel.SearchRequestTypeId : null, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new GdprLogListModel().PrepareToGridAsync(searchModel, gdprLog, () => { return gdprLog.SelectAwait(async log => { //fill in model values from the entity var customer = await _customerService.GetCustomerByIdAsync(log.CustomerId); var requestModel = log.ToModel(); //fill in additional values (not existing in the entity) requestModel.CustomerInfo = customer != null && !customer.Deleted && !string.IsNullOrEmpty(customer.Email) ? customer.Email : log.CustomerInfo; requestModel.RequestType = await _localizationService.GetLocalizedEnumAsync(log.RequestType); requestModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(log.CreatedOnUtc, DateTimeKind.Utc); return requestModel; }); }); return model; } #endregion }