130 lines
5.0 KiB
C#
130 lines
5.0 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// Customer report service
|
|
/// </summary>
|
|
public partial class CustomerReportService : ICustomerReportService
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly ICustomerService _customerService;
|
|
protected readonly IDateTimeHelper _dateTimeHelper;
|
|
protected readonly IRepository<Customer> _customerRepository;
|
|
protected readonly IRepository<Order> _orderRepository;
|
|
|
|
#endregion
|
|
|
|
#region Ctor
|
|
|
|
public CustomerReportService(ICustomerService customerService,
|
|
IDateTimeHelper dateTimeHelper,
|
|
IRepository<Customer> customerRepository,
|
|
IRepository<Order> orderRepository)
|
|
{
|
|
_customerService = customerService;
|
|
_dateTimeHelper = dateTimeHelper;
|
|
_customerRepository = customerRepository;
|
|
_orderRepository = orderRepository;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
/// <summary>
|
|
/// Get best customers
|
|
/// </summary>
|
|
/// <param name="createdFromUtc">Order created date from (UTC); null to load all records</param>
|
|
/// <param name="createdToUtc">Order created date to (UTC); null to load all records</param>
|
|
/// <param name="os">Order status; null to load all records</param>
|
|
/// <param name="ps">Order payment status; null to load all records</param>
|
|
/// <param name="ss">Order shipment status; null to load all records</param>
|
|
/// <param name="orderBy">1 - order by order total, 2 - order by number of orders</param>
|
|
/// <param name="pageIndex">Page index</param>
|
|
/// <param name="pageSize">Page size</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the report
|
|
/// </returns>
|
|
public virtual async Task<IPagedList<BestCustomerReportLine>> 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<BestCustomerReportLine>(tmp.Select(x => new BestCustomerReportLine
|
|
{
|
|
CustomerId = x.CustomerId,
|
|
OrderTotal = x.OrderTotal,
|
|
OrderCount = x.OrderCount
|
|
}).ToList(),
|
|
tmp.PageIndex, tmp.PageSize, tmp.TotalCount);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a report of customers registered in the last days
|
|
/// </summary>
|
|
/// <param name="days">Customers registered in the last days</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the number of registered customers
|
|
/// </returns>
|
|
public virtual async Task<int> 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
|
|
} |