using Nop.Core.Domain.Affiliates; using Nop.Services.Affiliates; using Nop.Services.Catalog; using Nop.Services.Common; using Nop.Services.Customers; using Nop.Services.Directory; using Nop.Services.Helpers; using Nop.Services.Localization; using Nop.Services.Orders; using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions; using Nop.Web.Areas.Admin.Models.Affiliates; using Nop.Web.Areas.Admin.Models.Common; using Nop.Web.Framework.Models.Extensions; namespace Nop.Web.Areas.Admin.Factories; /// /// Represents the affiliate model factory implementation /// public partial class AffiliateModelFactory : IAffiliateModelFactory { #region Fields protected readonly IAddressModelFactory _addressModelFactory; protected readonly IAddressService _addressService; protected readonly IAffiliateService _affiliateService; protected readonly IBaseAdminModelFactory _baseAdminModelFactory; protected readonly ICountryService _countryService; protected readonly ICustomerService _customerService; protected readonly IDateTimeHelper _dateTimeHelper; protected readonly ILocalizationService _localizationService; protected readonly IOrderService _orderService; protected readonly IPriceFormatter _priceFormatter; protected readonly IStateProvinceService _stateProvinceService; #endregion #region Ctor public AffiliateModelFactory(IAddressModelFactory addressModelFactory, IAddressService addressService, IAffiliateService affiliateService, IBaseAdminModelFactory baseAdminModelFactory, ICountryService countryService, ICustomerService customerService, IDateTimeHelper dateTimeHelper, ILocalizationService localizationService, IOrderService orderService, IPriceFormatter priceFormatter, IStateProvinceService stateProvinceService) { _addressModelFactory = addressModelFactory; _addressService = addressService; _affiliateService = affiliateService; _baseAdminModelFactory = baseAdminModelFactory; _countryService = countryService; _customerService = customerService; _dateTimeHelper = dateTimeHelper; _localizationService = localizationService; _orderService = orderService; _priceFormatter = priceFormatter; _stateProvinceService = stateProvinceService; } #endregion #region Utilities /// /// Prepare affiliated order search model /// /// Affiliated order search model /// Affiliate /// /// A task that represents the asynchronous operation /// The task result contains the affiliated order search model /// protected virtual async Task PrepareAffiliatedOrderSearchModelAsync(AffiliatedOrderSearchModel searchModel, Affiliate affiliate) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(affiliate); searchModel.AffliateId = affiliate.Id; //prepare available order, payment and shipping statuses await _baseAdminModelFactory.PrepareOrderStatusesAsync(searchModel.AvailableOrderStatuses); await _baseAdminModelFactory.PreparePaymentStatusesAsync(searchModel.AvailablePaymentStatuses); await _baseAdminModelFactory.PrepareShippingStatusesAsync(searchModel.AvailableShippingStatuses); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare affiliated customer search model /// /// Affiliated customer search model /// Affiliate /// Affiliated customer search model protected virtual AffiliatedCustomerSearchModel PrepareAffiliatedCustomerSearchModel(AffiliatedCustomerSearchModel searchModel, Affiliate affiliate) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(affiliate); searchModel.AffliateId = affiliate.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } #endregion #region Methods /// /// Prepare affiliate search model /// /// Affiliate search model /// /// A task that represents the asynchronous operation /// The task result contains the affiliate search model /// public virtual Task PrepareAffiliateSearchModelAsync(AffiliateSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare page parameters searchModel.SetGridPageSize(); return Task.FromResult(searchModel); } /// /// Prepare paged affiliate list model /// /// Affiliate search model /// /// A task that represents the asynchronous operation /// The task result contains the affiliate list model /// public virtual async Task PrepareAffiliateListModelAsync(AffiliateSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get affiliates var affiliates = await _affiliateService.GetAllAffiliatesAsync(searchModel.SearchFriendlyUrlName, searchModel.SearchFirstName, searchModel.SearchLastName, searchModel.LoadOnlyWithOrders, searchModel.OrdersCreatedFromUtc, searchModel.OrdersCreatedToUtc, searchModel.Page - 1, searchModel.PageSize, true); //prepare list model var model = await new AffiliateListModel().PrepareToGridAsync(searchModel, affiliates, () => { //fill in model values from the entity return affiliates.SelectAwait(async affiliate => { var address = await _addressService.GetAddressByIdAsync(affiliate.AddressId); var affiliateModel = affiliate.ToModel(); affiliateModel.Address = address.ToModel(); affiliateModel.Address.CountryName = (await _countryService.GetCountryByAddressAsync(address))?.Name; affiliateModel.Address.StateProvinceName = (await _stateProvinceService.GetStateProvinceByAddressAsync(address))?.Name; return affiliateModel; }); }); return model; } /// /// Prepare affiliate model /// /// Affiliate model /// Affiliate /// Whether to exclude populating of some properties of model /// /// A task that represents the asynchronous operation /// The task result contains the affiliate model /// public virtual async Task PrepareAffiliateModelAsync(AffiliateModel model, Affiliate affiliate, bool excludeProperties = false) { //fill in model values from the entity if (affiliate != null) { model ??= affiliate.ToModel(); model.Url = await _affiliateService.GenerateUrlAsync(affiliate); //prepare nested search models await PrepareAffiliatedOrderSearchModelAsync(model.AffiliatedOrderSearchModel, affiliate); PrepareAffiliatedCustomerSearchModel(model.AffiliatedCustomerSearchModel, affiliate); //whether to fill in some of properties if (!excludeProperties) { model.AdminComment = affiliate.AdminComment; model.FriendlyUrlName = affiliate.FriendlyUrlName; model.Active = affiliate.Active; } } //prepare address model var address = await _addressService.GetAddressByIdAsync(affiliate?.AddressId ?? 0); if (!excludeProperties && address != null) model.Address = address.ToModel(model.Address); await _addressModelFactory.PrepareAddressModelAsync(model.Address, address); model.Address.FirstNameRequired = true; model.Address.LastNameRequired = true; model.Address.EmailRequired = true; model.Address.CountryRequired = true; model.Address.CountyRequired = true; model.Address.CityRequired = true; model.Address.StreetAddressRequired = true; model.Address.ZipPostalCodeRequired = true; model.Address.PhoneRequired = true; return model; } /// /// Prepare paged affiliated order list model /// /// Affiliated order search model /// Affiliate /// /// A task that represents the asynchronous operation /// The task result contains the affiliated order list model /// public virtual async Task PrepareAffiliatedOrderListModelAsync(AffiliatedOrderSearchModel searchModel, Affiliate affiliate) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(affiliate); //get parameters to filter orders var startDateValue = !searchModel.StartDate.HasValue ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.StartDate.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()); var endDateValue = !searchModel.EndDate.HasValue ? null : (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.EndDate.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()).AddDays(1); var orderStatusIds = searchModel.OrderStatusId > 0 ? new List { searchModel.OrderStatusId } : null; var paymentStatusIds = searchModel.PaymentStatusId > 0 ? new List { searchModel.PaymentStatusId } : null; var shippingStatusIds = searchModel.ShippingStatusId > 0 ? new List { searchModel.ShippingStatusId } : null; //get orders var orders = await _orderService.SearchOrdersAsync(createdFromUtc: startDateValue, createdToUtc: endDateValue, osIds: orderStatusIds, psIds: paymentStatusIds, ssIds: shippingStatusIds, affiliateId: affiliate.Id, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new AffiliatedOrderListModel().PrepareToGridAsync(searchModel, orders, () => { //fill in model values from the entity return orders.SelectAwait(async order => { var affiliatedOrderModel = order.ToModel(); //fill in additional values (not existing in the entity) affiliatedOrderModel.OrderStatus = await _localizationService.GetLocalizedEnumAsync(order.OrderStatus); affiliatedOrderModel.PaymentStatus = await _localizationService.GetLocalizedEnumAsync(order.PaymentStatus); affiliatedOrderModel.ShippingStatus = await _localizationService.GetLocalizedEnumAsync(order.ShippingStatus); affiliatedOrderModel.OrderTotal = await _priceFormatter.FormatPriceAsync(order.OrderTotal, true, false); affiliatedOrderModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(order.CreatedOnUtc, DateTimeKind.Utc); return affiliatedOrderModel; }); }); return model; } /// /// Prepare paged affiliated customer list model /// /// Affiliated customer search model /// Affiliate /// /// A task that represents the asynchronous operation /// The task result contains the affiliated customer list model /// public virtual async Task PrepareAffiliatedCustomerListModelAsync(AffiliatedCustomerSearchModel searchModel, Affiliate affiliate) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(affiliate); //get customers var customers = await _customerService.GetAllCustomersAsync(affiliateId: affiliate.Id, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = new AffiliatedCustomerListModel().PrepareToGrid(searchModel, customers, () => { //fill in model values from the entity return customers.Select(customer => { var affiliatedCustomerModel = customer.ToModel(); affiliatedCustomerModel.Name = customer.Email; return affiliatedCustomerModel; }); }); return model; } #endregion }