All checks were successful
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 2m2s
156 lines
6.1 KiB
C#
156 lines
6.1 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 year = date.Year;
|
|
|
|
// پیدا کردن اولین شنبه سال
|
|
var jan1 = new DateTime(year, 1, 1);
|
|
var jan1DayOfWeek = (int)jan1.DayOfWeek; // 0=Sunday, 1=Monday, ..., 6=Saturday
|
|
|
|
// محاسبه تعداد روزهایی که باید اضافه کنیم تا به اولین شنبه برسیم
|
|
var daysToFirstSaturday = jan1DayOfWeek == 6 ? 0 : (6 - jan1DayOfWeek + 7) % 7;
|
|
var firstSaturday = jan1.AddDays(daysToFirstSaturday);
|
|
|
|
// پیدا کردن شنبه شروع هفته جاری
|
|
var currentDayOfWeek = (int)date.DayOfWeek; // 0=Sun, 1=Mon, ..., 6=Sat
|
|
var daysToCurrentSaturday = currentDayOfWeek == 6 ? 0 : (currentDayOfWeek + 1) % 7;
|
|
var weekStartSaturday = date.Date.AddDays(-daysToCurrentSaturday);
|
|
|
|
// محاسبه شماره هفته
|
|
int weekNum;
|
|
if (weekStartSaturday < firstSaturday)
|
|
{
|
|
weekNum = 1; // هفته اول سال
|
|
}
|
|
else
|
|
{
|
|
var daysSinceFirstSaturday = (weekStartSaturday - firstSaturday).Days;
|
|
weekNum = (daysSinceFirstSaturday / 7) + 1;
|
|
}
|
|
|
|
return $"{year}-W{weekNum:D2}";
|
|
}
|
|
|
|
private static (DateTime startDate, DateTime endDate) GetWeekRange(DateTime date)
|
|
{
|
|
var dayOfWeek = (int)date.DayOfWeek;
|
|
// محاسبه تعداد روزهایی که باید عقب برویم تا به شنبه برسیم
|
|
// شنبه = 6, یکشنبه = 0, دوشنبه = 1, ..., جمعه = 5
|
|
var daysToSaturday = dayOfWeek == 6 ? 0 : (dayOfWeek + 1) % 7;
|
|
|
|
var startDate = date.Date.AddDays(-daysToSaturday);
|
|
var endDate = startDate.AddDays(6).AddHours(23).AddMinutes(59).AddSeconds(59);
|
|
|
|
return (startDate, endDate);
|
|
}
|
|
}
|