feat(package): update package purchase methods and enhance Protobuf definitions
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 6m45s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 6m45s
- Changed package purchase method from DirectPurchase to Manual in multiple command handlers to reflect new business logic. - Added Manual purchase method to PackagePurchaseMethod enum for clarity. - Introduced new RPC method GetCustomerPackagePurchaseRollup in Protobuf for summarizing customer package purchases. - Updated UserPackagePurchaseProfile and UserPackagePurchaseService to support new rollup functionality. - Bumped Protobuf project version to accommodate new features.
This commit is contained in:
+51
@@ -0,0 +1,51 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserPackagePurchaseCQ.Queries.GetCustomerPackagePurchaseRollup;
|
||||
|
||||
public record GetCustomerPackagePurchaseRollupQuery : IRequest<GetCustomerPackagePurchaseRollupResponseDto>
|
||||
{
|
||||
public PaginationState? PaginationState { get; init; }
|
||||
public GetCustomerPackagePurchaseRollupFilter? Filter { get; init; }
|
||||
}
|
||||
|
||||
public class GetCustomerPackagePurchaseRollupFilter
|
||||
{
|
||||
public long? UserId { get; set; }
|
||||
public PackagePurchaseMethod? PurchaseMethod { get; set; }
|
||||
public DateTime? PurchasedFrom { get; set; }
|
||||
public DateTime? PurchasedTo { get; set; }
|
||||
}
|
||||
|
||||
public class GetCustomerPackagePurchaseRollupResponseDto
|
||||
{
|
||||
public MetaData MetaData { get; set; } = new();
|
||||
public List<CustomerPackagePurchaseRollupModel> Models { get; set; } = new();
|
||||
}
|
||||
|
||||
public class CustomerPackagePurchaseRollupModel
|
||||
{
|
||||
public long UserId { get; set; }
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
public string UserMobile { get; set; } = string.Empty;
|
||||
|
||||
public long FirstPackageId { get; set; }
|
||||
public string FirstPackageName { get; set; } = string.Empty;
|
||||
public long FirstAmount { get; set; }
|
||||
public DateTime FirstPurchasedAt { get; set; }
|
||||
|
||||
public long LastPackageId { get; set; }
|
||||
public string LastPackageName { get; set; } = string.Empty;
|
||||
public long LastAmount { get; set; }
|
||||
public DateTime LastPurchasedAt { get; set; }
|
||||
public PackagePurchaseMethod LastPurchaseMethod { get; set; }
|
||||
|
||||
public int PurchaseCount { get; set; }
|
||||
public long TotalAmount { get; set; }
|
||||
|
||||
public int DayaCount { get; set; }
|
||||
public long DayaAmount { get; set; }
|
||||
public int ManualCount { get; set; }
|
||||
public long ManualAmount { get; set; }
|
||||
public int GatewayCount { get; set; }
|
||||
public long GatewayAmount { get; set; }
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CMSMicroservice.Application.UserPackagePurchaseCQ.Queries.GetCustomerPackagePurchaseRollup;
|
||||
|
||||
public class GetCustomerPackagePurchaseRollupQueryHandler
|
||||
: IRequestHandler<GetCustomerPackagePurchaseRollupQuery, GetCustomerPackagePurchaseRollupResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
|
||||
public GetCustomerPackagePurchaseRollupQueryHandler(IApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<GetCustomerPackagePurchaseRollupResponseDto> Handle(
|
||||
GetCustomerPackagePurchaseRollupQuery request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var filter = request.Filter;
|
||||
var pagination = request.PaginationState ?? new PaginationState { PageNumber = 1, PageSize = 20 };
|
||||
if (pagination.PageNumber < 1) pagination.PageNumber = 1;
|
||||
if (pagination.PageSize < 1) pagination.PageSize = 20;
|
||||
|
||||
// خرید معتبر: بدون تراکنش یا تراکنش موفق
|
||||
var purchases = _context.UserPackagePurchases
|
||||
.AsNoTracking()
|
||||
.Include(x => x.User)
|
||||
.Include(x => x.Package)
|
||||
.Include(x => x.Transaction)
|
||||
.Where(x => x.TransactionId == null
|
||||
|| (x.Transaction != null && x.Transaction.PaymentStatus == PaymentStatus.Success));
|
||||
|
||||
if (filter?.UserId is > 0)
|
||||
purchases = purchases.Where(x => x.UserId == filter.UserId.Value);
|
||||
|
||||
if (filter?.PurchaseMethod != null)
|
||||
purchases = purchases.Where(x => x.PurchaseMethod == filter.PurchaseMethod.Value);
|
||||
|
||||
if (filter?.PurchasedFrom != null)
|
||||
purchases = purchases.Where(x => x.PurchasedAt >= filter.PurchasedFrom.Value);
|
||||
|
||||
if (filter?.PurchasedTo != null)
|
||||
purchases = purchases.Where(x => x.PurchasedAt <= filter.PurchasedTo.Value);
|
||||
|
||||
var rows = await purchases
|
||||
.Select(x => new
|
||||
{
|
||||
x.UserId,
|
||||
FirstName = x.User != null ? x.User.FirstName : null,
|
||||
LastName = x.User != null ? x.User.LastName : null,
|
||||
Mobile = x.User != null ? x.User.Mobile : null,
|
||||
x.PackageId,
|
||||
PackageName = x.Package != null ? x.Package.Title : null,
|
||||
x.Amount,
|
||||
x.PurchasedAt,
|
||||
x.PurchaseMethod
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var grouped = rows
|
||||
.GroupBy(x => x.UserId)
|
||||
.Select(g =>
|
||||
{
|
||||
var ordered = g.OrderBy(x => x.PurchasedAt).ThenBy(x => x.PackageId).ToList();
|
||||
var first = ordered.First();
|
||||
var last = ordered.Last();
|
||||
var userName = string.Join(" ",
|
||||
new[] { first.FirstName, first.LastName }.Where(s => !string.IsNullOrWhiteSpace(s))).Trim();
|
||||
|
||||
return new CustomerPackagePurchaseRollupModel
|
||||
{
|
||||
UserId = g.Key,
|
||||
UserName = string.IsNullOrWhiteSpace(userName)
|
||||
? (!string.IsNullOrWhiteSpace(first.Mobile) ? first.Mobile! : $"کاربر {g.Key}")
|
||||
: userName,
|
||||
UserMobile = first.Mobile ?? string.Empty,
|
||||
|
||||
FirstPackageId = first.PackageId,
|
||||
FirstPackageName = first.PackageName ?? string.Empty,
|
||||
FirstAmount = first.Amount,
|
||||
FirstPurchasedAt = first.PurchasedAt,
|
||||
|
||||
LastPackageId = last.PackageId,
|
||||
LastPackageName = last.PackageName ?? string.Empty,
|
||||
LastAmount = last.Amount,
|
||||
LastPurchasedAt = last.PurchasedAt,
|
||||
LastPurchaseMethod = last.PurchaseMethod,
|
||||
|
||||
PurchaseCount = ordered.Count,
|
||||
TotalAmount = ordered.Sum(x => x.Amount),
|
||||
|
||||
DayaCount = ordered.Count(x => x.PurchaseMethod == PackagePurchaseMethod.DayaLoan),
|
||||
DayaAmount = ordered.Where(x => x.PurchaseMethod == PackagePurchaseMethod.DayaLoan).Sum(x => x.Amount),
|
||||
ManualCount = ordered.Count(x => x.PurchaseMethod == PackagePurchaseMethod.Manual),
|
||||
ManualAmount = ordered.Where(x => x.PurchaseMethod == PackagePurchaseMethod.Manual).Sum(x => x.Amount),
|
||||
GatewayCount = ordered.Count(x => x.PurchaseMethod == PackagePurchaseMethod.DirectPurchase),
|
||||
GatewayAmount = ordered.Where(x => x.PurchaseMethod == PackagePurchaseMethod.DirectPurchase).Sum(x => x.Amount)
|
||||
};
|
||||
})
|
||||
.OrderByDescending(x => x.LastPurchasedAt)
|
||||
.ToList();
|
||||
|
||||
var totalCount = grouped.Count;
|
||||
var pageSize = pagination.PageSize;
|
||||
var pageNumber = pagination.PageNumber;
|
||||
var totalPage = pageSize > 0 ? (int)Math.Ceiling(totalCount / (double)pageSize) : 0;
|
||||
|
||||
var pageModels = grouped
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return new GetCustomerPackagePurchaseRollupResponseDto
|
||||
{
|
||||
MetaData = new MetaData
|
||||
{
|
||||
CurrentPage = pageNumber,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalPage = totalPage,
|
||||
HasPrevious = pageNumber > 1,
|
||||
HasNext = pageNumber < totalPage
|
||||
},
|
||||
Models = pageModels
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user