feat: Implement User Package Status and User Order Management features

- Added GetUserPackageStatus functionality with mapping and service implementation.
- Introduced UserOrder service methods for updating order status, applying discounts, and calculating order PV.
- Created Protobuf definitions for public messages and user orders, including necessary request and response messages.
- Implemented mapping profiles for package and user order related queries and commands.
- Developed query handlers and validators for new commands and queries in the application layer.
- Established PublicMessage service for handling public messages with appropriate gRPC endpoints.
This commit is contained in:
masoodafar-web
2025-12-04 03:43:28 +03:30
parent 256b41fcb5
commit 4b6f8187e5
34 changed files with 884 additions and 18 deletions

View File

@@ -0,0 +1,11 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using MediatR;
namespace BackOffice.BFF.Application.UserOrderCQ.Commands.ApplyDiscountToOrder;
public record ApplyDiscountToOrderCommand : IRequest<ApplyDiscountToOrderResponse>
{
public long OrderId { get; init; }
public long DiscountAmount { get; init; }
public string Reason { get; init; } = string.Empty;
}

View File

@@ -0,0 +1,27 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using MediatR;
using Microsoft.Extensions.Logging;
namespace BackOffice.BFF.Application.UserOrderCQ.Commands.ApplyDiscountToOrder;
public class ApplyDiscountToOrderCommandHandler : IRequestHandler<ApplyDiscountToOrderCommand, ApplyDiscountToOrderResponse>
{
private readonly UserOrderContract.UserOrderContractClient _orderClient;
private readonly ILogger<ApplyDiscountToOrderCommandHandler> _logger;
public ApplyDiscountToOrderCommandHandler(
UserOrderContract.UserOrderContractClient orderClient,
ILogger<ApplyDiscountToOrderCommandHandler> logger)
{
_orderClient = orderClient;
_logger = logger;
}
public async Task<ApplyDiscountToOrderResponse> Handle(ApplyDiscountToOrderCommand request, CancellationToken cancellationToken)
{
// TODO: پیاده‌سازی ApplyDiscountToOrder
// 1. ایجاد gRPC Request و فراخوانی CMS
// 2. return response از CMS
throw new NotImplementedException("ApplyDiscountToOrder needs implementation");
}
}

View File

@@ -0,0 +1,21 @@
using FluentValidation;
namespace BackOffice.BFF.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("دلیل تخفیف الزامی است");
}
}

View File

@@ -0,0 +1,10 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using MediatR;
namespace BackOffice.BFF.Application.UserOrderCQ.Commands.UpdateOrderStatus;
public record UpdateOrderStatusCommand : IRequest<UpdateOrderStatusResponse>
{
public long OrderId { get; init; }
public int NewStatus { get; init; }
}

View File

@@ -0,0 +1,27 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using MediatR;
using Microsoft.Extensions.Logging;
namespace BackOffice.BFF.Application.UserOrderCQ.Commands.UpdateOrderStatus;
public class UpdateOrderStatusCommandHandler : IRequestHandler<UpdateOrderStatusCommand, UpdateOrderStatusResponse>
{
private readonly UserOrderContract.UserOrderContractClient _orderClient;
private readonly ILogger<UpdateOrderStatusCommandHandler> _logger;
public UpdateOrderStatusCommandHandler(
UserOrderContract.UserOrderContractClient orderClient,
ILogger<UpdateOrderStatusCommandHandler> logger)
{
_orderClient = orderClient;
_logger = logger;
}
public async Task<UpdateOrderStatusResponse> Handle(UpdateOrderStatusCommand request, CancellationToken cancellationToken)
{
// TODO: پیاده‌سازی UpdateOrderStatus
// 1. ایجاد gRPC Request و فراخوانی CMS
// 2. return response از CMS
throw new NotImplementedException("UpdateOrderStatus needs implementation");
}
}

View File

@@ -0,0 +1,17 @@
using FluentValidation;
namespace BackOffice.BFF.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("وضعیت جدید معتبر نیست");
}
}

View File

