feat(dal, TemplateDistributorWorker): NextRunServiceV2 - реализован метод распределения шаблонов. Обновлен TemplateDistributorWorker для использования новой логики.

This commit is contained in:
Mikhail Trubnikov
2026-02-13 15:39:21 +10:00
parent 858dd8c31c
commit 89b6cdf731
7 changed files with 234 additions and 46 deletions

View File

@@ -1,4 +1,5 @@
using PARR.DAL.NextRunServices.Models; using PARR.Constants;
using PARR.DAL.NextRunServices.Models;
namespace PARR.DAL.NextRunServices namespace PARR.DAL.NextRunServices
{ {
@@ -7,8 +8,9 @@ namespace PARR.DAL.NextRunServices
/// <summary> /// <summary>
/// Распределить шаблоны в группе работ (получить список распределенных шаблонов с актуальными nextRun) /// Распределить шаблоны в группе работ (получить список распределенных шаблонов с актуальными nextRun)
/// </summary> /// </summary>
/// <param name="jobGroupId"></param> /// <param name="jobGroupId">ИД группы работ</param>
/// <param name="templateStatusType">Статус шаблона, если не передать, берутся все шаблоны группы</param>
/// <returns>Список TemplateId с NextRun и NextRunOld</returns> /// <returns>Список TemplateId с NextRun и NextRunOld</returns>
Task<List<TemplateNextRunResultDto>?> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId); Task<List<TemplateNextRunResultDto>?> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId, TemplateStatusTypeEnum? templateStatusType);
} }
} }

View File

