131 lines
4.9 KiB
C#
131 lines
4.9 KiB
C#
using Microsoft.Extensions.Logging;
|
||
using PARR.BLL.Services.Interfaces;
|
||
using PARR.Common;
|
||
using PARR.Constants;
|
||
|
||
namespace PARR.BLL.Services.Implementations
|
||
{
|
||
internal class CalendarService : ICalendarService
|
||
{
|
||
private readonly ILogger<CalendarService> logger;
|
||
|
||
public CalendarService(ILogger<CalendarService> logger)
|
||
{
|
||
this.logger = logger;
|
||
}
|
||
|
||
|
||
public DateOnly GetEndPeriodDate(DateOnly startPeriod, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
||
{
|
||
switch (periodType)
|
||
{
|
||
case (DistributionPeriodTypeEnum.Day):
|
||
return startPeriod.AddDays(ParseInt(distributionPeriod)).AddDays(-1);
|
||
|
||
case (DistributionPeriodTypeEnum.Month):
|
||
return startPeriod.AddMonths(ParseInt(distributionPeriod)).AddDays(-1);
|
||
|
||
case (DistributionPeriodTypeEnum.Year):
|
||
return startPeriod.AddYears(ParseInt(distributionPeriod)).AddDays(-1);
|
||
|
||
}
|
||
|
||
return startPeriod;
|
||
}
|
||
|
||
|
||
private int ParseInt(string value)
|
||
{
|
||
try
|
||
{
|
||
return int.Parse(value);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.LogError(ex, $"{nameof(CalendarService)}, получение конца периода. Не смог распарсить string в int для значения {value}.");
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// Возвращает список рабочих дней с начала периода без выходных
|
||
/// </summary>
|
||
/// <param name="startPeriod"></param>
|
||
/// <param name="refTime"></param>
|
||
/// <param name="periodType"></param>
|
||
/// <param name="distributionPeriod"></param>
|
||
/// <param name="getWeekends"></param>
|
||
/// <returns></returns>
|
||
public List<DateOnly> GetWorkDatesForPeriod(DateOnly startPeriod, TimeOnly refTime, DistributionPeriodTypeEnum periodType, string distributionPeriod, GetWeekendsDelegate getWeekends)
|
||
{
|
||
var endPeriod = GetEndPeriodDate(startPeriod, periodType, distributionPeriod);
|
||
|
||
//не получилось сделать асинхронным
|
||
var weekends = getWeekends.Invoke(startPeriod, endPeriod).ToList(); //.ToListAsync();
|
||
|
||
//Берем список дат за период
|
||
var workDays = GetDatesForPeriod(startPeriod, endPeriod);
|
||
|
||
//Убираем праздники
|
||
if (weekends.Any())
|
||
workDays = workDays.Where(t => !weekends.Any(x => x == t)).ToList();
|
||
|
||
//РАСКОММЕНТИРОВАТЬ НИЖЕ (28 дней), если не использовать календарь выходных дней
|
||
////Убираем числа старше 28, чтобы сравнять продолжительность с февралем
|
||
//workDays.RemoveAll(t => t.Day > 28);
|
||
|
||
//Так как в базе всё храним в UTC то время с 21 часа уже соответствует следующими суткам в календаре Москвы
|
||
//просто сдвигаем на день весь список
|
||
//if (refTime.Hour > 21)
|
||
if (DateResolver.IsCurrentDayRelativeMskTime(refTime.Hour) == false)
|
||
return workDays.Select(wd => wd.AddDays(-1)).ToList();
|
||
|
||
//иначе просто отдаём как есть
|
||
return workDays;
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// Возвращает список дней между датами
|
||
/// </summary>
|
||
/// <param name="startPeriod"></param>
|
||
/// <param name="endPeriod"></param>
|
||
/// <returns></returns>
|
||
public List<DateOnly> GetDatesForPeriod(DateOnly startPeriod, DateOnly endPeriod)
|
||
{
|
||
var workDaysList = new List<DateOnly>();
|
||
|
||
var currentDay = startPeriod;
|
||
|
||
while (currentDay <= endPeriod)
|
||
{
|
||
workDaysList.Add(currentDay);
|
||
currentDay = currentDay.AddDays(1);
|
||
}
|
||
|
||
return workDaysList.OrderBy(t => t).ToList();
|
||
}
|
||
|
||
/// <summary>
|
||
/// Возвращает список дней между датами
|
||
/// </summary>
|
||
/// <param name="startPeriod"></param>
|
||
/// <param name="endPeriod"></param>
|
||
/// <returns></returns>
|
||
public List<DateOnly> GetDatesForPeriod(DateTimeOffset startPeriod, DateTimeOffset endPeriod)
|
||
{
|
||
return GetDatesForPeriod(DateOnly.FromDateTime(startPeriod.DateTime), DateOnly.FromDateTime(endPeriod.DateTime));
|
||
}
|
||
|
||
|
||
public DateTimeOffset GetDateWithTimeZoneOffset(DateTimeOffset date, int timeZoneOffsetHours)
|
||
{
|
||
return date.AddHours(timeZoneOffsetHours);
|
||
}
|
||
|
||
}
|
||
}
|