feat: Implement Discount Product and Shopping Cart functionalities

- Added UpdateDiscountProductCommandValidator for validating discount product updates.
- Created GetDiscountProductByIdQuery and its handler for retrieving discount product details by ID.
- Implemented GetDiscountProductsQuery and handler for fetching a list of discount products with filtering options.
- Developed AddToCartCommand and handler for adding products to the shopping cart.
- Implemented ClearCartCommand and handler for clearing the shopping cart.
- Created RemoveFromCartCommand and handler for removing items from the cart.
- Added UpdateCartItemCountCommand and handler for updating the quantity of items in the cart.
- Developed GetUserCartQuery and handler for retrieving the user's shopping cart details.
- Implemented Product Tag functionalities including assigning tags to products, creating, updating, and deleting tags.
- Added queries for fetching all tags and products by tag.
This commit is contained in:
masoodafar-web
2025-12-04 02:41:19 +03:30
parent c9dab944fa
commit 4f400eabc5
92 changed files with 2285 additions and 41 deletions

View File

@@ -0,0 +1,181 @@
namespace BackOffice.BFF.Application.CommissionCQ.Queries.GetWithdrawalReports;
/// <summary>
/// گزارش برداشت‌ها بر اساس بازه زمانی و دسته‌بندی
/// </summary>
public record GetWithdrawalReportsQuery : IRequest<GetWithdrawalReportsResponseDto>
{
/// <summary>
/// تاریخ شروع (اختیاری - پیش‌فرض: 30 روز قبل)
/// </summary>
public DateTime? StartDate { get; init; }
/// <summary>
/// تاریخ پایان (اختیاری - پیش‌فرض: امروز)
/// </summary>
public DateTime? EndDate { get; init; }
/// <summary>
/// نوع دوره گزارش: 1=روزانه, 2=هفتگی, 3=ماهانه
/// </summary>
public ReportPeriodType PeriodType { get; init; } = ReportPeriodType.Daily;
/// <summary>
/// فیلتر وضعیت (اختیاری)
/// </summary>
public int? Status { get; init; }
/// <summary>
/// فیلتر شناسه کاربر (اختیاری)
/// </summary>
public long? UserId { get; init; }
}
/// <summary>
/// نوع دسته‌بندی گزارش
/// </summary>
public enum ReportPeriodType
{
/// <summary>
/// روزانه
/// </summary>
Daily = 1,
/// <summary>
/// هفتگی
/// </summary>
Weekly = 2,
/// <summary>
/// ماهانه
/// </summary>
Monthly = 3
}
/// <summary>
/// پاسخ گزارش برداشت‌ها
/// </summary>
public class GetWithdrawalReportsResponseDto
{
/// <summary>
/// گزارش‌های هر دوره
/// </summary>
public List<PeriodReportDto> PeriodReports { get; set; } = new();
/// <summary>
/// خلاصه کل گزارش
/// </summary>
public WithdrawalSummaryDto Summary { get; set; } = new();
}
/// <summary>
/// گزارش یک دوره زمانی
/// </summary>
public class PeriodReportDto
{
/// <summary>
/// برچسب دوره (مثلاً "2025-01-15" یا "هفته 3" یا "فروردین 1404")
/// </summary>
public string PeriodLabel { get; set; } = string.Empty;
/// <summary>
/// تاریخ شروع دوره
/// </summary>
public DateTime StartDate { get; set; }
/// <summary>
/// تاریخ پایان دوره
/// </summary>
public DateTime EndDate { get; set; }
/// <summary>
/// تعداد کل درخواست‌ها
/// </summary>
public int TotalRequests { get; set; }
/// <summary>
/// تعداد در انتظار
/// </summary>
public int PendingCount { get; set; }
/// <summary>
/// تعداد تایید شده
/// </summary>
public int ApprovedCount { get; set; }
/// <summary>
/// تعداد رد شده
/// </summary>
public int RejectedCount { get; set; }
/// <summary>
/// تعداد تکمیل شده
/// </summary>
public int CompletedCount { get; set; }
/// <summary>
/// تعداد ناموفق
/// </summary>
public int FailedCount { get; set; }
/// <summary>
/// مبلغ کل (ریال)
/// </summary>
public long TotalAmount { get; set; }
/// <summary>
/// مبلغ پرداخت شده (ریال)
/// </summary>
public long PaidAmount { get; set; }
/// <summary>
/// مبلغ در انتظار (ریال)
/// </summary>
public long PendingAmount { get; set; }
}
/// <summary>
/// خلاصه کل گزارش برداشت‌ها
/// </summary>
public class WithdrawalSummaryDto
{
/// <summary>
/// تعداد کل درخواست‌ها
/// </summary>
public int TotalRequests { get; set; }
/// <summary>
/// مبلغ کل درخواست‌ها (ریال)
/// </summary>
public long TotalAmount { get; set; }
/// <summary>
/// مبلغ کل پرداخت شده (ریال)
/// </summary>
public long TotalPaid { get; set; }
/// <summary>
/// مبلغ کل در انتظار (ریال)
/// </summary>
public long TotalPending { get; set; }
/// <summary>
/// مبلغ کل رد شده (ریال)
/// </summary>
public long TotalRejected { get; set; }
/// <summary>
/// میانگین مبلغ درخواست (ریال)
/// </summary>
public long AverageAmount { get; set; }
/// <summary>
/// تعداد کاربران منحصر به فرد
/// </summary>
public int UniqueUsers { get; set; }
/// <summary>
/// درصد موفقیت (0-100)
/// </summary>
public decimal SuccessRate { get; set; }
}

