feat(dal): template distributor - логика получения NextRun. Рефакторинг
This commit is contained in:
@@ -25,60 +25,100 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
}
|
||||
|
||||
|
||||
public Task<TemplateNextRunResultDto> GetValidNextRunForTemplateAsync(DateOnly startDate, int duration, DateTimeOffset referenceDate, TemplateNextRunDto targetTemplate, List<TemplateNextRunDto> allTemplates, bool excludeWeekends)
|
||||
public async Task<TemplateNextRunResultDto> GetValidNextRunForTemplateAsync(DateOnly startDate, int duration, DateTimeOffset referenceDate, TemplateNextRunDto targetTemplate, List<TemplateNextRunDto> allTemplates, bool excludeWeekends, bool isNew)
|
||||
{
|
||||
//TODO:
|
||||
throw new NotImplementedException();
|
||||
//todo: allTemplates - пока не используется. Будет использоваться когда каждый раз будем строить план
|
||||
|
||||
// Пока работает так:
|
||||
// Получаем список рабочих дней, если работа попадает в эти дни, то считаем дату валидной
|
||||
// Если нет, то перемещаем на последний день периода распределения или первый в зависимости от параметра isNew
|
||||
|
||||
var _startDate = GetStartPeriodDate(startDate, referenceDate);
|
||||
var _endDate = GetEndPeriodDate(_startDate, duration);
|
||||
|
||||
logger.LogDebug("Получаю актуальный nextRun для шаблона {templateId}. Текущий nextRun: {nextRun}. Период {duration} дней, с {_startDate} по {_endDate}. Исключить выходные и праздники: {excludeWeekends}. Для нового шаблона: {isNew}", targetTemplate.Id, targetTemplate.NextRun, duration, _startDate, _endDate, excludeWeekends, isNew);
|
||||
|
||||
// Получаем список рабочих дней (исключая выходные и праздники)
|
||||
var workDays = await GetWorkDaysAsync(_startDate, _endDate, excludeWeekends);
|
||||
|
||||
if (workDays.Count == 0)
|
||||
{
|
||||
logger.LogWarning("Нет доступных рабочих дней в диапазоне {_startDate} - {_endDate}. Возвращаем шаблон со смещением: {offsetYearsIfErrorCalcNextRun} лет.", _startDate, _endDate, offsetYearsIfErrorCalcNextRun);
|
||||
|
||||
// смещаем nextRun вперед
|
||||
var result = FillTemplateResultWithOffsetError(targetTemplate, _startDate, referenceDate);
|
||||
|
||||
logger.LogInformation("Получение актуального NextRun завершено, templateId: {templateId}. NextRun {nextRun}. OldNextRun у {oldNextRun} шт.", result.Id, result.NextRun, result.NextRunOld);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// если isNew, то берем первый день периода
|
||||
if (isNew)
|
||||
{
|
||||
var result = new TemplateNextRunResultDto
|
||||
(
|
||||
Id: targetTemplate.Id,
|
||||
NextRun: FindNextAvailableDateIgnoreLoad(workDays, referenceDate, true), //CreateDateTimeOffset(workDays.First(), referenceDate),
|
||||
NextRunOld: targetTemplate.NextRun
|
||||
);
|
||||
|
||||
logger.LogInformation("Получение актуального NextRun завершено, templateId: {templateId}. Это было создание нового, поместили его в начало периода. NextRun {nextRun}. OldNextRun у {oldNextRun} шт.", result.Id, result.NextRun, result.NextRunOld);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// есть ли NextRun и попадает ли он на рабочий день
|
||||
// проверяем чтоб было не меньше чем UtcNow
|
||||
//TODO: тут еще сделать проверку нагрузки на день
|
||||
if (targetTemplate.NextRun.HasValue && workDays.Contains(DateOnly.FromDateTime(targetTemplate.NextRun.Value.Date)) && targetTemplate.NextRun.Value > DateTimeOffset.UtcNow)
|
||||
{
|
||||
var result = new TemplateNextRunResultDto
|
||||
(
|
||||
Id: targetTemplate.Id,
|
||||
NextRun: CreateDateTimeOffset(targetTemplate.NextRun.Value, referenceDate),
|
||||
NextRunOld: targetTemplate.NextRun
|
||||
);
|
||||
|
||||
logger.LogInformation("Получение актуального NextRun завершено, templateId: {templateId}. NextRun актуальный, возвращаем его. NextRun {nextRun}. OldNextRun у {oldNextRun} шт.", result.Id, result.NextRun, result.NextRunOld);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//TODO: Временный костыль, перемещаем на конец периода
|
||||
|
||||
var endPeriodResult = new TemplateNextRunResultDto
|
||||
(
|
||||
Id: targetTemplate.Id,
|
||||
NextRun: FindNextAvailableDateIgnoreLoad(workDays, referenceDate, false),
|
||||
NextRunOld: targetTemplate.NextRun
|
||||
);
|
||||
|
||||
logger.LogInformation("Получение актуального NextRun завершено, templateId: {templateId}. NextRun перемещен на конец периода. NextRun {nextRun}. OldNextRun у {oldNextRun} шт.", endPeriodResult.Id, endPeriodResult.NextRun, endPeriodResult.NextRunOld);
|
||||
|
||||
return endPeriodResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task<List<TemplateNextRunResultDto>> DistributeTemplatesAsync(DateOnly startDate, int duration, DateTimeOffset referenceDate, List<TemplateNextRunDto> allTemplates, bool excludeWeekends)
|
||||
{
|
||||
var _startDate = GetStartPeriodDate(startDate, referenceDate);
|
||||
var _endDate = GetEndPeriodDate(_startDate, duration);
|
||||
|
||||
logger.LogInformation("Начинаем распределение {Count} шаблонов на {duration} дней, с {_startDate} по {_endDate}. ReferenceDate: {referenceDate}", allTemplates.Count, duration, _startDate, _endDate, referenceDate);
|
||||
|
||||
// Получаем список выходных/праздничных дней
|
||||
var weekends = new HashSet<DateOnly>();
|
||||
if (excludeWeekends)
|
||||
{
|
||||
weekends = await GetWeekendsAsync(_startDate, _endDate);
|
||||
logger.LogDebug("Найдено не рабочих дней: {Count}", weekends.Count);
|
||||
|
||||
foreach (var weekend in weekends)
|
||||
logger.LogDebug("Не рабочий день: {weekend}", weekend);
|
||||
}
|
||||
logger.LogInformation("Начинаем распределение {Count} шаблонов на {duration} дней, с {_startDate} по {_endDate}. ReferenceDate: {referenceDate}. Исключить выходные и праздники: {excludeWeekends}.", allTemplates.Count, duration, _startDate, _endDate, referenceDate, excludeWeekends);
|
||||
|
||||
// Получаем список рабочих дней (исключая выходные и праздники)
|
||||
var workDays = GetWorkDays(_startDate, _endDate, weekends);
|
||||
|
||||
logger.LogDebug("Найдено рабочих дней: {Count}", workDays.Count);
|
||||
|
||||
foreach (var workDay in workDays)
|
||||
logger.LogDebug("Рабочий день: {workDay}", workDay);
|
||||
var workDays = await GetWorkDaysAsync(_startDate, _endDate, excludeWeekends);
|
||||
|
||||
if (workDays.Count == 0)
|
||||
{
|
||||
logger.LogWarning("Нет доступных рабочих дней в диапазоне {_startDate} - {_endDate}. Возвращаем список шаблонов со смещением: {offsetYearsIfErrorCalcNextRun} лет.", _startDate, _endDate, offsetYearsIfErrorCalcNextRun);
|
||||
|
||||
// смещаем все nextRun вперед
|
||||
var result = allTemplates.Select(t => new TemplateNextRunResultDto
|
||||
{
|
||||
Id = t.Id,
|
||||
NextRun = t.NextRun.HasValue
|
||||
// если есть nextRun, то прибавляем к нему offsetYearsIfErrorCalcNextRun
|
||||
? CreateNextRun(t.NextRun.Value.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate)
|
||||
// если нет nextRun, берем сегодня и прибавляем offsetYearsIfErrorCalcNextRun
|
||||
: CreateNextRun(DateTimeOffset.UtcNow.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate),
|
||||
NextRunOld = t.NextRun
|
||||
}).OrderBy(t => t.NextRun).ToList();
|
||||
|
||||
foreach (var item in result)
|
||||
logger.LogDebug("Нет рабочих дней, сдвинул nextRun у шаблона {Id}, nextRun: {NextRun}, nextRunOld: {NextRunOld}", item.Id, item.NextRun, item.NextRunOld);
|
||||
var result = allTemplates.Select(t =>
|
||||
FillTemplateResultWithOffsetError(t, _startDate, referenceDate)
|
||||
).OrderBy(t => t.NextRun).ToList();
|
||||
|
||||
logger.LogInformation("Распределение завершено. Возвращаем {Count} записей. NextRun не изменился у {oldCount} шт. Обновлен NextRun у {changedCount} шт.", result.Count, result.Count(t => t.NextRun == t.NextRunOld), result.Count(t => t.NextRun != t.NextRunOld));
|
||||
|
||||
@@ -86,13 +126,12 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
}
|
||||
|
||||
var totalWorks = allTemplates.Count;
|
||||
var totalDays = workDays.Count;
|
||||
|
||||
// интервал между шаблонами
|
||||
var interval = GetInterval(totalDays, totalWorks);
|
||||
var interval = GetInterval(workDays.Count, totalWorks);
|
||||
|
||||
// строим план, дни на которые должны быть назанчены шаблоны
|
||||
var plan = GetPlan(totalWorks, totalDays, workDays);
|
||||
var plan = GetPlan(totalWorks, workDays);
|
||||
|
||||
|
||||
// Подсчитываем, сколько работ должно быть на каждый день
|
||||
@@ -168,11 +207,11 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
foreach (var template in templates)
|
||||
{
|
||||
templatesToKeep.Add(new TemplateNextRunResultDto
|
||||
{
|
||||
Id = template.Id,
|
||||
NextRun = template.NextRun.Value,
|
||||
NextRunOld = template.NextRun
|
||||
});
|
||||
(
|
||||
Id: template.Id,
|
||||
NextRun: template.NextRun.Value,
|
||||
NextRunOld: template.NextRun
|
||||
));
|
||||
logger.LogDebug("Шаблон {TemplateId} оставлен на дату {NextRun}, т.к. нагрузка в день не превышена.", template.Id, template.NextRun);
|
||||
}
|
||||
}
|
||||
@@ -183,11 +222,11 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
{
|
||||
var template = templates[i];
|
||||
templatesToKeep.Add(new TemplateNextRunResultDto
|
||||
{
|
||||
Id = template.Id,
|
||||
NextRun = template.NextRun.Value,
|
||||
NextRunOld = template.NextRun
|
||||
});
|
||||
(
|
||||
Id: template.Id,
|
||||
NextRun: template.NextRun.Value,
|
||||
NextRunOld: template.NextRun
|
||||
));
|
||||
logger.LogDebug("Шаблон {TemplateId} оставлен на дату {NextRun}, т.к. нагрузка в день не превышена.", template.Id, template.NextRun);
|
||||
}
|
||||
|
||||
@@ -228,11 +267,11 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
currentDailyLoad[day]++;
|
||||
|
||||
updatedTemplates.Add(new TemplateNextRunResultDto
|
||||
{
|
||||
Id = template.Id,
|
||||
NextRun = nextRun.Value,
|
||||
NextRunOld = template.NextRun
|
||||
});
|
||||
(
|
||||
Id: template.Id,
|
||||
NextRun: nextRun.Value,
|
||||
NextRunOld: template.NextRun
|
||||
));
|
||||
|
||||
logger.LogDebug("Шаблону {TemplateId} назначен NextRun: {NextRun}, NextRunOld: {NextRunOld}", template.Id, nextRun, template.NextRun);
|
||||
}
|
||||
@@ -242,11 +281,11 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
|
||||
// Возвращаем с ошибкой
|
||||
updatedTemplates.Add(new TemplateNextRunResultDto
|
||||
{
|
||||
Id = template.Id,
|
||||
NextRun = CreateNextRun(DateTimeOffset.UtcNow.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate),
|
||||
NextRunOld = template.NextRun
|
||||
});
|
||||
(
|
||||
Id: template.Id,
|
||||
NextRun: CreateDateTimeOffset(DateTimeOffset.UtcNow.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate),
|
||||
NextRunOld: template.NextRun
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +294,7 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
|
||||
updatedTemplates = updatedTemplates.OrderBy(t => t.NextRun).ToList();
|
||||
|
||||
logger.LogDebug("--- Результат распределения: ---");
|
||||
logger.LogDebug("--- Результат распределения ---");
|
||||
foreach (var item in updatedTemplates)
|
||||
logger.LogDebug("Шаблон {templateId}, NextRun: {NextRun}, NextRunOld: {NextRunOld}", item.Id, item.NextRun, item.NextRunOld);
|
||||
|
||||
@@ -265,6 +304,77 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Заполнить TemplateNextRunResultDto, если нет рабочих дней со смещением
|
||||
/// </summary>
|
||||
/// <param name="template"></param>
|
||||
/// <returns></returns>
|
||||
private TemplateNextRunResultDto FillTemplateResultWithOffsetError(TemplateNextRunDto template, DateOnly startDate, DateTimeOffset referenceDate)
|
||||
{
|
||||
var result = new TemplateNextRunResultDto
|
||||
(
|
||||
Id: template.Id,
|
||||
//NextRun = template.NextRun.HasValue
|
||||
// // если есть nextRun, то прибавляем к нему offsetYearsIfErrorCalcNextRun
|
||||
// ? CreateNextRun(template.NextRun.Value.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate)
|
||||
// // если нет nextRun, берем сегодня и прибавляем offsetYearsIfErrorCalcNextRun
|
||||
// : CreateNextRun(DateTimeOffset.UtcNow.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate),
|
||||
NextRun: CreateDateTimeOffset(startDate.AddYears(offsetYearsIfErrorCalcNextRun), referenceDate),
|
||||
NextRunOld: template.NextRun
|
||||
);
|
||||
|
||||
logger.LogDebug("Нет рабочих дней, сдвинул nextRun у шаблона {Id} на {offsetYearsIfErrorCalcNextRun} лет вперед, nextRun: {NextRun}, nextRunOld: {NextRunOld}", result.Id, offsetYearsIfErrorCalcNextRun, result.NextRun, result.NextRunOld);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Получает NextRun не учитывая нагрузку на день
|
||||
/// </summary>
|
||||
/// <param name="workDays"></param>
|
||||
/// <param name="referenseDate"></param>
|
||||
/// <param name="isSearchFirst">Искать с начала = true, false - искать с конца</param>
|
||||
/// <returns></returns>
|
||||
private DateTimeOffset FindNextAvailableDateIgnoreLoad(List<DateOnly> workDays, DateTimeOffset referenseDate, bool isSearchFirst)
|
||||
{
|
||||
// возможно это временная реализация метода, используется для GetValidNextRunForTemplateAsync
|
||||
|
||||
if (!isSearchFirst)
|
||||
{
|
||||
// берем первый рабочий день с конца и возвращаем его
|
||||
var lastDate = CreateDateTimeOffset(workDays.Last(), referenseDate);
|
||||
logger.LogDebug("Берем первый рабочий день с конца. Сгенерированный NextRun: {lastDate}", lastDate);
|
||||
return lastDate;
|
||||
}
|
||||
|
||||
// будем искать сначала
|
||||
// берем первый день, и смотрим не прошло ли уже время
|
||||
var firstDate = CreateDateTimeOffset(workDays.First(), referenseDate);
|
||||
if (firstDate > DateTimeOffset.UtcNow)
|
||||
{
|
||||
logger.LogDebug("Берем первый день с начала. Сгенерированный NextRun: {firstDate}", firstDate);
|
||||
return firstDate;
|
||||
}
|
||||
|
||||
|
||||
// тогда берем второй день
|
||||
if (workDays.Count > 1)
|
||||
{
|
||||
var secondDate = CreateDateTimeOffset(workDays.ElementAt(1), referenseDate);
|
||||
logger.LogDebug("Берем второй день сначала, так как у первого дня уже время прошло. Сгенерированный NextRun: {secondDate}", secondDate);
|
||||
return secondDate;
|
||||
}
|
||||
|
||||
logger.LogWarning("Вернули nextRun: {firstDate} из первого дня распределения, хотя время уже просрочено. Всего рабочих дней: {workDays}", firstDate, workDays.Count);
|
||||
// если вдруг список рабочих дней был не >1, то тогда берем первый и вренем его. Так никогда не должно быть
|
||||
return firstDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Находит следующий день с доступной нагрузкой, учитывая expectedDailyLoad
|
||||
/// </summary>
|
||||
@@ -282,7 +392,7 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
|
||||
if (current < expected)
|
||||
{
|
||||
return CreateNextRun(day, referenceDate);
|
||||
return CreateDateTimeOffset(day, referenceDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +404,7 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
|
||||
if (current < expected)
|
||||
{
|
||||
return CreateNextRun(day, referenceDate);
|
||||
return CreateDateTimeOffset(day, referenceDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +412,7 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
var minLoad = currentDailyLoad.Values.Min();
|
||||
var minDay = currentDailyLoad.First(x => x.Value == minLoad).Key;
|
||||
|
||||
return CreateNextRun(minDay, referenceDate);
|
||||
return CreateDateTimeOffset(minDay, referenceDate);
|
||||
}
|
||||
|
||||
|
||||
@@ -311,11 +421,12 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
/// Получить план: дни, на которые должны быть назначены шаблоны
|
||||
/// </summary>
|
||||
/// <param name="totalWorks"></param>
|
||||
/// <param name="totalDays"></param>
|
||||
/// <param name="workDays"></param>
|
||||
/// <returns></returns>
|
||||
private List<DateOnly> GetPlan(int totalWorks, int totalDays, List<DateOnly> workDays)
|
||||
private List<DateOnly> GetPlan(int totalWorks, List<DateOnly> workDays)
|
||||
{
|
||||
var totalDays = workDays.Count();
|
||||
|
||||
var interval = GetInterval(totalDays, totalWorks);
|
||||
|
||||
var plan = new List<DateOnly>();
|
||||
@@ -336,8 +447,11 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
plan.Add(date);
|
||||
}
|
||||
|
||||
logger.LogDebug("--- План распределения ---");
|
||||
foreach (var item in plan.GroupBy(t => t))
|
||||
logger.LogDebug("Дата: {date}, кол-во работ: {workCount}", item.Key, item.Count());
|
||||
|
||||
return plan;
|
||||
// return new HashSet<DateOnly>(plan);
|
||||
}
|
||||
|
||||
|
||||
@@ -356,23 +470,23 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Создать NextRun (из DateTimeOffset + refDate)
|
||||
/// Создать DateTimeOffset (из DateTimeOffset + refDate)
|
||||
/// </summary>
|
||||
/// <param name="date">Откуда взять дату</param>
|
||||
/// <param name="refDate">Откуда взять время</param>
|
||||
/// <returns></returns>
|
||||
private DateTimeOffset CreateNextRun(DateTimeOffset date, DateTimeOffset refDate)
|
||||
private DateTimeOffset CreateDateTimeOffset(DateTimeOffset date, DateTimeOffset refDate)
|
||||
{
|
||||
return CreateNextRun(DateOnly.FromDateTime(date.Date), refDate);
|
||||
return CreateDateTimeOffset(DateOnly.FromDateTime(date.Date), refDate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создать NextRun (из DateOnly + refDate)
|
||||
/// Создать DateTimeOffset (из DateOnly + refDate)
|
||||
/// </summary>
|
||||
/// <param name="date"></param>
|
||||
/// <param name="refDate"></param>
|
||||
/// <returns></returns>
|
||||
private DateTimeOffset CreateNextRun(DateOnly date, DateTimeOffset refDate)
|
||||
private DateTimeOffset CreateDateTimeOffset(DateOnly date, DateTimeOffset refDate)
|
||||
{
|
||||
return new DateTimeOffset(date.Year, date.Month, date.Day, refDate.Hour, refDate.Minute, refDate.Second, TimeSpan.Zero);
|
||||
}
|
||||
@@ -395,10 +509,15 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
if (dateStart < DateOnly.FromDateTime(referenceDate.Date))
|
||||
dateStart = DateOnly.FromDateTime(referenceDate.Date);
|
||||
|
||||
// если dateStart < чем текущая дата, то берем ьекущую дату
|
||||
// если dateStart < чем текущая дата, то берем текущую дату
|
||||
if (dateStart < DateOnly.FromDateTime(DateTime.UtcNow.Date))
|
||||
dateStart = DateOnly.FromDateTime(DateTime.UtcNow.Date);
|
||||
|
||||
// если текущее время > referenceDate, то прибавляем 1 день
|
||||
var dateTimeStart = CreateDateTimeOffset(dateStart, referenceDate);
|
||||
if (dateTimeStart < DateTimeOffset.UtcNow)
|
||||
dateStart = dateStart.AddDays(1);
|
||||
|
||||
return dateStart;
|
||||
}
|
||||
|
||||
@@ -428,6 +547,10 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
{
|
||||
var weekends = await weekendDayService.GetWeekends(startDate, endDate).ToListAsync();
|
||||
|
||||
logger.LogDebug("Найдено не рабочих дней: {Count}", weekends.Count);
|
||||
foreach (var weekend in weekends)
|
||||
logger.LogDebug("Не рабочий день: {weekend}", weekend);
|
||||
|
||||
return weekends.ToHashSet();
|
||||
}
|
||||
|
||||
@@ -437,10 +560,15 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="weekends"></param>
|
||||
/// <param name="excludeWeekends">Исключить выходные и праздники</param>
|
||||
/// <returns></returns>
|
||||
private List<DateOnly> GetWorkDays(DateOnly start, DateOnly end, HashSet<DateOnly> weekends)
|
||||
private async Task<List<DateOnly>> GetWorkDaysAsync(DateOnly start, DateOnly end, bool excludeWeekends)
|
||||
{
|
||||
// Получаем список выходных/праздничных дней
|
||||
var weekends = new HashSet<DateOnly>();
|
||||
if (excludeWeekends)
|
||||
weekends = await GetWeekendsAsync(start, end);
|
||||
|
||||
var result = new List<DateOnly>();
|
||||
var date = start;
|
||||
|
||||
@@ -454,6 +582,10 @@ namespace PARR.DAL.NextRunServices.Subservices
|
||||
date = date.AddDays(1);
|
||||
}
|
||||
|
||||
logger.LogDebug("Найдено рабочих дней: {Count}", result.Count);
|
||||
foreach (var workDay in result)
|
||||
logger.LogDebug("Рабочий день: {workDay}", workDay);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user