@@ -1,7 +1,5 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NodaTime;
using PARR.Constants; using PARR.Constants;
using PARR.DAL.Contracts; using PARR.DAL.Contracts;
using PARR.DAL.DomainServices.Shortcodes; using PARR.DAL.DomainServices.Shortcodes;
@@ -47,14 +45,15 @@ namespace PARR.DAL.NextRunServices
this.settingsFromDb = settingsFromDb; this.settingsFromDb = settingsFromDb;
} }
public async Task<List<TemplateNextRunResultDto>?> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId)
public async Task<List<TemplateNextRunResultDto>?> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId, TemplateStatusTypeEnum? templateStatusType)
{ {
logger.LogInformation("Начинаю распределять шаблоны для группы работ {gobGroupId}", jobGroupId); logger.LogInformation("Начинаю распределять шаблоны для группы работ {gobGroupId}, templateStatusType: {templateStatusType}", jobGroupId, templateStatusType);
var jobGroup = await jobGroupService.Get() var jobGroup = await jobGroupService.Get()
.AsNoTracking()
.Include(t => t.DistributionConfig) .Include(t => t.DistributionConfig)
.ThenInclude(t => t.DistributionPeriod) .ThenInclude(t => t.DistributionPeriod)
.AsNoTracking()
.FirstOrDefaultAsync(t => t.Id == jobGroupId); .FirstOrDefaultAsync(t => t.Id == jobGroupId);
if (jobGroup == null) if (jobGroup == null)
@@ -76,13 +75,20 @@ namespace PARR.DAL.NextRunServices
jobGroup.DistributionConfig.IsExcludeWeekends, jobGroup.DistributionConfig.IsGroupingByWorkGroup, jobGroup.IsResponseAreaTimezone); jobGroup.DistributionConfig.IsExcludeWeekends, jobGroup.DistributionConfig.IsGroupingByWorkGroup, jobGroup.IsResponseAreaTimezone);
//получаем шаблоны только в статусе Used //получаем шаблоны только в статусе Used
var allTemplates = await templateService.Get() var templateQuery = templateService.Get()
.AsNoTracking() .AsNoTracking()
.Include(t => t.Job) .Include(t => t.Job)
.Where(t => .Where(t =>
t.Job!.GroupId == jobGroupId t.Job!.GroupId == jobGroupId
&& t.StatusTypeId == TemplateStatusTypeEnum.Used //&& t.StatusTypeId == TemplateStatusTypeEnum.Used
).ToListAsync(); );
if (templateStatusType.HasValue)
templateQuery = templateQuery.Where(t => t.StatusTypeId == templateStatusType);
var allTemplates = await templateQuery.ToListAsync();
if (!allTemplates.Any()) if (!allTemplates.Any())
{ {
logger.LogInformation("В группе c ИД {jobGroupId} отсутствуют шаблоны в статусе Used", jobGroupId); logger.LogInformation("В группе c ИД {jobGroupId} отсутствуют шаблоны в статусе Used", jobGroupId);
@@ -106,39 +112,150 @@ namespace PARR.DAL.NextRunServices
if (isGroupingByWorkGroup) if (isGroupingByWorkGroup)
{ {
// группировать по РГ // группировать по РГ
logger.LogDebug("Нужно группировать по РГ");
// получаем для каждого шаблона РГ и сразу группируем по РГ
var templatesByWorkGroup = new Dictionary<string?, List<Template>>();
foreach (var template in allTemplates)
{
var workGroupName = await shortcodesService.ApplyShortcodesAsync(template.Job!.WorkGroupMask, template);
// Если даже workGroupName == null, ну и ладно, сгруппируем по null, и распределим шаблоны в рамках этого null
if (workGroupName == null)
logger.LogWarning("Для шаблона {id}, с маской РГ '{workGroupMask}', не смог с помощью шорткода определить рабочую группу, шорткод сервис вернул РГ: '{workGroupName}'",
template.Id, template.Job!.WorkGroupMask, workGroupName);
// Добавляем шаблон в группу
if (!templatesByWorkGroup.TryGetValue(workGroupName, out var templatesList))
{
templatesList = new List<Template>();
templatesByWorkGroup[workGroupName] = templatesList;
}
templatesList.Add(template);
}
logger.LogDebug("Групп для распределения: {count}", templatesByWorkGroup.Count);
var dateStart = GetDateStart();
// Будем распределять каждую РГ отдельно
foreach (var (workGroupName, templates) in templatesByWorkGroup)
{
logger.LogDebug("Готовлюсь распределать шаблоны {templateCount} шт. в РГ '{workGroup}'", templates.Count, workGroupName);
if (isResponseAreaTimeZone) if (isResponseAreaTimeZone)
{ {
// использовать часовой пояс РГ // использовать часовой пояс РГ
logger.LogDebug("Использовать часовой пояс РГ");
// считаем, что у всех шаблонов сгруппированных по РГ, одна ЗО
// получаем ЗО для первого шаблона
var firstTemplate = templates.First();
var responseArea = await shortcodesService.ApplyShortcodesAsync(firstTemplate.Job!.ResponseAreaMask, firstTemplate);
if (responseArea == null)
logger.LogWarning("Для шаблона {id}, с маской ЗО '{responseAreaMask}', не смог с помощью шорткода определить ЗО, шорткод сервис вернул ЗО: '{responseArea}'",
firstTemplate.Id, firstTemplate.Job!.ResponseAreaMask, responseArea);
var offset = GetOffsetForDistributionByResponseArea(responseArea);
var templatesForDistribute = templates.Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList();
var referenceDate = GetReferenceDate(jobGroup, responseArea);
logger.LogInformation("Буду распределать шаблоны {count} шт, сгруппированные по РГ '{workGroup}', использую часовой пояс ЗО. dateStart: {dateStart}, offset: {offset}, referenceDate: {referenceDate}",
templatesForDistribute.Count, workGroupName, dateStart, offset, referenceDate);
var distributionResult = await templateDistributor.DistributeTemplatesAsync(dateStart, durationDays, referenceDate, offset, templatesForDistribute, jobGroup.DistributionConfig.IsExcludeWeekends);
logger.LogDebug("Закончил распределение для РГ '{workGroupName}', referenceDate: {referenceDate}, часового пояса ЗО {responseArea}, utcOffset: {offset}, распределил шаблонов: {count} шт.",
workGroupName, referenceDate, responseArea, offset, distributionResult.Count);
distributedTemplates.AddRange(distributionResult);
} }
else else
{ {
// не нужно использовать часовой пояс РГ (используем часовой пояс УЗ ЕСПП) // не нужно использовать часовой пояс РГ (используем часовой пояс УЗ ЕСПП)
logger.LogDebug("Не нужно использовать часовой пояс РГ (используем часовой пояс УЗ ЕСПП)");
var offset = GetOffsetForDistributionByResponseArea();
var templatesForDistribute = templates.Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList();
var referenceDate = GetReferenceDate(jobGroup, null);
logger.LogInformation("Буду распределать шаблоны {count} шт, сгруппированные по РГ '{workGroup}', НЕ НУЖНО использовать часовой пояс ЗО. dateStart: {dateStart}, offset: {offset}, referenceDate: {referenceDate}",
templatesForDistribute.Count, workGroupName, dateStart, offset, referenceDate);
var distributionResult = await templateDistributor.DistributeTemplatesAsync(dateStart, durationDays, referenceDate, offset, templatesForDistribute, jobGroup.DistributionConfig.IsExcludeWeekends);
logger.LogDebug("Закончил распределение для РГ '{workGroup}', referenceDate: {referenceDate}, utcOffset: {offset}, распределил шаблонов: {count} шт.", workGroupName, referenceDate, offset, distributionResult.Count);
distributedTemplates.AddRange(distributionResult);
}
} }
} }
else else
{ {
//не нужно группировать по РГ //не нужно группировать по РГ
logger.LogDebug("Не нужно группировать по РГ");
if (isResponseAreaTimeZone) if (isResponseAreaTimeZone)
{ {
// использовать ЧАСОВОЙ ПОЯС РГ (нужно сгруппировать шаблоны по часовым поясам, затем отдельно распределить каждую группу) // использовать ЧАСОВОЙ ПОЯС ЗО (нужно сгруппировать шаблоны по часовым поясам, затем отдельно распределить каждую группу)
logger.LogDebug("Использовать ЧАСОВОЙ ПОЯС ЗО (нужно сгруппировать шаблоны по часовым поясам, затем отдельно распределить каждую группу)");
// получаем для каждого шаблона ЗО и сразу группируем по ЗО
var templatesByResponseArea = new Dictionary<string?, List<Template>>();
foreach (var template in allTemplates)
{
var responseArea = await shortcodesService.ApplyShortcodesAsync(template.Job!.ResponseAreaMask, template);
if (responseArea == null)
logger.LogWarning("Для шаблона {id}, с маской ЗО '{responseAreaMask}', не смог с помощью шорткода определить ЗО, шорткод сервис вернул ЗО: '{responseArea}'",
template.Id, template.Job!.ResponseAreaMask, responseArea);
// Добавляем шаблон в группу
if (!templatesByResponseArea.TryGetValue(responseArea, out var templateList))
{
templateList = new List<Template>();
templatesByResponseArea[responseArea] = templateList;
}
templateList.Add(template);
}
logger.LogDebug("Групп для распределения: {count}", templatesByResponseArea.Count);
var dateStart = GetDateStart();
// для каждой ЗО получить offset и распределить шаблоны
foreach (var (responseArea, templates) in templatesByResponseArea)
{
var offset = GetOffsetForDistributionByResponseArea(responseArea);
var templatesForDistribute = templates.Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList();
var referenceDate = GetReferenceDate(jobGroup, responseArea);
logger.LogInformation("Буду распределять шаблоны {count} шт, их НЕ НУЖНО группировать по РГ, НУЖНО использовать часовой пояс ЗО: {responseArea}, utcOffset: {offset}. dateStart: {dateStart}, referenceDate: {referenceDate}",
templatesForDistribute.Count, responseArea, offset, dateStart, referenceDate);
var distributionResult = await templateDistributor.DistributeTemplatesAsync(dateStart, durationDays, referenceDate, offset, templatesForDistribute, jobGroup.DistributionConfig.IsExcludeWeekends);
logger.LogDebug("Закончил распределение для часового пояса ЗО {responseArea}, utcOffset: {offset}, referenceDate: {referenceDate}, распределил шаблонов: {count} шт.", responseArea, offset, referenceDate, distributionResult.Count);
distributedTemplates.AddRange(distributionResult);
}
} }
else else
{ {
// не нужно использовать часовой пояс РГ // не нужно использовать часовой пояс ЗО
logger.LogDebug("Не нужно использовать часовой пояс ЗО. Распределю все шаблоны без группировки.");
var offset = GetOffsetForDistribution(); var offset = GetOffsetForDistributionByResponseArea();
var templatesForDistribute = allTemplates.Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList(); var templatesForDistribute = allTemplates.Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList();
var dateStart = GetDateStart(offset); var referenceDate = GetReferenceDate(jobGroup, null);
var dateStart = GetDateStart();
logger.LogInformation("Буду распределать шаблоны {count} шт, их НЕ НУЖНО группировать по РГ, НЕ НУЖНО использовать часовой пояс РГ. dateStart в целевом часовом поясе: {dateStart}, offset: {offset}", logger.LogInformation("Буду распределать шаблоны {count} шт, их НЕ НУЖНО группировать по РГ, НЕ НУЖНО использовать часовой пояс ЗО. dateStart: {dateStart}, offset: {offset}, referenceDate: {referenceDate}",
templatesForDistribute.Count, dateStart, offset); templatesForDistribute.Count, dateStart, offset, referenceDate);
distributedTemplates = await templateDistributor.DistributeTemplatesAsync(dateStart, durationDays, jobGroup.ReferenceDate, offset, templatesForDistribute, jobGroup.DistributionConfig.IsExcludeWeekends); distributedTemplates = await templateDistributor.DistributeTemplatesAsync(dateStart, durationDays, referenceDate, offset, templatesForDistribute, jobGroup.DistributionConfig.IsExcludeWeekends);
} }
} }
logger.LogInformation("Закончил распределение шаблонов {count} шт. для jobGroupId: {jobGroupId}. Изменено: {changedCount}, без изменений: {oldCount}",
distributedTemplates.Count, jobGroupId, distributedTemplates.Count(t => t.NextRun != t.NextRunOld), distributedTemplates.Count(t => t.NextRun == t.NextRunOld));
return distributedTemplates; return distributedTemplates;
} }
@@ -186,9 +303,9 @@ namespace PARR.DAL.NextRunServices
/// Получить часовую зону для распределения /// Получить часовую зону для распределения
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private TimeSpan GetOffsetForDistribution(string? responseArea = null) private TimeSpan GetOffsetForDistributionByResponseArea(string? responseArea = null)
{ {
// или часова зона робота, или часовая зона РГ // или часовая зона робота, или часовая зона РГ
if (responseArea != null) if (responseArea != null)
{ {
// возвращаем часовой пояс ЗО // возвращаем часовой пояс ЗО
@@ -222,19 +339,81 @@ namespace PARR.DAL.NextRunServices
/// <summary> /// <summary>
/// Получить дату начала распределения в целевом часовом поясе /// Получить дату начала распределения
/// </summary> /// </summary>
/// <param name="offset"></param> /// <param name="offset"></param>
/// <returns></returns> /// <returns></returns>
private DateOnly GetDateStart(TimeSpan offset) private DateOnly GetDateStart()
{ {
var dateStart = DateOnly.FromDateTime(DateTimeOffset.UtcNow.ToOffset(offset).Date); //var dateStart = DateOnly.FromDateTime(DateTimeOffset.UtcNow.ToOffset(offset).Date);
logger.LogDebug("Дата начала распределения (сегодня) в целевом часовом поясе {dateStart}, offset: {offset}", dateStart, offset); //logger.LogDebug("Дата начала распределения (сегодня) в целевом часовом поясе {dateStart}, offset: {offset}", dateStart, offset);
var dateStart = DateOnly.FromDateTime(DateTime.UtcNow.Date);
logger.LogDebug("Дата начала распределения (сегодня): {dateStart}", dateStart);
return dateStart; return dateStart;
} }
/// <summary>
/// Получить referenceDate для расчета с учетом часового пояса ЗО или без учета
/// </summary>
/// <param name="jobGroup"></param>
/// <param name="responseArea">Не обзяательный параметр, нужен обязательно при расчете с учетом часового пояса ЗО</param>
/// <returns></returns>
private DateTimeOffset GetReferenceDate(JobGroup jobGroup, string? responseArea)
{
// для того чтобы посчитать nextRun в часовом поясе ЗО, нужно пересчитать refDate чтобы понять в какое время хотел выполнять заказчик
logger.LogDebug("Исходный referenceDate UTC: {referenceDate}", jobGroup.ReferenceDate);
if (jobGroup.IsResponseAreaTimezone)
{
// нужно вернуть с учетом часового пояса клиента сохранившего refDate (используется для расчета с учетом часового пояса ЗО)
var clientOffset = jobGroup.UserTimeZoneOffset;
if (!clientOffset.HasValue)
{
logger.LogError("При расчете referenceDate для ЗО '{responseArea}', UserTimeZoneOffset=null. Вернул referenceDate {referenceDate} без смещения ЗО",
responseArea, jobGroup.ReferenceDate);
return jobGroup.ReferenceDate;
}
if (responseArea == null)
{
logger.LogError("При расчете referenceDate для ЗО '{responseArea}', responseArea=null. Вернул referenceDate {referenceDate} без смещения ЗО",
responseArea, jobGroup.ReferenceDate);
return jobGroup.ReferenceDate;
}
var responseAreaOffset = scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea).UtcTimeOffset;
// = реф + офКлиента(который нажал в ГУИ сохранить)-офЗО
var resultOffset = clientOffset.Value - responseAreaOffset;
var refDateWithResponseAreaOffset = jobGroup.ReferenceDate.Add(resultOffset);
logger.LogDebug("Клиент ожидает, что будет выполняться задача в каждой ЗО в {time}. referenceDate+clientOffset, {referenceDate}, {clientOffset}",
TimeOnly.FromDateTime(jobGroup.ReferenceDate.Add(clientOffset.Value).DateTime), jobGroup.ReferenceDate, clientOffset);
logger.LogDebug("Итоговый referenceDate UTC: {resultRefDate}, для использования часовой зоны ЗО: '{responseArea}', добавлено времени {resultOffset} к исходному {refDate}",
refDateWithResponseAreaOffset, responseArea, resultOffset, jobGroup.ReferenceDate);
logger.LogDebug("Если итоговый referenceDate UTC {refDateWithResponseAreaOffset} перевести в часовой пояс ЗО {responseAreaOffset}, то дата в часовом поясе ЗО будет {refDateTargetTz}",
refDateWithResponseAreaOffset, responseAreaOffset, refDateWithResponseAreaOffset.Add(responseAreaOffset));
return refDateWithResponseAreaOffset;
}
else
{
// если НЕ НУЖНО в часовом поясе ЗО, то просто возвращаем refDate
logger.LogDebug("Итоговый referenceDate UTC: {refDate}, не нужно использовать часовой пояс ЗО", jobGroup.ReferenceDate);
return jobGroup.ReferenceDate;
}
}
} }
} }

