feat(dal): NextRunService - получение актуального nextRun для нового или существующего шаблона

This commit is contained in:
Mikhail Trubnikov
2026-01-21 15:36:54 +10:00
parent 5ad26742e6
commit b83438d6ca
3 changed files with 119 additions and 18 deletions

View File

@@ -12,21 +12,29 @@ namespace PARR.DAL.NextRunServices
Task<List<TemplateNextRunResultDto>?> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId); Task<List<TemplateNextRunResultDto>?> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId);
///// <summary>
///// Получить NextRun по jobGroupId с расписанием ЕСПП
///// </summary>
///// <param name="jobGroupId"></param>
///// <returns></returns>
//Task<DateTimeOffset> GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId);
/// <summary> /// <summary>
/// Получить NextRun по jobGroupId с расписанием ЕСПП /// Получить nextRun для создаваемого шаблона, которого еще нет в БД
/// </summary> /// </summary>
/// <param name="jobGroupId"></param> /// <param name="jobGroupId"></param>
/// <returns></returns> /// <returns></returns>
Task<DateTimeOffset> GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId); Task<DateTimeOffset> GetNextRunForNewTemplateAsync(Guid jobGroupId);
/// <summary> /// <summary>
/// Получить NextRun по id шаблона /// Получить NextRun по id существующего шаблона
/// </summary> /// </summary>
/// <param name="templateId"></param> /// <param name="templateId"></param>
/// <param name="isNew">Новый шаблон или шаблон переведенный из unused</param> /// <param name="isNew">Шаблон переведенный из unused</param>
/// <returns></returns> /// <returns></returns>
Task<DateTimeOffset> GetNextRunForTemplate(Guid templateId, bool isNew); Task<DateTimeOffset> GetNextRunForTemplateAsync(Guid templateId, bool isNew);
} }
} }

View File

@@ -1,4 +1,5 @@
 