View File

@@ -0,0 +1,78 @@
using BackOffice.BFF.Commission.Protobuf;
using Google.Protobuf.WellKnownTypes;
namespace BackOffice.BFF.Application.CommissionCQ.Queries.GetWithdrawalReports;
public class GetWithdrawalReportsQueryHandler : IRequestHandler<GetWithdrawalReportsQuery, GetWithdrawalReportsResponseDto>
{
private readonly IApplicationContractContext _context;
public GetWithdrawalReportsQueryHandler(IApplicationContractContext context)
{
_context = context;
}
public async Task<GetWithdrawalReportsResponseDto> Handle(GetWithdrawalReportsQuery request, CancellationToken cancellationToken)
{
var grpcRequest = new GetWithdrawalReportsRequest
{
PeriodType = (int)request.PeriodType
};
// تنظیم بازه زمانی
if (request.StartDate.HasValue)
{
grpcRequest.StartDate = Timestamp.FromDateTime(request.StartDate.Value.ToUniversalTime());
}
if (request.EndDate.HasValue)
{
grpcRequest.EndDate = Timestamp.FromDateTime(request.EndDate.Value.ToUniversalTime());
}
// فیلتر وضعیت
if (request.Status.HasValue)
{
grpcRequest.Status = request.Status.Value;
}
// فیلتر کاربر
if (request.UserId.HasValue)
{
grpcRequest.UserId = request.UserId.Value;
}
var response = await _context.Commissions.GetWithdrawalReportsAsync(grpcRequest, cancellationToken: cancellationToken);
// تبدیل به DTO
return new GetWithdrawalReportsResponseDto
{
PeriodReports = response.PeriodReports.Select(p => new PeriodReportDto
{
PeriodLabel = p.PeriodLabel,
StartDate = p.StartDate.ToDateTime(),
EndDate = p.EndDate.ToDateTime(),
TotalRequests = p.TotalRequests,
PendingCount = p.PendingCount,
ApprovedCount = p.ApprovedCount,
RejectedCount = p.RejectedCount,
CompletedCount = p.CompletedCount,
FailedCount = p.FailedCount,
TotalAmount = p.TotalAmount,
PaidAmount = p.PaidAmount,
PendingAmount = p.PendingAmount
}).ToList(),
Summary = new WithdrawalSummaryDto
{
TotalRequests = response.Summary.TotalRequests,
TotalAmount = response.Summary.TotalAmount,
TotalPaid = response.Summary.TotalPaid,
TotalPending = response.Summary.TotalPending,
TotalRejected = response.Summary.TotalRejected,
AverageAmount = response.Summary.AverageAmount,
UniqueUsers = response.Summary.UniqueUsers,
SuccessRate = (decimal)response.Summary.SuccessRate
}
};
}
}