View File

@@ -8,7 +8,7 @@ namespace PARR.DAL.NextRunServices.Subservices
/// <summary> /// <summary>
/// Распределить шаблоны /// Распределить шаблоны
/// </summary> /// </summary>
/// <param name="startDate"></param> /// <param name="startDate">Дата начала, в любом часовом поясе</param>
/// <param name="duration"></param> /// <param name="duration"></param>
/// <param name="referenceDate"></param> /// <param name="referenceDate"></param>
/// <param name="offset"></param> /// <param name="offset"></param>
@@ -21,7 +21,7 @@ namespace PARR.DAL.NextRunServices.Subservices
/// Метод проверяет, актуален ли текущий NextRun шаблона, если не актуален, возвращает актуальное значение /// Метод проверяет, актуален ли текущий NextRun шаблона, если не актуален, возвращает актуальное значение
/// При проверке загружаются шаблоны из БД! Если хотим рассчитывать nextRun для НЕСКОЛЬКИХ шаблонов, то следует рассчитать nextRun для одного шаблона, сохранить в БД, затем рассчитать для следующего /// При проверке загружаются шаблоны из БД! Если хотим рассчитывать nextRun для НЕСКОЛЬКИХ шаблонов, то следует рассчитать nextRun для одного шаблона, сохранить в БД, затем рассчитать для следующего
/// </summary> /// </summary>
/// <param name="startDate"></param> /// <param name="startDate">Дата начала, в любом часовом поясе</param>
/// <param name="duration"></param> /// <param name="duration"></param>
/// <param name="referenceDate"></param> /// <param name="referenceDate"></param>
/// <param name="offset"></param> /// <param name="offset"></param>

