using Microsoft.AspNetCore.Mvc.Rendering; using Nop.Core; using Nop.Core.Domain.Orders; using Nop.Core.Domain.Payments; using Nop.Core.Domain.Shipping; using Nop.Services; using Nop.Services.Catalog; 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.Models.Reports; using Nop.Web.Framework.Models.Extensions; namespace Nop.Web.Areas.Admin.Factories; /// /// Represents the report model factory implementation /// public partial class ReportModelFactory : IReportModelFactory { #region Fields protected readonly IBaseAdminModelFactory _baseAdminModelFactory; protected readonly ICountryService _countryService; protected readonly ICustomerReportService _customerReportService; protected readonly ICustomerService _customerService; protected readonly IDateTimeHelper _dateTimeHelper; protected readonly ILocalizationService _localizationService; protected readonly IOrderReportService _orderReportService; protected readonly IPriceFormatter _priceFormatter; protected readonly IProductAttributeFormatter _productAttributeFormatter; protected readonly IProductService _productService; protected readonly IStoreContext _storeContext; protected readonly IWorkContext _workContext; #endregion #region Ctor public ReportModelFactory(IBaseAdminModelFactory baseAdminModelFactory, ICountryService countryService, ICustomerReportService customerReportService, ICustomerService customerService, IDateTimeHelper dateTimeHelper, ILocalizationService localizationService, IOrderReportService orderReportService, IPriceFormatter priceFormatter, IProductAttributeFormatter productAttributeFormatter, IProductService productService, IStoreContext storeContext, IWorkContext workContext) { _baseAdminModelFactory = baseAdminModelFactory; _countryService = countryService; _customerReportService = customerReportService; _customerService = customerService; _dateTimeHelper = dateTimeHelper; _localizationService = localizationService; _orderReportService = orderReportService; _priceFormatter = priceFormatter; _productAttributeFormatter = productAttributeFormatter; _productService = productService; _storeContext = storeContext; _workContext = workContext; } #endregion #region Utilities /// A task that represents the asynchronous operation protected virtual async Task> GetSalesSummaryReportAsync(SalesSummarySearchModel searchModel) { //get parameters to filter orders var orderStatusIds = (searchModel.OrderStatusIds?.Contains(0) ?? true) ? null : searchModel.OrderStatusIds.ToList(); var paymentStatusIds = (searchModel.PaymentStatusIds?.Contains(0) ?? true) ? null : searchModel.PaymentStatusIds.ToList(); var currentVendor = await _workContext.GetCurrentVendorAsync(); 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); //get sales summary var salesSummary = await _orderReportService.SalesSummaryReportAsync( createdFromUtc: startDateValue, createdToUtc: endDateValue, osIds: orderStatusIds, psIds: paymentStatusIds, billingCountryId: searchModel.BillingCountryId, groupBy: (GroupByOptions)searchModel.SearchGroupId, categoryId: searchModel.CategoryId, productId: searchModel.ProductId, manufacturerId: searchModel.ManufacturerId, vendorId: currentVendor?.Id ?? searchModel.VendorId, storeId: searchModel.StoreId, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); return salesSummary; } /// A task that represents the asynchronous operation protected virtual async Task> GetBestsellersReportAsync(BestsellerSearchModel searchModel) { //get parameters to filter bestsellers var orderStatus = searchModel.OrderStatusId > 0 ? (OrderStatus?)searchModel.OrderStatusId : null; var paymentStatus = searchModel.PaymentStatusId > 0 ? (PaymentStatus?)searchModel.PaymentStatusId : null; var currentVendor = await _workContext.GetCurrentVendorAsync(); if (currentVendor != null) searchModel.VendorId = currentVendor.Id; 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); //get bestsellers var bestsellers = await _orderReportService.BestSellersReportAsync(showHidden: true, createdFromUtc: startDateValue, createdToUtc: endDateValue, os: orderStatus, ps: paymentStatus, billingCountryId: searchModel.BillingCountryId, orderBy: OrderByEnum.OrderByTotalAmount, vendorId: searchModel.VendorId, categoryId: searchModel.CategoryId, manufacturerId: searchModel.ManufacturerId, storeId: searchModel.StoreId, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); return bestsellers; } #endregion #region Methods #region Sales summary /// /// Prepare sales summary search model /// /// Sales summary search model /// /// A task that represents the asynchronous operation /// The task result contains the sales summary search model /// public virtual async Task PrepareSalesSummarySearchModelAsync(SalesSummarySearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); searchModel.IsLoggedInAsVendor = await _workContext.GetCurrentVendorAsync() != null; //prepare available stores await _baseAdminModelFactory.PrepareStoresAsync(searchModel.AvailableStores); //prepare available order statuses await _baseAdminModelFactory.PrepareOrderStatusesAsync(searchModel.AvailableOrderStatuses); if (searchModel.AvailableOrderStatuses.Any()) { if (searchModel.OrderStatusIds?.Any() ?? false) { var ids = searchModel.OrderStatusIds.Select(id => id.ToString()); var statusItems = searchModel.AvailableOrderStatuses.Where(statusItem => ids.Contains(statusItem.Value)).ToList(); foreach (var statusItem in statusItems) { statusItem.Selected = true; } } else searchModel.AvailableOrderStatuses.FirstOrDefault().Selected = true; } //prepare available payment statuses await _baseAdminModelFactory.PreparePaymentStatusesAsync(searchModel.AvailablePaymentStatuses); if (searchModel.AvailablePaymentStatuses.Any()) { if (searchModel.PaymentStatusIds?.Any() ?? false) { var ids = searchModel.PaymentStatusIds.Select(id => id.ToString()); var statusItems = searchModel.AvailablePaymentStatuses.Where(statusItem => ids.Contains(statusItem.Value)).ToList(); foreach (var statusItem in statusItems) { statusItem.Selected = true; } } else searchModel.AvailablePaymentStatuses.FirstOrDefault().Selected = true; } //prepare available categories await _baseAdminModelFactory.PrepareCategoriesAsync(searchModel.AvailableCategories); //prepare available manufacturers await _baseAdminModelFactory.PrepareManufacturersAsync(searchModel.AvailableManufacturers); //prepare available billing countries searchModel.AvailableCountries = (await _countryService.GetAllCountriesForBillingAsync(showHidden: true)) .Select(country => new SelectListItem { Text = country.Name, Value = country.Id.ToString() }).ToList(); searchModel.AvailableCountries.Insert(0, new SelectListItem { Text = await _localizationService.GetResourceAsync("Admin.Common.All"), Value = "0" }); //prepare "group by" filter searchModel.GroupByOptions = (await GroupByOptions.Day.ToSelectListAsync()).ToList(); //prepare available vendors await _baseAdminModelFactory.PrepareVendorsAsync(searchModel.AvailableVendors); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare sales summary list model /// /// Sales summary search model /// /// A task that represents the asynchronous operation /// The task result contains the sales summary list model /// public virtual async Task PrepareSalesSummaryListModelAsync(SalesSummarySearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); var salesSummary = await GetSalesSummaryReportAsync(searchModel); //prepare list model var model = new SalesSummaryListModel().PrepareToGrid(searchModel, salesSummary, () => { return salesSummary.Select(sale => { //fill in model values from the entity var salesSummaryModel = new SalesSummaryModel { Summary = sale.Summary, NumberOfOrders = sale.NumberOfOrders, ProfitStr = sale.ProfitStr, Shipping = sale.Shipping, Tax = sale.Tax, OrderTotal = sale.OrderTotal }; return salesSummaryModel; }); }); return model; } #endregion #region LowStock /// /// Prepare low stock product search model /// /// Low stock product search model /// /// A task that represents the asynchronous operation /// The task result contains the low stock product search model /// public virtual async Task PrepareLowStockProductSearchModelAsync(LowStockProductSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare "published" filter (0 - all; 1 - published only; 2 - unpublished only) searchModel.AvailablePublishedOptions.Add(new SelectListItem { Value = "0", Text = await _localizationService.GetResourceAsync("Admin.Reports.LowStock.SearchPublished.All") }); searchModel.AvailablePublishedOptions.Add(new SelectListItem { Value = "1", Text = await _localizationService.GetResourceAsync("Admin.Reports.LowStock.SearchPublished.PublishedOnly") }); searchModel.AvailablePublishedOptions.Add(new SelectListItem { Value = "2", Text = await _localizationService.GetResourceAsync("Admin.Reports.LowStock.SearchPublished.UnpublishedOnly") }); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare paged low stock product list model /// /// Low stock product search model /// /// A task that represents the asynchronous operation /// The task result contains the low stock product list model /// public virtual async Task PrepareLowStockProductListModelAsync(LowStockProductSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter comments var publishedOnly = searchModel.SearchPublishedId == 0 ? null : searchModel.SearchPublishedId == 1 ? true : (bool?)false; var vendor = await _workContext.GetCurrentVendorAsync(); var vendorId = vendor?.Id ?? 0; //get low stock product and product combinations var products = await _productService.GetLowStockProductsAsync(vendorId: vendorId, loadPublishedOnly: publishedOnly); var combinations = await _productService.GetLowStockProductCombinationsAsync(vendorId: vendorId, loadPublishedOnly: publishedOnly); //prepare low stock product models var lowStockProductModels = new List(); lowStockProductModels.AddRange(await products.SelectAwait(async product => new LowStockProductModel { Id = product.Id, Name = product.Name, ManageInventoryMethod = await _localizationService.GetLocalizedEnumAsync(product.ManageInventoryMethod), StockQuantity = await _productService.GetTotalStockQuantityAsync(product), Published = product.Published }).ToListAsync()); var currentCustomer = await _workContext.GetCurrentCustomerAsync(); var currentStore = await _storeContext.GetCurrentStoreAsync(); lowStockProductModels.AddRange(await combinations.SelectAwait(async combination => { var product = await _productService.GetProductByIdAsync(combination.ProductId); return new LowStockProductModel { Id = combination.ProductId, Name = product.Name, Attributes = await _productAttributeFormatter .FormatAttributesAsync(product, combination.AttributesXml, currentCustomer, currentStore, "
", true, true, true, false), ManageInventoryMethod = await _localizationService.GetLocalizedEnumAsync(product.ManageInventoryMethod), StockQuantity = combination.StockQuantity, Published = product.Published }; }).ToListAsync()); var pagesList = lowStockProductModels.ToPagedList(searchModel); //prepare list model var model = new LowStockProductListModel().PrepareToGrid(searchModel, pagesList, () => pagesList); return model; } #endregion #region Bestsellers /// /// Prepare bestseller search model /// /// Bestseller search model /// /// A task that represents the asynchronous operation /// The task result contains the bestseller search model /// public virtual async Task PrepareBestsellerSearchModelAsync(BestsellerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); searchModel.IsLoggedInAsVendor = await _workContext.GetCurrentVendorAsync() != null; //prepare available stores await _baseAdminModelFactory.PrepareStoresAsync(searchModel.AvailableStores); //prepare available order statuses await _baseAdminModelFactory.PrepareOrderStatusesAsync(searchModel.AvailableOrderStatuses); //prepare available payment statuses await _baseAdminModelFactory.PreparePaymentStatusesAsync(searchModel.AvailablePaymentStatuses); //prepare available categories await _baseAdminModelFactory.PrepareCategoriesAsync(searchModel.AvailableCategories); //prepare available manufacturers await _baseAdminModelFactory.PrepareManufacturersAsync(searchModel.AvailableManufacturers); //prepare available billing countries searchModel.AvailableCountries = (await _countryService.GetAllCountriesForBillingAsync(showHidden: true)) .Select(country => new SelectListItem { Text = country.Name, Value = country.Id.ToString() }).ToList(); searchModel.AvailableCountries.Insert(0, new SelectListItem { Text = await _localizationService.GetResourceAsync("Admin.Common.All"), Value = "0" }); //prepare available vendors await _baseAdminModelFactory.PrepareVendorsAsync(searchModel.AvailableVendors); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare paged bestseller list model /// /// Bestseller search model /// /// A task that represents the asynchronous operation /// The task result contains the bestseller list model /// public virtual async Task PrepareBestsellerListModelAsync(BestsellerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); var bestsellers = await GetBestsellersReportAsync(searchModel); //prepare list model var model = await new BestsellerListModel().PrepareToGridAsync(searchModel, bestsellers, () => { return bestsellers.SelectAwait(async bestseller => { //fill in model values from the entity var bestsellerModel = new BestsellerModel { ProductId = bestseller.ProductId, TotalQuantity = bestseller.TotalQuantity, ProductName = bestseller.ProductName }; //fill in additional values (not existing in the entity) bestsellerModel.TotalAmount = await _priceFormatter.FormatPriceAsync(bestseller.TotalAmount, true, false); return bestsellerModel; }); }); return model; } /// /// Get a formatted bestsellers total amount /// /// Bestseller search model /// /// A task that represents the asynchronous operation /// The task result contains the bestseller total amount /// public virtual async Task GetBestsellerTotalAmountAsync(BestsellerSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter bestsellers var orderStatus = searchModel.OrderStatusId > 0 ? (OrderStatus?)searchModel.OrderStatusId : null; var paymentStatus = searchModel.PaymentStatusId > 0 ? (PaymentStatus?)searchModel.PaymentStatusId : null; var currentVendor = await _workContext.GetCurrentVendorAsync(); if (currentVendor != null) searchModel.VendorId = currentVendor.Id; 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); //get a total amount var totalAmount = await _orderReportService.BestSellersReportTotalAmountAsync( showHidden: true, createdFromUtc: startDateValue, createdToUtc: endDateValue, os: orderStatus, ps: paymentStatus, billingCountryId: searchModel.BillingCountryId, vendorId: searchModel.VendorId, categoryId: searchModel.CategoryId, manufacturerId: searchModel.ManufacturerId, storeId: searchModel.StoreId); return await _priceFormatter.FormatPriceAsync(totalAmount, true, false); } #endregion #region NeverSold /// /// Prepare never sold report search model /// /// Never sold report search model /// /// A task that represents the asynchronous operation /// The task result contains the never sold report search model /// public virtual async Task PrepareNeverSoldSearchModelAsync(NeverSoldReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); searchModel.IsLoggedInAsVendor = await _workContext.GetCurrentVendorAsync() != null; //prepare available stores await _baseAdminModelFactory.PrepareStoresAsync(searchModel.AvailableStores); //prepare available categories await _baseAdminModelFactory.PrepareCategoriesAsync(searchModel.AvailableCategories); //prepare available manufacturers await _baseAdminModelFactory.PrepareManufacturersAsync(searchModel.AvailableManufacturers); //prepare available vendors await _baseAdminModelFactory.PrepareVendorsAsync(searchModel.AvailableVendors); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare paged never sold report list model /// /// Never sold report search model /// /// A task that represents the asynchronous operation /// The task result contains the never sold report list model /// public virtual async Task PrepareNeverSoldListModelAsync(NeverSoldReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter neverSoldReports var currentVendor = await _workContext.GetCurrentVendorAsync(); if (currentVendor != null) searchModel.SearchVendorId = currentVendor.Id; 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); //get report items var items = await _orderReportService.ProductsNeverSoldAsync(showHidden: true, vendorId: searchModel.SearchVendorId, storeId: searchModel.SearchStoreId, categoryId: searchModel.SearchCategoryId, manufacturerId: searchModel.SearchManufacturerId, createdFromUtc: startDateValue, createdToUtc: endDateValue, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = new NeverSoldReportListModel().PrepareToGrid(searchModel, items, () => { //fill in model values from the entity return items.Select(item => new NeverSoldReportModel { ProductId = item.Id, ProductName = item.Name }); }); return model; } #endregion #region Country sales /// /// Prepare country report search model /// /// Country report search model /// /// A task that represents the asynchronous operation /// The task result contains the country report search model /// public virtual async Task PrepareCountrySalesSearchModelAsync(CountryReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare available order statuses await _baseAdminModelFactory.PrepareOrderStatusesAsync(searchModel.AvailableOrderStatuses); //prepare available payment statuses await _baseAdminModelFactory.PreparePaymentStatusesAsync(searchModel.AvailablePaymentStatuses); //prepare available stores await _baseAdminModelFactory.PrepareStoresAsync(searchModel.AvailableStores); //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } /// /// Prepare paged country report list model /// /// Country report search model /// /// A task that represents the asynchronous operation /// The task result contains the country report list model /// public virtual async Task PrepareCountrySalesListModelAsync(CountryReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter countryReports var orderStatus = searchModel.OrderStatusId > 0 ? (OrderStatus?)searchModel.OrderStatusId : null; var paymentStatus = searchModel.PaymentStatusId > 0 ? (PaymentStatus?)searchModel.PaymentStatusId : null; 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); //get items var items = (await _orderReportService.GetCountryReportAsync(os: orderStatus, ps: paymentStatus, storeId: searchModel.SearchStoreId, startTimeUtc: startDateValue, endTimeUtc: endDateValue)).ToPagedList(searchModel); //prepare list model var model = await new CountryReportListModel().PrepareToGridAsync(searchModel, items, () => { return items.SelectAwait(async item => { //fill in model values from the entity var countryReportModel = new CountryReportModel { TotalOrders = item.TotalOrders }; //fill in additional values (not existing in the entity) countryReportModel.SumOrders = await _priceFormatter.FormatPriceAsync(item.SumOrders, true, false); countryReportModel.CountryName = (await _countryService.GetCountryByIdAsync(item.CountryId ?? 0))?.Name; return countryReportModel; }); }); return model; } #endregion #region Customer reports /// /// Prepare customer reports search model /// /// Customer reports search model /// /// A task that represents the asynchronous operation /// The task result contains the customer reports search model /// public virtual async Task PrepareCustomerReportsSearchModelAsync(CustomerReportsSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare nested search models await PrepareBestCustomersReportByOrderTotalSearchModelAsync(searchModel.BestCustomersByOrderTotal); await PrepareBestCustomersReportSearchModelAsync(searchModel.BestCustomersByNumberOfOrders); await PrepareRegisteredCustomersReportSearchModelAsync(searchModel.RegisteredCustomers); return searchModel; } /// /// Prepare best customers by number of orders report search model /// /// Best customers report search model /// /// A task that represents the asynchronous operation /// The task result contains the best customers report search model /// protected virtual async Task PrepareBestCustomersReportSearchModelAsync(BestCustomersReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //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 best customers by order total report search model /// /// Best customers report search model /// /// A task that represents the asynchronous operation /// The task result contains the best customers report search model /// protected virtual async Task PrepareBestCustomersReportByOrderTotalSearchModelAsync(BestCustomersReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //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 registered customers report search model /// /// Registered customers report search model /// /// A task that represents the asynchronous operation /// The task result contains the registered customers report search model /// protected virtual Task PrepareRegisteredCustomersReportSearchModelAsync(RegisteredCustomersReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare page parameters searchModel.SetGridPageSize(); return Task.FromResult(searchModel); } /// /// Prepare paged best customers report list model /// /// Best customers report search model /// /// A task that represents the asynchronous operation /// The task result contains the best customers report list model /// public virtual async Task PrepareBestCustomersReportListModelAsync(BestCustomersReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get parameters to filter 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 orderStatus = searchModel.OrderStatusId > 0 ? (OrderStatus?)searchModel.OrderStatusId : null; var paymentStatus = searchModel.PaymentStatusId > 0 ? (PaymentStatus?)searchModel.PaymentStatusId : null; var shippingStatus = searchModel.ShippingStatusId > 0 ? (ShippingStatus?)searchModel.ShippingStatusId : null; //get report items var reportItems = await _customerReportService.GetBestCustomersReportAsync(createdFromUtc: startDateValue, createdToUtc: endDateValue, os: orderStatus, ps: paymentStatus, ss: shippingStatus, orderBy: searchModel.OrderBy, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new BestCustomersReportListModel().PrepareToGridAsync(searchModel, reportItems, () => { return reportItems.SelectAwait(async item => { //fill in model values from the entity var bestCustomersReportModel = new BestCustomersReportModel { CustomerId = item.CustomerId, OrderTotal = await _priceFormatter.FormatPriceAsync(item.OrderTotal, true, false), OrderCount = item.OrderCount }; //fill in additional values (not existing in the entity) var customer = await _customerService.GetCustomerByIdAsync(item.CustomerId); if (customer != null) { bestCustomersReportModel.CustomerName = (await _customerService.IsRegisteredAsync(customer)) ? customer.Email : await _localizationService.GetResourceAsync("Admin.Customers.Guest"); } return bestCustomersReportModel; }); }); return model; } /// /// Prepare paged registered customers report list model /// /// Registered customers report search model /// /// A task that represents the asynchronous operation /// The task result contains the registered customers report list model /// public virtual async Task PrepareRegisteredCustomersReportListModelAsync(RegisteredCustomersReportSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get report items var reportItems = new List { new() { Period = await _localizationService.GetResourceAsync("Admin.Reports.Customers.RegisteredCustomers.Fields.Period.7days"), Customers = await _customerReportService.GetRegisteredCustomersReportAsync(7) }, new() { Period = await _localizationService.GetResourceAsync("Admin.Reports.Customers.RegisteredCustomers.Fields.Period.14days"), Customers = await _customerReportService.GetRegisteredCustomersReportAsync(14) }, new() { Period = await _localizationService.GetResourceAsync("Admin.Reports.Customers.RegisteredCustomers.Fields.Period.month"), Customers = await _customerReportService.GetRegisteredCustomersReportAsync(30) }, new() { Period = await _localizationService.GetResourceAsync("Admin.Reports.Customers.RegisteredCustomers.Fields.Period.year"), Customers = await _customerReportService.GetRegisteredCustomersReportAsync(365) } }; var pagedList = reportItems.ToPagedList(searchModel); //prepare list model var model = new RegisteredCustomersReportListModel().PrepareToGrid(searchModel, pagedList, () => pagedList); return model; } #endregion #endregion }