Add validators and services for Product Galleries and Product Tags
- Implemented Create, Delete, Get, and Update validators for Product Galleries. - Added Create, Delete, Get, and Update validators for Product Tags. - Created service classes for handling Discount Categories, Discount Orders, Discount Products, Discount Shopping Cart, Product Categories, Product Galleries, and Product Tags. - Each service class integrates with CQRS for command and query handling. - Established mapping profiles for Product Galleries.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.CommissionCQ.Queries.GetWithdrawalReports;
|
||||
|
||||
/// <summary>
|
||||
/// Query برای دریافت گزارش برداشتها
|
||||
/// </summary>
|
||||
public record GetWithdrawalReportsQuery : IRequest<WithdrawalReportsDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// تاریخ شروع
|
||||
/// </summary>
|
||||
public DateTime? StartDate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ پایان
|
||||
/// </summary>
|
||||
public DateTime? EndDate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// نوع بازه زمانی (روزانه، هفتگی، ماهانه)
|
||||
/// </summary>
|
||||
public ReportPeriodType PeriodType { get; init; } = ReportPeriodType.Daily;
|
||||
|
||||
/// <summary>
|
||||
/// فیلتر بر اساس وضعیت
|
||||
/// </summary>
|
||||
public CommissionPayoutStatus? Status { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// شناسه کاربر (برای فیلتر کردن بر اساس کاربر خاص)
|
||||
/// </summary>
|
||||
public long? UserId { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// نوع بازه زمانی گزارش
|
||||
/// </summary>
|
||||
public enum ReportPeriodType
|
||||
{
|
||||
Daily = 1,
|
||||
Weekly = 2,
|
||||
Monthly = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO گزارش برداشتها
|
||||
/// </summary>
|
||||
public class WithdrawalReportsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// گزارشهای بازههای زمانی
|
||||
/// </summary>
|
||||
public List<PeriodReportDto> PeriodReports { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// خلاصه کلی
|
||||
/// </summary>
|
||||
public WithdrawalSummaryDto Summary { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// گزارش یک بازه زمانی
|
||||
/// </summary>
|
||||
public class PeriodReportDto
|
||||
{
|
||||
/// <summary>
|
||||
/// عنوان بازه (مثلاً "هفته 1" یا "دی ماه")
|
||||
/// </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>
|
||||
/// درصد موفقیت (Completed / Total)
|
||||
/// </summary>
|
||||
public decimal SuccessRate { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CMSMicroservice.Application.CommissionCQ.Queries.GetWithdrawalReports;
|
||||
|
||||
/// <summary>
|
||||
/// Handler برای دریافت گزارش برداشتها
|
||||
/// </summary>
|
||||
public class GetWithdrawalReportsQueryHandler : IRequestHandler<GetWithdrawalReportsQuery, WithdrawalReportsDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
|
||||
public GetWithdrawalReportsQueryHandler(IApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<WithdrawalReportsDto> Handle(GetWithdrawalReportsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// تعیین بازه زمانی پیشفرض (30 روز گذشته)
|
||||
var endDate = request.EndDate ?? DateTime.UtcNow;
|
||||
var startDate = request.StartDate ?? endDate.AddDays(-30);
|
||||
|
||||
// Query پایه
|
||||
var query = _context.UserCommissionPayouts
|
||||
.Where(p => p.Created >= startDate && p.Created <= endDate);
|
||||
|
||||
// فیلتر بر اساس وضعیت
|
||||
if (request.Status.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.Status == request.Status.Value);
|
||||
}
|
||||
|
||||
// فیلتر بر اساس کاربر
|
||||
if (request.UserId.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.UserId == request.UserId.Value);
|
||||
}
|
||||
|
||||
var payouts = await query
|
||||
.OrderBy(p => p.Created)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// گروهبندی بر اساس نوع بازه
|
||||
var periodReports = request.PeriodType switch
|
||||
{
|
||||
ReportPeriodType.Daily => GroupByDay(payouts, startDate, endDate),
|
||||
ReportPeriodType.Weekly => GroupByWeek(payouts, startDate, endDate),
|
||||
ReportPeriodType.Monthly => GroupByMonth(payouts, startDate, endDate),
|
||||
_ => GroupByDay(payouts, startDate, endDate)
|
||||
};
|
||||
|
||||
// محاسبه خلاصه کلی
|
||||
var summary = CalculateSummary(payouts);
|
||||
|
||||
return new WithdrawalReportsDto
|
||||
{
|
||||
PeriodReports = periodReports,
|
||||
Summary = summary
|
||||
};
|
||||
}
|
||||
|
||||
private List<PeriodReportDto> GroupByDay(List<Domain.Entities.Commission.UserCommissionPayout> payouts, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var reports = new List<PeriodReportDto>();
|
||||
var currentDate = startDate.Date;
|
||||
|
||||
while (currentDate <= endDate.Date)
|
||||
{
|
||||
var dayPayouts = payouts.Where(p => p.Created.Date == currentDate).ToList();
|
||||
|
||||
reports.Add(new PeriodReportDto
|
||||
{
|
||||
PeriodLabel = currentDate.ToString("yyyy-MM-dd"),
|
||||
StartDate = currentDate,
|
||||
EndDate = currentDate.AddDays(1).AddSeconds(-1),
|
||||
TotalRequests = dayPayouts.Count,
|
||||
PendingCount = dayPayouts.Count(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested),
|
||||
ApprovedCount = 0, // تایید جداگانه نداریم
|
||||
RejectedCount = dayPayouts.Count(p => p.Status == CommissionPayoutStatus.Cancelled),
|
||||
CompletedCount = dayPayouts.Count(p => p.Status == CommissionPayoutStatus.Withdrawn),
|
||||
FailedCount = dayPayouts.Count(p => p.Status == CommissionPayoutStatus.PaymentFailed),
|
||||
TotalAmount = dayPayouts.Sum(p => p.TotalAmount),
|
||||
PaidAmount = dayPayouts.Where(p => p.Status == CommissionPayoutStatus.Withdrawn).Sum(p => p.TotalAmount),
|
||||
PendingAmount = dayPayouts.Where(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested).Sum(p => p.TotalAmount)
|
||||
});
|
||||
|
||||
currentDate = currentDate.AddDays(1);
|
||||
}
|
||||
|
||||
return reports;
|
||||
}
|
||||
|
||||
private List<PeriodReportDto> GroupByWeek(List<Domain.Entities.Commission.UserCommissionPayout> payouts, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var reports = new List<PeriodReportDto>();
|
||||
var currentWeekStart = startDate.Date;
|
||||
|
||||
int weekNumber = 1;
|
||||
while (currentWeekStart <= endDate)
|
||||
{
|
||||
var weekEnd = currentWeekStart.AddDays(7).AddSeconds(-1);
|
||||
if (weekEnd > endDate)
|
||||
weekEnd = endDate;
|
||||
|
||||
var weekPayouts = payouts.Where(p => p.Created >= currentWeekStart && p.Created <= weekEnd).ToList();
|
||||
|
||||
reports.Add(new PeriodReportDto
|
||||
{
|
||||
PeriodLabel = $"هفته {weekNumber}",
|
||||
StartDate = currentWeekStart,
|
||||
EndDate = weekEnd,
|
||||
TotalRequests = weekPayouts.Count,
|
||||
PendingCount = weekPayouts.Count(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested),
|
||||
ApprovedCount = 0, // تایید جداگانه نداریم
|
||||
RejectedCount = weekPayouts.Count(p => p.Status == CommissionPayoutStatus.Cancelled),
|
||||
CompletedCount = weekPayouts.Count(p => p.Status == CommissionPayoutStatus.Withdrawn),
|
||||
FailedCount = weekPayouts.Count(p => p.Status == CommissionPayoutStatus.PaymentFailed),
|
||||
TotalAmount = weekPayouts.Sum(p => p.TotalAmount),
|
||||
PaidAmount = weekPayouts.Where(p => p.Status == CommissionPayoutStatus.Withdrawn).Sum(p => p.TotalAmount),
|
||||
PendingAmount = weekPayouts.Where(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested).Sum(p => p.TotalAmount)
|
||||
});
|
||||
|
||||
currentWeekStart = currentWeekStart.AddDays(7);
|
||||
weekNumber++;
|
||||
}
|
||||
|
||||
return reports;
|
||||
}
|
||||
|
||||
private List<PeriodReportDto> GroupByMonth(List<Domain.Entities.Commission.UserCommissionPayout> payouts, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var reports = new List<PeriodReportDto>();
|
||||
var currentMonthStart = new DateTime(startDate.Year, startDate.Month, 1);
|
||||
|
||||
while (currentMonthStart <= endDate)
|
||||
{
|
||||
var monthEnd = currentMonthStart.AddMonths(1).AddSeconds(-1);
|
||||
if (monthEnd > endDate)
|
||||
monthEnd = endDate;
|
||||
|
||||
var monthPayouts = payouts.Where(p => p.Created >= currentMonthStart && p.Created <= monthEnd).ToList();
|
||||
|
||||
var persianMonthName = GetPersianMonthName(currentMonthStart.Month);
|
||||
|
||||
reports.Add(new PeriodReportDto
|
||||
{
|
||||
PeriodLabel = $"{persianMonthName} {currentMonthStart.Year}",
|
||||
StartDate = currentMonthStart,
|
||||
EndDate = monthEnd,
|
||||
TotalRequests = monthPayouts.Count,
|
||||
PendingCount = monthPayouts.Count(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested),
|
||||
ApprovedCount = 0, // تایید جداگانه نداریم
|
||||
RejectedCount = monthPayouts.Count(p => p.Status == CommissionPayoutStatus.Cancelled),
|
||||
CompletedCount = monthPayouts.Count(p => p.Status == CommissionPayoutStatus.Withdrawn),
|
||||
FailedCount = monthPayouts.Count(p => p.Status == CommissionPayoutStatus.PaymentFailed),
|
||||
TotalAmount = monthPayouts.Sum(p => p.TotalAmount),
|
||||
PaidAmount = monthPayouts.Where(p => p.Status == CommissionPayoutStatus.Withdrawn).Sum(p => p.TotalAmount),
|
||||
PendingAmount = monthPayouts.Where(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested).Sum(p => p.TotalAmount)
|
||||
});
|
||||
|
||||
currentMonthStart = currentMonthStart.AddMonths(1);
|
||||
}
|
||||
|
||||
return reports;
|
||||
}
|
||||
|
||||
private WithdrawalSummaryDto CalculateSummary(List<Domain.Entities.Commission.UserCommissionPayout> payouts)
|
||||
{
|
||||
var totalRequests = payouts.Count;
|
||||
var completedCount = payouts.Count(p => p.Status == CommissionPayoutStatus.Withdrawn);
|
||||
|
||||
return new WithdrawalSummaryDto
|
||||
{
|
||||
TotalRequests = totalRequests,
|
||||
TotalAmount = payouts.Sum(p => p.TotalAmount),
|
||||
TotalPaid = payouts.Where(p => p.Status == CommissionPayoutStatus.Withdrawn).Sum(p => p.TotalAmount),
|
||||
TotalPending = payouts.Where(p => p.Status == CommissionPayoutStatus.Pending ||
|
||||
p.Status == CommissionPayoutStatus.WithdrawRequested).Sum(p => p.TotalAmount),
|
||||
TotalRejected = payouts.Where(p => p.Status == CommissionPayoutStatus.Cancelled).Sum(p => p.TotalAmount),
|
||||
AverageAmount = totalRequests > 0 ? payouts.Sum(p => p.TotalAmount) / totalRequests : 0,
|
||||
UniqueUsers = payouts.Select(p => p.UserId).Distinct().Count(),
|
||||
SuccessRate = totalRequests > 0 ? (decimal)completedCount / totalRequests * 100 : 0
|
||||
};
|
||||
}
|
||||
|
||||
private string GetPersianMonthName(int month)
|
||||
{
|
||||
return month switch
|
||||
{
|
||||
1 => "فروردین",
|
||||
2 => "اردیبهشت",
|
||||
3 => "خرداد",
|
||||
4 => "تیر",
|
||||
5 => "مرداد",
|
||||
6 => "شهریور",
|
||||
7 => "مهر",
|
||||
8 => "آبان",
|
||||
9 => "آذر",
|
||||
10 => "دی",
|
||||
11 => "بهمن",
|
||||
12 => "اسفند",
|
||||
_ => month.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user