View File

@@ -540,7 +540,7 @@ namespace PARR.DAL.NextRunServices.Subservices
var updatedTemplates = new List<TemplateNextRunResultDto>(templatesToKeep); var updatedTemplates = new List<TemplateNextRunResultDto>(templatesToKeep);
foreach (var template in templatesToReassign) foreach (var template in templatesToReassign.OrderBy(t => t.NextRun))
{ {
var nextRunInTargetTz = FindNextAvailableDateWithLoad(currentDailyLoad, workDays, referenceDateInTargetTz, expectedDailyLoad, targetOffset); var nextRunInTargetTz = FindNextAvailableDateWithLoad(currentDailyLoad, workDays, referenceDateInTargetTz, expectedDailyLoad, targetOffset);
if (nextRunInTargetTz.HasValue) if (nextRunInTargetTz.HasValue)

View File

@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.DAL.Cache.Services.Base; using PARR.DAL.Cache.Services.Base;
using PARR.DAL.Configurations.DbSettings; using PARR.DAL.Configurations.DbSettings;
using PARR.DAL.Context; using PARR.DAL.Context;
@@ -189,8 +190,9 @@ namespace PARR.DAL
using var scope = provider.CreateScope(); using var scope = provider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<DataContext>(); var dbContext = scope.ServiceProvider.GetRequiredService<DataContext>();
var settingsFromDb = scope.ServiceProvider.GetRequiredService<SettingsFromDb>(); var settingsFromDb = scope.ServiceProvider.GetRequiredService<SettingsFromDb>();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<ScheduleResponseAreaTimeOffsetService>>();
return new ScheduleResponseAreaTimeOffsetService(dbContext, settingsFromDb); return new ScheduleResponseAreaTimeOffsetService(dbContext, settingsFromDb, logger);
}); });
} }

