feat: Implement Public Message Management Commands and Queries
- Add GetUserPackageStatusQueryValidator for user package status validation. - Create ArchiveMessageCommand and ArchiveMessageCommandHandler for archiving public messages. - Implement ArchiveMessageCommandValidator to validate message ID. - Introduce PublishMessageCommand and PublishMessageCommandHandler for publishing messages. - Add PublishMessageCommandValidator for validating publish message requests. - Implement GetPublicMessageQuery and GetPublicMessageQueryHandler for retrieving public messages. - Create GetPublicMessageQueryValidator for validating public message requests. - Add ApplyDiscountToOrderCommand and ApplyDiscountToOrderCommandHandler for applying discounts to orders. - Implement ApplyDiscountToOrderCommandValidator for validating discount application requests. - Create UpdateOrderStatusCommand and UpdateOrderStatusCommandHandler for changing order statuses. - Implement UpdateOrderStatusCommandValidator for validating order status updates. - Add CalculateOrderPVQuery and CalculateOrderPVQueryHandler for calculating order PV. - Implement CalculateOrderPVQueryValidator for validating PV calculation requests. - Create GetOrdersByDateRangeQuery and GetOrdersByDateRangeQueryHandler for retrieving orders by date range. - Implement GetOrdersByDateRangeQueryValidator for validating date range queries. - Add PublicMessage entity to represent public messages in the system. - Implement PublicMessageService for handling public message operations via gRPC.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.ApplyDiscountToOrder;
|
||||
|
||||
/// <summary>
|
||||
/// اعمال تخفیف به سفارش
|
||||
/// </summary>
|
||||
public record ApplyDiscountToOrderCommand : IRequest<ApplyDiscountToOrderResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه سفارش
|
||||
/// </summary>
|
||||
public long OrderId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ تخفیف (ریال)
|
||||
/// </summary>
|
||||
public long DiscountAmount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// دلیل تخفیف
|
||||
/// </summary>
|
||||
public string Reason { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// کد تخفیف (اختیاری)
|
||||
/// </summary>
|
||||
public string? DiscountCode { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پاسخ اعمال تخفیف
|
||||
/// </summary>
|
||||
public class ApplyDiscountToOrderResponseDto
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public long OriginalAmount { get; set; }
|
||||
public long DiscountAmount { get; set; }
|
||||
public long FinalAmount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.ApplyDiscountToOrder;
|
||||
|
||||
public class ApplyDiscountToOrderCommandHandler : IRequestHandler<ApplyDiscountToOrderCommand, ApplyDiscountToOrderResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<ApplyDiscountToOrderCommandHandler> _logger;
|
||||
|
||||
public ApplyDiscountToOrderCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
ILogger<ApplyDiscountToOrderCommandHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<ApplyDiscountToOrderResponseDto> Handle(ApplyDiscountToOrderCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: پیادهسازی اعمال تخفیف به سفارش
|
||||
// 1. پیدا کردن سفارش:
|
||||
// - var order = await _context.UserOrders.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken)
|
||||
// - بررسی null و پرتاب NotFoundException
|
||||
//
|
||||
// 2. بررسی شرایط اعمال تخفیف:
|
||||
// - سفارش نباید Delivered یا Cancelled باشد
|
||||
// - مبلغ تخفیف نباید بیشتر از Amount باشد
|
||||
// - if (order.DeliveryStatus == DeliveryStatus.Delivered || order.DeliveryStatus == DeliveryStatus.Cancelled)
|
||||
// throw new InvalidOperationException("نمیتوان به این سفارش تخفیف اعمال کرد")
|
||||
// - if (request.DiscountAmount > order.Amount)
|
||||
// throw new InvalidOperationException("مبلغ تخفیف نمیتواند بیشتر از مبلغ سفارش باشد")
|
||||
//
|
||||
// 3. محاسبه مبلغ نهایی:
|
||||
// - var originalAmount = order.Amount
|
||||
// - var newDiscountedPrice = order.Amount - request.DiscountAmount
|
||||
// - مطمئن شوید که منفی نشود: newDiscountedPrice = Math.Max(0, newDiscountedPrice)
|
||||
//
|
||||
// 4. بهروزرسانی سفارش:
|
||||
// - order.DiscountedPrice = newDiscountedPrice
|
||||
// - اگر فیلد OrderDiscountAmount وجود دارد، آن را هم بهروز کنید
|
||||
// - order.OrderDiscountAmount = request.DiscountAmount
|
||||
// - اضافه کردن به توضیحات:
|
||||
// order.DeliveryDescription = (order.DeliveryDescription ?? "") +
|
||||
// $"\nتخفیف اعمال شده: {request.DiscountAmount} ریال - دلیل: {request.Reason}"
|
||||
//
|
||||
// 5. ذخیره Log تخفیف (اختیاری - اگر جدول OrderDiscountLog دارید):
|
||||
// - var discountLog = new OrderDiscountLog {
|
||||
// OrderId = order.Id,
|
||||
// DiscountAmount = request.DiscountAmount,
|
||||
// Reason = request.Reason,
|
||||
// DiscountCode = request.DiscountCode,
|
||||
// AppliedAt = DateTime.UtcNow
|
||||
// }
|
||||
// - await _context.OrderDiscountLogs.AddAsync(discountLog, cancellationToken)
|
||||
//
|
||||
// 6. ذخیره و Log:
|
||||
// - await _context.SaveChangesAsync(cancellationToken)
|
||||
// - _logger.LogInformation("Discount {Amount} applied to order {OrderId}: {Reason}",
|
||||
// request.DiscountAmount, request.OrderId, request.Reason)
|
||||
//
|
||||
// 7. برگشت Response:
|
||||
// - return new ApplyDiscountToOrderResponseDto {
|
||||
// Success = true,
|
||||
// Message = "تخفیف با موفقیت اعمال شد",
|
||||
// OriginalAmount = originalAmount,
|
||||
// DiscountAmount = request.DiscountAmount,
|
||||
// FinalAmount = newDiscountedPrice
|
||||
// }
|
||||
//
|
||||
// نکته: این تخفیف برای تخفیفات دستی Admin است و جدا از تخفیفهای محصول
|
||||
|
||||
throw new NotImplementedException("ApplyDiscountToOrder needs implementation");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.ApplyDiscountToOrder;
|
||||
|
||||
public class ApplyDiscountToOrderCommandValidator : AbstractValidator<ApplyDiscountToOrderCommand>
|
||||
{
|
||||
public ApplyDiscountToOrderCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.OrderId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه سفارش باید بزرگتر از 0 باشد");
|
||||
|
||||
RuleFor(x => x.DiscountAmount)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("مبلغ تخفیف باید بزرگتر از 0 باشد");
|
||||
|
||||
RuleFor(x => x.Reason)
|
||||
.NotEmpty()
|
||||
.WithMessage("دلیل تخفیف الزامی است")
|
||||
.MaximumLength(500)
|
||||
.WithMessage("دلیل تخفیف نمیتواند بیشتر از 500 کاراکتر باشد");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.UpdateOrderStatus;
|
||||
|
||||
/// <summary>
|
||||
/// تغییر وضعیت سفارش
|
||||
/// </summary>
|
||||
public record UpdateOrderStatusCommand : IRequest<UpdateOrderStatusResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه سفارش
|
||||
/// </summary>
|
||||
public long OrderId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// وضعیت تحویل جدید
|
||||
/// </summary>
|
||||
public DeliveryStatus NewStatus { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// توضیحات (اختیاری)
|
||||
/// </summary>
|
||||
public string? Description { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پاسخ تغییر وضعیت سفارش
|
||||
/// </summary>
|
||||
public class UpdateOrderStatusResponseDto
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public DeliveryStatus CurrentStatus { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.UpdateOrderStatus;
|
||||
|
||||
public class UpdateOrderStatusCommandHandler : IRequestHandler<UpdateOrderStatusCommand, UpdateOrderStatusResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<UpdateOrderStatusCommandHandler> _logger;
|
||||
|
||||
public UpdateOrderStatusCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
ILogger<UpdateOrderStatusCommandHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<UpdateOrderStatusResponseDto> Handle(UpdateOrderStatusCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: پیادهسازی تغییر وضعیت سفارش
|
||||
// 1. پیدا کردن سفارش:
|
||||
// - await _context.UserOrders.FirstOrDefaultAsync(o => o.Id == request.OrderId)
|
||||
// - بررسی null و پرتاب NotFoundException
|
||||
//
|
||||
// 2. بررسیهای انتقال وضعیت (State Transition Validation):
|
||||
// - نمیتوان از Delivered به Cancelled رفت
|
||||
// - نمیتوان از Cancelled به سایر وضعیتها رفت
|
||||
// - الگوی معمول: Pending → Processing → Shipped → Delivered
|
||||
// - Cancelled میتواند از Pending, Processing, Shipped باشد
|
||||
//
|
||||
// 3. تغییر وضعیت:
|
||||
// - order.DeliveryStatus = request.NewStatus
|
||||
// - اگر Description داریم: order.DeliveryDescription = request.Description
|
||||
// - تنظیم تاریخهای مربوطه:
|
||||
// * اگر NewStatus == Delivered → order.DeliveredAt = DateTime.UtcNow
|
||||
// * اگر NewStatus == Shipped → order.ShippedAt = DateTime.UtcNow
|
||||
// * اگر NewStatus == Processing → order.ProcessedAt = DateTime.UtcNow
|
||||
//
|
||||
// 4. ذخیره و Log:
|
||||
// - await _context.SaveChangesAsync(cancellationToken)
|
||||
// - _logger.LogInformation("Order {OrderId} status changed to {NewStatus}", request.OrderId, request.NewStatus)
|
||||
//
|
||||
// 5. برگشت Response:
|
||||
// - Success = true
|
||||
// - Message = "وضعیت سفارش با موفقیت تغییر کرد"
|
||||
// - CurrentStatus = order.DeliveryStatus
|
||||
//
|
||||
// نکته: برای validation دقیقتر، میتوان یک State Machine برای انتقالهای مجاز تعریف کرد
|
||||
|
||||
throw new NotImplementedException("UpdateOrderStatus needs implementation");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.UpdateOrderStatus;
|
||||
|
||||
public class UpdateOrderStatusCommandValidator : AbstractValidator<UpdateOrderStatusCommand>
|
||||
{
|
||||
public UpdateOrderStatusCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.OrderId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه سفارش باید بزرگتر از 0 باشد");
|
||||
|
||||
RuleFor(x => x.NewStatus)
|
||||
.IsInEnum()
|
||||
.WithMessage("وضعیت تحویل نامعتبر است");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Queries.CalculateOrderPV;
|
||||
|
||||
/// <summary>
|
||||
/// محاسبه امتیاز PV سفارش
|
||||
/// </summary>
|
||||
public record CalculateOrderPVQuery : IRequest<CalculateOrderPVResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه سفارش
|
||||
/// </summary>
|
||||
public long OrderId { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پاسخ محاسبه PV سفارش
|
||||
/// </summary>
|
||||
public class CalculateOrderPVResponseDto
|
||||
{
|
||||
/// <summary>
|
||||
/// مجموع امتیاز PV سفارش
|
||||
/// </summary>
|
||||
public decimal TotalPV { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// جزئیات PV هر محصول
|
||||
/// </summary>
|
||||
public List<ProductPVDto> ProductPVs { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ قابل پرداخت
|
||||
/// </summary>
|
||||
public long PayableAmount { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// جزئیات PV یک محصول در سفارش
|
||||
/// </summary>
|
||||
public class ProductPVDto
|
||||
{
|
||||
public long ProductId { get; set; }
|
||||
public string ProductTitle { get; set; } = string.Empty;
|
||||
public int Quantity { get; set; }
|
||||
public decimal UnitPV { get; set; }
|
||||
public decimal TotalPV { get; set; }
|
||||
public long UnitPrice { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Queries.CalculateOrderPV;
|
||||
|
||||
public class CalculateOrderPVQueryHandler : IRequestHandler<CalculateOrderPVQuery, CalculateOrderPVResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<CalculateOrderPVQueryHandler> _logger;
|
||||
|
||||
public CalculateOrderPVQueryHandler(
|
||||
IApplicationDbContext context,
|
||||
ILogger<CalculateOrderPVQueryHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<CalculateOrderPVResponseDto> Handle(CalculateOrderPVQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: پیادهسازی محاسبه PV سفارش
|
||||
// 1. پیدا کردن سفارش و جزئیات:
|
||||
// - var order = await _context.UserOrders
|
||||
// .Include(o => o.FactorDetails)
|
||||
// .ThenInclude(fd => fd.Product)
|
||||
// .FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken)
|
||||
// - بررسی null و پرتاب NotFoundException
|
||||
//
|
||||
// 2. محاسبه PV هر محصول:
|
||||
// - var productPVs = new List<ProductPVDto>()
|
||||
// - decimal totalPV = 0
|
||||
// - foreach (var detail in order.FactorDetails):
|
||||
// * محاسبه PV واحد محصول (فرض: قیمت / 10000 یا از فیلد Product.PV اگر وجود دارد):
|
||||
// decimal unitPV = detail.Product.PV ?? (detail.Product.Price / 10000m)
|
||||
// * محاسبه PV کل این آیتم:
|
||||
// decimal itemTotalPV = unitPV * detail.Count
|
||||
// * اضافه به لیست:
|
||||
// productPVs.Add(new ProductPVDto {
|
||||
// ProductId = detail.ProductId,
|
||||
// ProductTitle = detail.Product.Title,
|
||||
// Quantity = detail.Count,
|
||||
// UnitPV = unitPV,
|
||||
// TotalPV = itemTotalPV,
|
||||
// UnitPrice = detail.Product.Price
|
||||
// })
|
||||
// * اضافه به مجموع:
|
||||
// totalPV += itemTotalPV
|
||||
//
|
||||
// 3. برگشت Response:
|
||||
// - _logger.LogInformation("Calculated PV for order {OrderId}: {TotalPV}", request.OrderId, totalPV)
|
||||
// - return new CalculateOrderPVResponseDto {
|
||||
// TotalPV = totalPV,
|
||||
// ProductPVs = productPVs,
|
||||
// PayableAmount = order.DiscountedPrice
|
||||
// }
|
||||
//
|
||||
// نکته: PV (Point Value) معمولاً برای سیستمهای MLM و کمیسیون شبکه استفاده میشود
|
||||
// نکته: فرمول محاسبه PV باید بر اساس business logic شما باشد (قیمت/10000 فقط مثال است)
|
||||
// نکته: اگر entity Product فیلد PV ندارد، باید اضافه شود یا از Configuration استفاده کنید
|
||||
|
||||
throw new NotImplementedException("CalculateOrderPV needs implementation");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Queries.CalculateOrderPV;
|
||||
|
||||
public class CalculateOrderPVQueryValidator : AbstractValidator<CalculateOrderPVQuery>
|
||||
{
|
||||
public CalculateOrderPVQueryValidator()
|
||||
{
|
||||
RuleFor(x => x.OrderId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه سفارش باید بزرگتر از 0 باشد");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Queries.GetOrdersByDateRange;
|
||||
|
||||
/// <summary>
|
||||
/// دریافت سفارشات بر اساس بازه زمانی
|
||||
/// </summary>
|
||||
public record GetOrdersByDateRangeQuery : IRequest<GetOrdersByDateRangeResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// تاریخ شروع (UTC)
|
||||
/// </summary>
|
||||
public DateTime StartDate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ پایان (UTC)
|
||||
/// </summary>
|
||||
public DateTime EndDate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// فیلتر وضعیت تحویل (اختیاری)
|
||||
/// </summary>
|
||||
public DeliveryStatus? Status { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// شناسه کاربر (اختیاری - برای فیلتر بر اساس کاربر)
|
||||
/// </summary>
|
||||
public long? UserId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// شماره صفحه
|
||||
/// </summary>
|
||||
public int PageIndex { get; init; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// تعداد در صفحه
|
||||
/// </summary>
|
||||
public int PageSize { get; init; } = 20;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پاسخ لیست سفارشات
|
||||
/// </summary>
|
||||
public class GetOrdersByDateRangeResponseDto
|
||||
{
|
||||
public MetaData MetaData { get; set; } = new();
|
||||
public List<OrderSummaryDto> Orders { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// خلاصه اطلاعات سفارش
|
||||
/// </summary>
|
||||
public class OrderSummaryDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public long UserId { get; set; }
|
||||
public string UserFullName { get; set; } = string.Empty;
|
||||
public long Amount { get; set; }
|
||||
public long DiscountedPrice { get; set; }
|
||||
public DeliveryStatus Status { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public DateTime? ShippedAt { get; set; }
|
||||
public DateTime? DeliveredAt { get; set; }
|
||||
public int ItemsCount { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Queries.GetOrdersByDateRange;
|
||||
|
||||
public class GetOrdersByDateRangeQueryHandler : IRequestHandler<GetOrdersByDateRangeQuery, GetOrdersByDateRangeResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<GetOrdersByDateRangeQueryHandler> _logger;
|
||||
|
||||
public GetOrdersByDateRangeQueryHandler(
|
||||
IApplicationDbContext context,
|
||||
ILogger<GetOrdersByDateRangeQueryHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<GetOrdersByDateRangeResponseDto> Handle(GetOrdersByDateRangeQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: پیادهسازی دریافت سفارشات بر اساس بازه زمانی
|
||||
// 1. شروع Query:
|
||||
// - var query = _context.UserOrders.AsQueryable()
|
||||
// - Include User برای نام کاربر: .Include(o => o.User)
|
||||
// - Include FactorDetails برای شمارش تعداد آیتمها: .Include(o => o.FactorDetails)
|
||||
//
|
||||
// 2. اعمال فیلتر بازه زمانی:
|
||||
// - query = query.Where(o => o.Created >= request.StartDate && o.Created <= request.EndDate)
|
||||
//
|
||||
// 3. اعمال فیلترهای اختیاری:
|
||||
// - اگر request.Status.HasValue:
|
||||
// query = query.Where(o => o.DeliveryStatus == request.Status.Value)
|
||||
// - اگر request.UserId.HasValue:
|
||||
// query = query.Where(o => o.UserId == request.UserId.Value)
|
||||
//
|
||||
// 4. محاسبه تعداد کل:
|
||||
// - var totalCount = await query.CountAsync(cancellationToken)
|
||||
//
|
||||
// 5. مرتبسازی و Pagination:
|
||||
// - query = query.OrderByDescending(o => o.Created)
|
||||
// - query = query.Skip((request.PageIndex - 1) * request.PageSize)
|
||||
// - query = query.Take(request.PageSize)
|
||||
//
|
||||
// 6. دریافت دادهها:
|
||||
// - var orders = await query.ToListAsync(cancellationToken)
|
||||
//
|
||||
// 7. Mapping به DTO:
|
||||
// - var orderDtos = orders.Select(o => new OrderSummaryDto {
|
||||
// Id = o.Id,
|
||||
// UserId = o.UserId,
|
||||
// UserFullName = $"{o.User.Firstname} {o.User.Lastname}",
|
||||
// Amount = o.Amount,
|
||||
// DiscountedPrice = o.DiscountedPrice,
|
||||
// Status = o.DeliveryStatus,
|
||||
// Created = o.Created,
|
||||
// ShippedAt = o.ShippedAt,
|
||||
// DeliveredAt = o.DeliveredAt,
|
||||
// ItemsCount = o.FactorDetails.Count
|
||||
// }).ToList()
|
||||
//
|
||||
// 8. ساخت MetaData:
|
||||
// - var totalPages = (int)Math.Ceiling(totalCount / (double)request.PageSize)
|
||||
// - MetaData = new MetaData {
|
||||
// CurrentPage = request.PageIndex,
|
||||
// TotalPage = totalPages,
|
||||
// PageSize = request.PageSize,
|
||||
// TotalCount = totalCount,
|
||||
// HasNext = request.PageIndex < totalPages,
|
||||
// HasPrevious = request.PageIndex > 1
|
||||
// }
|
||||
//
|
||||
// 9. Log و برگشت:
|
||||
// - _logger.LogInformation("Retrieved {Count} orders for date range {Start} to {End}", orders.Count, request.StartDate, request.EndDate)
|
||||
// - return new GetOrdersByDateRangeResponseDto { MetaData = metaData, Orders = orderDtos }
|
||||
//
|
||||
// نکته: برای performance بهتر، میتوان از AsNoTracking() استفاده کرد
|
||||
|
||||
throw new NotImplementedException("GetOrdersByDateRange needs implementation");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Queries.GetOrdersByDateRange;
|
||||
|
||||
public class GetOrdersByDateRangeQueryValidator : AbstractValidator<GetOrdersByDateRangeQuery>
|
||||
{
|
||||
public GetOrdersByDateRangeQueryValidator()
|
||||
{
|
||||
RuleFor(x => x.StartDate)
|
||||
.LessThanOrEqualTo(x => x.EndDate)
|
||||
.WithMessage("تاریخ شروع باید کوچکتر یا مساوی تاریخ پایان باشد");
|
||||
|
||||
RuleFor(x => x.EndDate)
|
||||
.LessThanOrEqualTo(DateTime.UtcNow.AddDays(1))
|
||||
.WithMessage("تاریخ پایان نمیتواند در آینده باشد");
|
||||
|
||||
RuleFor(x => x.PageIndex)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شماره صفحه باید بزرگتر از 0 باشد");
|
||||
|
||||
RuleFor(x => x.PageSize)
|
||||
.InclusiveBetween(1, 100)
|
||||
.WithMessage("تعداد در صفحه باید بین 1 تا 100 باشد");
|
||||
|
||||
// بازه زمانی نباید بیش از 1 سال باشد
|
||||
RuleFor(x => x)
|
||||
.Must(x => (x.EndDate - x.StartDate).TotalDays <= 365)
|
||||
.WithMessage("بازه زمانی نمیتواند بیش از 1 سال باشد");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user