using Nop.Core; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Orders; using Nop.Core.Domain.Payments; using Nop.Core.Domain.Shipping; using Nop.Data; using Nop.Services.Helpers; using Nop.Services.Orders; namespace Nop.Services.Customers; /// /// Customer report service /// public partial class CustomerReportService : ICustomerReportService { #region Fields protected readonly ICustomerService _customerService; protected readonly IDateTimeHelper _dateTimeHelper; protected readonly IRepository _customerRepository; protected readonly IRepository _orderRepository; #endregion #region Ctor public CustomerReportService(ICustomerService customerService, IDateTimeHelper dateTimeHelper, IRepository customerRepository, IRepository orderRepository) { _customerService = customerService; _dateTimeHelper = dateTimeHelper; _customerRepository = customerRepository; _orderRepository = orderRepository; } #endregion #region Methods /// /// Get best customers /// /// Order created date from (UTC); null to load all records /// Order created date to (UTC); null to load all records /// Order status; null to load all records /// Order payment status; null to load all records /// Order shipment status; null to load all records /// 1 - order by order total, 2 - order by number of orders /// Page index /// Page size /// /// A task that represents the asynchronous operation /// The task result contains the report /// public virtual async Task> GetBestCustomersReportAsync(DateTime? createdFromUtc, DateTime? createdToUtc, OrderStatus? os, PaymentStatus? ps, ShippingStatus? ss, OrderByEnum orderBy, int pageIndex = 0, int pageSize = 214748364) { int? orderStatusId = null; if (os.HasValue) orderStatusId = (int)os.Value; int? paymentStatusId = null; if (ps.HasValue) paymentStatusId = (int)ps.Value; int? shippingStatusId = null; if (ss.HasValue) shippingStatusId = (int)ss.Value; var query1 = from c in _customerRepository.Table join o in _orderRepository.Table on c.Id equals o.CustomerId where (!createdFromUtc.HasValue || createdFromUtc.Value <= o.CreatedOnUtc) && (!createdToUtc.HasValue || createdToUtc.Value >= o.CreatedOnUtc) && (!orderStatusId.HasValue || orderStatusId == o.OrderStatusId) && (!paymentStatusId.HasValue || paymentStatusId == o.PaymentStatusId) && (!shippingStatusId.HasValue || shippingStatusId == o.ShippingStatusId) && !o.Deleted && !c.Deleted select new { c, o }; var query2 = from co in query1 group co by co.c.Id into g select new { CustomerId = g.Key, OrderTotal = g.Sum(x => x.o.OrderTotal), OrderCount = g.Count() }; query2 = orderBy switch { OrderByEnum.OrderByQuantity => query2.OrderByDescending(x => x.OrderCount), OrderByEnum.OrderByTotalAmount => query2.OrderByDescending(x => x.OrderTotal), _ => throw new ArgumentException("Wrong orderBy parameter", nameof(orderBy)), }; var tmp = await query2.ToPagedListAsync(pageIndex, pageSize); return new PagedList(tmp.Select(x => new BestCustomerReportLine { CustomerId = x.CustomerId, OrderTotal = x.OrderTotal, OrderCount = x.OrderCount }).ToList(), tmp.PageIndex, tmp.PageSize, tmp.TotalCount); } /// /// Gets a report of customers registered in the last days /// /// Customers registered in the last days /// /// A task that represents the asynchronous operation /// The task result contains the number of registered customers /// public virtual async Task GetRegisteredCustomersReportAsync(int days) { var date = (await _dateTimeHelper.ConvertToUserTimeAsync(DateTime.Now)).AddDays(-days); var registeredCustomerRole = await _customerService.GetCustomerRoleBySystemNameAsync(NopCustomerDefaults.RegisteredRoleName); if (registeredCustomerRole == null) return 0; return (await _customerService.GetAllCustomersAsync( date, customerRoleIds: new[] { registeredCustomerRole.Id })).Count; } #endregion }