using InfluxDB.Client.Api.Domain;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using PARR.Constants; using PARR.Constants;
@@ -127,9 +128,30 @@ namespace PARR.DAL.NextRunServices
} }
public async Task<DateTimeOffset> GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId) //public async Task<DateTimeOffset> GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId)
//{
// var jobGroup = await jobGroupService.Get().AsNoTracking().FirstOrDefaultAsync(t => t.Id == jobGroupId);
// if (jobGroup == null)
// {
// logger.LogError("Не найдена группа работ с Id: {jobGroupId}.", jobGroupId);
// throw new ArgumentNullException(nameof(jobGroupId), $"Не найдена группа работ с Id: {jobGroupId}");
// }
// // Берем из обычного расписания ЕСПП
// return await esppScheduleTransformService.GetNextDateAsync(jobGroupId, jobGroup.ReferenceDate);
//}
public async Task<DateTimeOffset> GetNextRunForNewTemplateAsync(Guid jobGroupId)
{ {
var jobGroup = await jobGroupService.Get().AsNoTracking().FirstOrDefaultAsync(t => t.Id == jobGroupId); // определяю это автораспределение или нет, вызываю соответствующий рассчет
var jobGroup = await jobGroupService.Get()
.Include(t => t.DistributionConfig)
.ThenInclude(t => t.DistributionPeriod)
.AsNoTracking()
.FirstOrDefaultAsync(t => t.Id == jobGroupId);
if (jobGroup == null) if (jobGroup == null)
{ {
@@ -137,39 +159,103 @@ namespace PARR.DAL.NextRunServices
throw new ArgumentNullException(nameof(jobGroupId), $"Не найдена группа работ с Id: {jobGroupId}"); throw new ArgumentNullException(nameof(jobGroupId), $"Не найдена группа работ с Id: {jobGroupId}");
} }
// Берем из обычного расписания ЕСПП if (jobGroup.IsAutoDistributionEnabled)
return await esppScheduleTransformService.GetNextDateAsync(jobGroupId, jobGroup.ReferenceDate); {
// тут автораспределение
if (jobGroup.DistributionConfig == null)
{
logger.LogError("Для группы работ {jobGroupId}, указано автораспределение, но отсутствует конфиг в таблице {GroupDistributionConfigs}", jobGroupId, nameof(JobGroupDistributionConfig));
throw new ArgumentNullException(nameof(JobGroupDistributionConfig), $"Для jobGroupId: {jobGroupId} отсутствует конфигурация автораспределения в таблице {nameof(JobGroupDistributionConfig)}");
}
#region Вынести в одтельный метод, почти все повторяется
var dateStart = GetDateStart(jobGroup.ReferenceDate);
var duration = GetDurationDays(jobGroup.DistributionConfig);
var result = await templateDistributor.GetValidNextRunForTemplateAsync(dateStart,
duration,
jobGroup.ReferenceDate,
new TemplateNextRunDto(Guid.Empty, null),
//TODO: тут пока не получаем список шаблонов, но позже, когда будем строить каждый раз план, нужно будет сюда передавать список связанных шаблонов
new List<TemplateNextRunDto>(),
jobGroup.DistributionConfig.IsExcludeWeekends,
isNew: true
);
#endregion
logger.LogDebug("Получил nextRun {nextRun} по jobGroupId {jobGroupId} для нового шаблона, тип расписания: автораспределение", result.NextRun, jobGroupId);
return result.NextRun;
}
else
{
// тут расписание ЕСПП
var nextRun = await esppScheduleTransformService.GetNextDateAsync(jobGroup.Id, jobGroup.ReferenceDate);
logger.LogDebug("Получил nextRun {nextRun} по jobGroupId {jobGroupId}, тип расписания ЕСПП", nextRun, jobGroupId);
return nextRun;
}
} }
public async Task<DateTimeOffset> GetNextRunForTemplate(Guid templateId, bool isNew) public async Task<DateTimeOffset> GetNextRunForTemplateAsync(Guid templateId, bool isNew)
{ {
var template = await templateService.Get() var template = await templateService.Get()
.Include(t => t.Job).ThenInclude(t => t.Group) .Include(t => t.Job)
.ThenInclude(t => t.Group).ThenInclude(t => t.DistributionConfig).ThenInclude(t => t.DistributionPeriod)
.AsNoTracking() .AsNoTracking()
.FirstOrDefaultAsync(t => t.Id == templateId); .FirstOrDefaultAsync(t => t.Id == templateId);
if (template == null) if (template == null)
{ {
logger.LogError("Не найдена шаблон с Id: {templateId}.", templateId); logger.LogError("Не найден шаблон с Id: {templateId}.", templateId);
throw new ArgumentNullException(nameof(templateId), $"Не найдена шаблон с Id: {templateId}"); throw new ArgumentNullException(nameof(templateId), $"Не найден шаблон с Id: {templateId}");
} }
if (template.Job!.Group!.IsAutoDistributionEnabled == true) if (template.Job!.Group!.IsAutoDistributionEnabled == true)
{ {
// включено автораспределение // включено автораспределение
//TODO: !!!!!!!!!!!!!!!! добавить метод рассчета с учетом распределения if (template.Job!.Group.DistributionConfig == null)
throw new NotImplementedException(); {
//return await templateDistributor.GetValidNextRunForTemplateAsync(); logger.LogError("Для шаблона {templateId}, jobGroupId {jobGroupId}, указано автораспределение, но отсутствует конфиг в таблице {GroupDistributionConfigs}", template.Id, template.Job.GroupId, nameof(JobGroupDistributionConfig));
throw new ArgumentNullException(nameof(JobGroupDistributionConfig), $"Для jobGroupId: {template.Job.GroupId} отсутствует конфигурация автораспределения в таблице {nameof(JobGroupDistributionConfig)}");
}
#region Вынести в одтельный метод, почти все повторяется
var dateStart = GetDateStart(template.Job!.Group.ReferenceDate);
var duration = GetDurationDays(template.Job!.Group.DistributionConfig);
var result = await templateDistributor.GetValidNextRunForTemplateAsync(dateStart,
duration,
template.Job.Group.ReferenceDate,
new TemplateNextRunDto(template.Id, template.NextRun),
//TODO: тут пока не получаем список шаблонов, но позже, когда будем строить каждый раз план, нужно будет сюда передавать список связанных шаблонов
new List<TemplateNextRunDto>(),
template.Job.Group.DistributionConfig.IsExcludeWeekends,
isNew
);
#endregion
logger.LogDebug("Получил nextRun {nextRun} по templateId {templateId}, isNew: {isNew}, тип расписания: автораспределение", result.NextRun, templateId, isNew);
return result.NextRun;
} }
else else
{ {
// считаем как ЕСПП // считаем как ЕСПП
return await esppScheduleTransformService.GetNextDateAsync(template.Job.Group.Id, template.Job.Group.ReferenceDate); var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job.Group.Id, template.Job.Group.ReferenceDate);
logger.LogDebug("Получил nextRun {nextRun} по templateId {templateId}, isNew: {isNew}, тип расписания: ЕСПП", nextRun, templateId, isNew);
return nextRun;
} }
} }
/// <summary> /// <summary>
/// Получить продолжительность в днях /// Получить продолжительность в днях
/// </summary> /// </summary>

View File

@@ -23,7 +23,14 @@ namespace PARR.Test.NextRun
//await DistributeTemplatesAsync(); //await DistributeTemplatesAsync();
//await GetValidNextRunForTemplateAsync(); //await GetValidNextRunForTemplateAsync();
var result = await nextRunService.GetNextRunForJobGroupWithAutoDistributionAsync(Guid.Parse("eadc5498-dba6-4f10-9b4b-a1653e3c3e61")); // распределить шаблоны (не сохраняя в БД)
//var result = await nextRunService.GetNextRunForJobGroupWithAutoDistributionAsync(Guid.Parse("eadc5498-dba6-4f10-9b4b-a1653e3c3e61"));
// получить nextRun для еще не созданного шаблона
//var nextRunForNullTemplate = await nextRunService.GetNextRunForNewTemplateAsync(Guid.Parse("eadc5498-dba6-4f10-9b4b-a1653e3c3e61"));
// получить nextRun для существующего шаблона
// var nextRunForExistTemplate = await nextRunService.GetNextRunForTemplateAsync(Guid.Parse("20fc3581-984e-4c9a-8b46-8a55c3401725"), false);
} }