View File

@@ -11,13 +11,15 @@ namespace PARR.TemplateDistributor
internal class TemplateDistributor : ITemplateDistributor internal class TemplateDistributor : ITemplateDistributor
{ {
private readonly ILogger<TemplateDistributor> logger; private readonly ILogger<TemplateDistributor> logger;
private readonly INextRunService nextRunService; //private readonly INextRunService nextRunService;
private readonly INextRunServiceV2 nextRunService;
private readonly ITemplateService templateService; private readonly ITemplateService templateService;
private readonly IRobotConfigurationService robotConfigurationService; private readonly IRobotConfigurationService robotConfigurationService;
public TemplateDistributor( public TemplateDistributor(
ILogger<TemplateDistributor> logger, ILogger<TemplateDistributor> logger,
INextRunService nextRunService, //INextRunService nextRunService,
INextRunServiceV2 nextRunService,
ITemplateService templateService, ITemplateService templateService,
IRobotConfigurationService robotConfigurationService IRobotConfigurationService robotConfigurationService
) )
@@ -32,20 +34,22 @@ namespace PARR.TemplateDistributor
public async Task DistributeAsync(TemplateDistributorMq mqResponse) public async Task DistributeAsync(TemplateDistributorMq mqResponse)
{ {
var jobGroupId = mqResponse.JobGroupId; var jobGroupId = mqResponse.JobGroupId;
// распределяем шаблоны только в статусе Used
var templateStatusType = TemplateStatusTypeEnum.Used;
// вызвать метод распределения, и получить новые даты // вызвать метод распределения, и получить новые даты
var distributedTemplates = await nextRunService.GetNextRunForJobGroupWithAutoDistributionAsync(jobGroupId); var distributedTemplates = await nextRunService.GetNextRunForJobGroupWithAutoDistributionAsync(jobGroupId, templateStatusType);
if (distributedTemplates == null) if (distributedTemplates == null)
{ {
logger.LogWarning("При распределении шаблонов по jobGroupId {jobGroupId} вернулся null. Это ошибка. Прекращаю распределение.", jobGroupId); logger.LogError("При распределении шаблонов по jobGroupId {jobGroupId} вернулся null. Это ошибка. Прекращаю распределение.", jobGroupId);
return; return;
} }
// получить список шаблонов, сравнить их с распределенными, обновить даты, сохранить // получить список шаблонов, сравнить их с распределенными, обновить даты, сохранить
var groupTemplates = await templateService.Get() var groupTemplates = await templateService.Get()
.Include(t => t.RobotConfigurations) .Include(t => t.RobotConfigurations)
.Where(t => t.Job.GroupId == jobGroupId) .Where(t => t.Job!.GroupId == jobGroupId && t.StatusTypeId == templateStatusType)
.ToListAsync(); .ToListAsync();
if (!groupTemplates.Any()) if (!groupTemplates.Any())

View File

@@ -1,4 +1,5 @@
using PARR.DAL.DomainServices.Shortcodes; using PARR.Constants;
using PARR.DAL.DomainServices.Shortcodes;
using PARR.DAL.NextRunServices; using PARR.DAL.NextRunServices;
using PARR.DAL.NextRunServices.Models; using PARR.DAL.NextRunServices.Models;
using PARR.DAL.NextRunServices.Subservices; using PARR.DAL.NextRunServices.Subservices;
@@ -38,7 +39,7 @@ namespace PARR.Test.NextRun
{ {
#region тестирование INextRunServiceV2 #region тестирование INextRunServiceV2
var distributeResult = await nextRunServiceV2.GetNextRunForJobGroupWithAutoDistributionAsync(Guid.Parse("d25d8a9e-898f-417a-9bec-ef3a356e7c94")); var distributeResult = await nextRunServiceV2.GetNextRunForJobGroupWithAutoDistributionAsync(Guid.Parse("d25d8a9e-898f-417a-9bec-ef3a356e7c94"), TemplateStatusTypeEnum.Used);
#endregion #endregion