@@ -0,0 +1,10 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using CMSMicroservice.Protobuf.Protos.UserOrder;
using MediatR;
namespace BackOffice.BFF.Application.UserOrderCQ.Queries.CalculateOrderPV;
public record CalculateOrderPVQuery : IRequest<CalculateOrderPVResponse>
{
public long OrderId { get; init; }
}

View File

@@ -0,0 +1,23 @@
using CMSMicroservice.Protobuf.Protos.UserOrder;
using MediatR;
using UserOrderContract = BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder.UserOrderContract;
namespace BackOffice.BFF.Application.UserOrderCQ.Queries.CalculateOrderPV;
public class CalculateOrderPVQueryHandler : IRequestHandler<CalculateOrderPVQuery, CalculateOrderPVResponse>
{
private readonly UserOrderContract.UserOrderContractClient _orderClient;
public CalculateOrderPVQueryHandler(UserOrderContract.UserOrderContractClient orderClient)
{
_orderClient = orderClient;
}
public async Task<CalculateOrderPVResponse> Handle(CalculateOrderPVQuery request, CancellationToken cancellationToken)
{
// TODO: پیاده‌سازی CalculateOrderPV
// 1. ایجاد gRPC Request و فراخوانی CMS
// 2. return response از CMS
throw new NotImplementedException("CalculateOrderPV needs implementation");
}
}

View File

@@ -0,0 +1,13 @@
using FluentValidation;
namespace BackOffice.BFF.Application.UserOrderCQ.Queries.CalculateOrderPV;
public class CalculateOrderPVQueryValidator : AbstractValidator<CalculateOrderPVQuery>
{
public CalculateOrderPVQueryValidator()
{
RuleFor(x => x.OrderId)
.GreaterThan(0)
.WithMessage("شناسه سفارش باید بزرگتر از 0 باشد");
}
}

View File

@@ -0,0 +1,14 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using MediatR;
namespace BackOffice.BFF.Application.UserOrderCQ.Queries.GetOrdersByDateRange;
public record GetOrdersByDateRangeQuery : IRequest<GetOrdersByDateRangeResponse>
{
public DateTime StartDate { get; init; }
public DateTime EndDate { get; init; }
public int? Status { get; init; }
public long? UserId { get; init; }
public int PageNumber { get; init; }
public int PageSize { get; init; }
}

View File

@@ -0,0 +1,21 @@
using FluentValidation;
namespace BackOffice.BFF.Application.UserOrderCQ.Queries.GetOrdersByDateRange;
public class GetOrdersByDateRangeQueryValidator : AbstractValidator<GetOrdersByDateRangeQuery>
{
public GetOrdersByDateRangeQueryValidator()
{
RuleFor(x => x.StartDate)
.LessThanOrEqualTo(x => x.EndDate)
.WithMessage("تاریخ شروع باید قبل از تاریخ پایان باشد");
RuleFor(x => x.PageNumber)
.GreaterThan(0)
.WithMessage("شماره صفحه باید بزرگتر از 0 باشد");
RuleFor(x => x.PageSize)
.InclusiveBetween(1, 100)
.WithMessage("اندازه صفحه باید بین 1 تا 100 باشد");
}
}

View File

@@ -0,0 +1,22 @@
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
using MediatR;
namespace BackOffice.BFF.Application.UserOrderCQ.Queries.GetOrdersByDateRange;
public class GetOrdersByDateRangeQueryHandler : IRequestHandler<GetOrdersByDateRangeQuery, GetOrdersByDateRangeResponse>
{
private readonly UserOrderContract.UserOrderContractClient _orderClient;
public GetOrdersByDateRangeQueryHandler(UserOrderContract.UserOrderContractClient orderClient)
{
_orderClient = orderClient;
}
public async Task<GetOrdersByDateRangeResponse> Handle(GetOrdersByDateRangeQuery request, CancellationToken cancellationToken)
{
// TODO: پیاده‌سازی GetOrdersByDateRange
// 1. ایجاد gRPC Request و فراخوانی CMS
// 2. return response از CMS
throw new NotImplementedException("GetOrdersByDateRange needs implementation");
}
}