feat: add IsActive field to UserClubFeatures for admin management
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
namespace CMSMicroservice.Application.CommissionCQ.Queries.GetAvailableWeeks;
|
||||
|
||||
/// <summary>
|
||||
/// دریافت لیست هفتههای قابل انتخاب برای محاسبه کمیسیون
|
||||
/// </summary>
|
||||
public class GetAvailableWeeksQuery : IRequest<GetAvailableWeeksResponseDto>
|
||||
{
|
||||
/// <summary>تعداد هفتههای آینده برای نمایش (پیشفرض: 4)</summary>
|
||||
public int FutureWeeksCount { get; init; } = 4;
|
||||
|
||||
/// <summary>تعداد هفتههای گذشته برای نمایش (پیشفرض: 12)</summary>
|
||||
public int PastWeeksCount { get; init; } = 12;
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Globalization;
|
||||
|
||||
namespace CMSMicroservice.Application.CommissionCQ.Queries.GetAvailableWeeks;
|
||||
|
||||
public class GetAvailableWeeksQueryHandler : IRequestHandler<GetAvailableWeeksQuery, GetAvailableWeeksResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
|
||||
public GetAvailableWeeksQueryHandler(IApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<GetAvailableWeeksResponseDto> Handle(
|
||||
GetAvailableWeeksQuery request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var currentDate = DateTime.Now;
|
||||
var currentWeekNumber = GetWeekNumber(currentDate);
|
||||
|
||||
// دریافت هفتههای محاسبه شده از دیتابیس
|
||||
var calculatedPools = await _context.WeeklyCommissionPools
|
||||
.Where(p => p.IsCalculated)
|
||||
.OrderByDescending(p => p.WeekNumber)
|
||||
.Take(request.PastWeeksCount)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// دریافت لاگهای اجرا
|
||||
var executionLogs = await _context.WorkerExecutionLogs
|
||||
.Where(log => log.Status == WorkerExecutionStatus.Success ||
|
||||
log.Status == WorkerExecutionStatus.Failed)
|
||||
.GroupBy(log => log.WeekNumber)
|
||||
.Select(g => new
|
||||
{
|
||||
WeekNumber = g.Key,
|
||||
LastLog = g.OrderByDescending(l => l.StartedAt).First()
|
||||
})
|
||||
.ToDictionaryAsync(x => x.WeekNumber, x => x.LastLog, cancellationToken);
|
||||
|
||||
var allWeeks = new List<WeekInfoDto>();
|
||||
|
||||
// هفته جاری
|
||||
var currentWeekInfo = CreateWeekInfo(currentDate, currentWeekNumber, calculatedPools, executionLogs);
|
||||
|
||||
// هفتههای گذشته (12 هفته)
|
||||
var pastWeeks = new List<WeekInfoDto>();
|
||||
for (int i = 1; i <= request.PastWeeksCount; i++)
|
||||
{
|
||||
var pastDate = currentDate.AddDays(-7 * i);
|
||||
var weekNumber = GetWeekNumber(pastDate);
|
||||
pastWeeks.Add(CreateWeekInfo(pastDate, weekNumber, calculatedPools, executionLogs));
|
||||
}
|
||||
|
||||
// هفتههای آینده (4 هفته)
|
||||
var futureWeeks = new List<WeekInfoDto>();
|
||||
for (int i = 1; i <= request.FutureWeeksCount; i++)
|
||||
{
|
||||
var futureDate = currentDate.AddDays(7 * i);
|
||||
var weekNumber = GetWeekNumber(futureDate);
|
||||
futureWeeks.Add(CreateWeekInfo(futureDate, weekNumber, calculatedPools, executionLogs));
|
||||
}
|
||||
|
||||
// تفکیک به calculated و pending
|
||||
var calculatedWeeks = pastWeeks.Where(w => w.IsCalculated).ToList();
|
||||
var pendingWeeks = pastWeeks.Where(w => !w.IsCalculated).ToList();
|
||||
|
||||
return new GetAvailableWeeksResponseDto
|
||||
{
|
||||
CurrentWeek = currentWeekInfo,
|
||||
CalculatedWeeks = calculatedWeeks,
|
||||
PendingWeeks = pendingWeeks,
|
||||
FutureWeeks = futureWeeks
|
||||
};
|
||||
}
|
||||
|
||||
private WeekInfoDto CreateWeekInfo(
|
||||
DateTime date,
|
||||
string weekNumber,
|
||||
List<Domain.Entities.Commission.WeeklyCommissionPool> calculatedPools,
|
||||
Dictionary<string, Domain.Entities.Commission.WorkerExecutionLog> executionLogs)
|
||||
{
|
||||
var (startDate, endDate) = GetWeekRange(date);
|
||||
var pool = calculatedPools.FirstOrDefault(p => p.WeekNumber == weekNumber);
|
||||
var log = executionLogs.GetValueOrDefault(weekNumber);
|
||||
|
||||
var isCalculated = pool != null && pool.IsCalculated;
|
||||
var displayText = $"{weekNumber} ({startDate:yyyy/MM/dd} - {endDate:yyyy/MM/dd})";
|
||||
|
||||
if (isCalculated)
|
||||
{
|
||||
displayText += " ✅ محاسبه شده";
|
||||
}
|
||||
|
||||
return new WeekInfoDto
|
||||
{
|
||||
WeekNumber = weekNumber,
|
||||
StartDate = startDate,
|
||||
EndDate = endDate,
|
||||
IsCalculated = isCalculated,
|
||||
CalculatedAt = pool?.CalculatedAt,
|
||||
LastExecutionStatus = log?.Status.ToString(),
|
||||
TotalPoolAmount = pool?.TotalPoolAmount,
|
||||
EligibleUsersCount = pool?.UserCommissionPayouts?.Count ?? 0,
|
||||
DisplayText = displayText
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetWeekNumber(DateTime date)
|
||||
{
|
||||
var calendar = CultureInfo.InvariantCulture.Calendar;
|
||||
var weekOfYear = calendar.GetWeekOfYear(
|
||||
date,
|
||||
CalendarWeekRule.FirstFourDayWeek,
|
||||
DayOfWeek.Monday);
|
||||
|
||||
return $"{date.Year}-W{weekOfYear:D2}";
|
||||
}
|
||||
|
||||
private static (DateTime startDate, DateTime endDate) GetWeekRange(DateTime date)
|
||||
{
|
||||
var dayOfWeek = (int)date.DayOfWeek;
|
||||
var daysToMonday = dayOfWeek == 0 ? 6 : dayOfWeek - 1; // اگر یکشنبه باشد، 6 روز عقب برو
|
||||
|
||||
var startDate = date.Date.AddDays(-daysToMonday);
|
||||
var endDate = startDate.AddDays(6);
|
||||
|
||||
return (startDate, endDate);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
namespace CMSMicroservice.Application.CommissionCQ.Queries.GetAvailableWeeks;
|
||||
|
||||
public class GetAvailableWeeksResponseDto
|
||||
{
|
||||
/// <summary>هفته جاری</summary>
|
||||
public required WeekInfoDto CurrentWeek { get; init; }
|
||||
|
||||
/// <summary>هفتههای محاسبه شده (از جدیدترین به قدیمیترین)</summary>
|
||||
public required List<WeekInfoDto> CalculatedWeeks { get; init; }
|
||||
|
||||
/// <summary>هفتههای محاسبه نشده (از جدیدترین به قدیمیترین)</summary>
|
||||
public required List<WeekInfoDto> PendingWeeks { get; init; }
|
||||
|
||||
/// <summary>هفتههای آینده قابل انتخاب</summary>
|
||||
public required List<WeekInfoDto> FutureWeeks { get; init; }
|
||||
}
|
||||
|
||||
public class WeekInfoDto
|
||||
{
|
||||
/// <summary>شماره هفته (YYYY-Www)</summary>
|
||||
public required string WeekNumber { get; init; }
|
||||
|
||||
/// <summary>تاریخ شروع هفته</summary>
|
||||
public required DateTime StartDate { get; init; }
|
||||
|
||||
/// <summary>تاریخ پایان هفته</summary>
|
||||
public required DateTime EndDate { get; init; }
|
||||
|
||||
/// <summary>آیا محاسبه شده؟</summary>
|
||||
public bool IsCalculated { get; init; }
|
||||
|
||||
/// <summary>تاریخ محاسبه (اگر محاسبه شده باشد)</summary>
|
||||
public DateTime? CalculatedAt { get; init; }
|
||||
|
||||
/// <summary>وضعیت اجرای آخرین محاسبه</summary>
|
||||
public string? LastExecutionStatus { get; init; }
|
||||
|
||||
/// <summary>مبلغ کل استخر کمیسیون (اگر محاسبه شده باشد)</summary>
|
||||
public long? TotalPoolAmount { get; init; }
|
||||
|
||||
/// <summary>تعداد کاربران واجد شرایط</summary>
|
||||
public int? EligibleUsersCount { get; init; }
|
||||
|
||||
/// <summary>نمایش فارسی (برای UI)</summary>
|
||||
public required string DisplayText { get; init; }
|
||||
}
|
||||
+1
-1
@@ -19,7 +19,7 @@ public class GetWithdrawalReportsQueryHandler : IRequestHandler<GetWithdrawalRep
|
||||
public async Task<WithdrawalReportsDto> Handle(GetWithdrawalReportsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// تعیین بازه زمانی پیشفرض (30 روز گذشته)
|
||||
var endDate = request.EndDate ?? DateTime.UtcNow;
|
||||
var endDate = request.EndDate ?? DateTime.Now;
|
||||
var startDate = request.StartDate ?? endDate.AddDays(-30);
|
||||
|
||||
// Query پایه
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@ public class GetWorkerStatusQueryHandler : IRequestHandler<GetWorkerStatusQuery,
|
||||
CurrentExecutionId = null,
|
||||
CurrentWeekNumber = null,
|
||||
CurrentStep = "Idle",
|
||||
LastRunAt = DateTime.UtcNow.AddHours(-24),
|
||||
NextScheduledRun = DateTime.UtcNow.AddDays(7),
|
||||
LastRunAt = DateTime.Now.AddHours(-24),
|
||||
NextScheduledRun = DateTime.Now.AddDays(7),
|
||||
TotalExecutions = 48,
|
||||
SuccessfulExecutions = 47,
|
||||
FailedExecutions = 1
|
||||
|
||||
Reference in New Issue
Block a user