feat(dal, TemplateDistributorWorker): NextRunServiceV2 - реализован метод распределения шаблонов. Обновлен TemplateDistributorWorker для использования новой логики.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user