133 lines
5.0 KiB
C#
133 lines
5.0 KiB
C#
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);
|
|
}
|
|
}
|