feat(dal,): NextRunServiceV2 - метод получения nextRun для существующего шаблона
This commit is contained in:
@@ -20,8 +20,8 @@ namespace PARR.DAL.NextRunServices
|
|||||||
/// <param name="jobGroupId">ИД группы работ</param>
|
/// <param name="jobGroupId">ИД группы работ</param>
|
||||||
/// <param name="workGroupName">Рабочая группа, не маска</param>
|
/// <param name="workGroupName">Рабочая группа, не маска</param>
|
||||||
/// <param name="responseAreaName">Зона ответственности, не маска</param>
|
/// <param name="responseAreaName">Зона ответственности, не маска</param>
|
||||||
/// <returns></returns>
|
/// <returns>NextRun или null, если null - то ошибка</returns>
|
||||||
Task<DateTimeOffset> GetNextRunForNewTemplateAsync(Guid jobGroupId, string workGroupName, string responseAreaName);
|
Task<DateTimeOffset?> GetNextRunForNewTemplateAsync(Guid jobGroupId, string workGroupName, string responseAreaName);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -29,8 +29,8 @@ namespace PARR.DAL.NextRunServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="templateId">ИД шаблона</param>
|
/// <param name="templateId">ИД шаблона</param>
|
||||||
/// <param name="isNew">При перемещении шаблона в новую для него работу, ставить isNew=true</param>
|
/// <param name="isNew">При перемещении шаблона в новую для него работу, ставить isNew=true</param>
|
||||||
/// <returns></returns>
|
/// <returns>NextRun или null, если null - то ошибка</returns>
|
||||||
Task<DateTimeOffset> GetNextRunForTemplateAsync(Guid templateId, bool isNew);
|
Task<DateTimeOffset?> GetNextRunForTemplateAsync(Guid templateId, bool isNew);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ namespace PARR.DAL.NextRunServices
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<DateTimeOffset> GetNextRunForNewTemplateAsync(Guid jobGroupId, string workGroupName, string responseAreaName)
|
public async Task<DateTimeOffset?> GetNextRunForNewTemplateAsync(Guid jobGroupId, string workGroupName, string responseAreaName)
|
||||||
{
|
{
|
||||||
logger.LogDebug("Получить nextRun для вновь создаваемого шаблона. jobGroupId: {jobGroupId}, workGroupName: {workGroupName}, responseAreaName: {responseAreaName}",
|
logger.LogDebug("Получить nextRun для вновь создаваемого шаблона. jobGroupId: {jobGroupId}, workGroupName: {workGroupName}, responseAreaName: {responseAreaName}",
|
||||||
jobGroupId, workGroupName, responseAreaName);
|
jobGroupId, workGroupName, responseAreaName);
|
||||||
@@ -274,7 +274,8 @@ namespace PARR.DAL.NextRunServices
|
|||||||
if (jobGroup == null)
|
if (jobGroup == null)
|
||||||
{
|
{
|
||||||
logger.LogError("Не найдена группа работ с Id: {jobGroupId}.", jobGroupId);
|
logger.LogError("Не найдена группа работ с Id: {jobGroupId}.", jobGroupId);
|
||||||
throw new ArgumentNullException(nameof(jobGroupId), $"Не найдена группа работ с Id: {jobGroupId}");
|
//throw new ArgumentNullException(nameof(jobGroupId), $"Не найдена группа работ с Id: {jobGroupId}");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jobGroup.IsAutoDistributionEnabled)
|
if (jobGroup.IsAutoDistributionEnabled)
|
||||||
@@ -285,7 +286,8 @@ namespace PARR.DAL.NextRunServices
|
|||||||
if (jobGroup.DistributionConfig == null)
|
if (jobGroup.DistributionConfig == null)
|
||||||
{
|
{
|
||||||
logger.LogError("Для группы работ {jobGroupId}, указано автораспределение, но отсутствует конфиг в таблице {GroupDistributionConfigs}", jobGroupId, nameof(JobGroupDistributionConfig));
|
logger.LogError("Для группы работ {jobGroupId}, указано автораспределение, но отсутствует конфиг в таблице {GroupDistributionConfigs}", jobGroupId, nameof(JobGroupDistributionConfig));
|
||||||
throw new ArgumentNullException(nameof(JobGroupDistributionConfig), $"Для jobGroupId: {jobGroupId} отсутствует конфигурация автораспределения в таблице {nameof(JobGroupDistributionConfig)}");
|
//throw new ArgumentNullException(nameof(JobGroupDistributionConfig), $"Для jobGroupId: {jobGroupId} отсутствует конфигурация автораспределения в таблице {nameof(JobGroupDistributionConfig)}");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var startDate = GetDateStart();
|
var startDate = GetDateStart();
|
||||||
@@ -430,7 +432,7 @@ namespace PARR.DAL.NextRunServices
|
|||||||
|
|
||||||
if (jobGroup.IsResponseAreaTimezone)
|
if (jobGroup.IsResponseAreaTimezone)
|
||||||
{
|
{
|
||||||
// использовать часовой пояс РГ
|
// использовать часовой пояс ЗО
|
||||||
|
|
||||||
var referenceDate = GetReferenceDate(jobGroup, responseAreaName);
|
var referenceDate = GetReferenceDate(jobGroup, responseAreaName);
|
||||||
var offset = GetOffsetForDistributionByResponseArea(responseAreaName);
|
var offset = GetOffsetForDistributionByResponseArea(responseAreaName);
|
||||||
@@ -443,7 +445,7 @@ namespace PARR.DAL.NextRunServices
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// не использовать часовой пояс РГ
|
// не использовать часовой пояс ЗО
|
||||||
// так как это классическое расписание еспп, и не используется часовой пояс РГ, то нам нужно считать в часовом поясе УЗ ЕСПП, т.е. МСК
|
// так как это классическое расписание еспп, и не используется часовой пояс РГ, то нам нужно считать в часовом поясе УЗ ЕСПП, т.е. МСК
|
||||||
|
|
||||||
var referenceDate = GetReferenceDate(jobGroup, null);
|
var referenceDate = GetReferenceDate(jobGroup, null);
|
||||||
@@ -459,12 +461,217 @@ namespace PARR.DAL.NextRunServices
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<DateTimeOffset> GetNextRunForTemplateAsync(Guid templateId, bool isNew)
|
public async Task<DateTimeOffset?> GetNextRunForTemplateAsync(Guid templateId, bool isNew)
|
||||||
{
|
{
|
||||||
logger.LogDebug("Получить nextRun для существующего шаблона, templateId: {templateId}, isNew: {isNew}", templateId, isNew);
|
logger.LogDebug("Получить nextRun для существующего шаблона, templateId: {templateId}, isNew: {isNew}", templateId, isNew);
|
||||||
|
|
||||||
|
var template = await templateService.Get()
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(t => t.Job)
|
||||||
|
.ThenInclude(t => t.Group).ThenInclude(t => t.DistributionConfig).ThenInclude(t => t.DistributionPeriod)
|
||||||
|
.FirstOrDefaultAsync(t => t.Id == templateId);
|
||||||
|
|
||||||
throw new NotImplementedException();
|
if (template == null)
|
||||||
|
{
|
||||||
|
logger.LogError("Не найден шаблон с Id: {templateId}.", templateId);
|
||||||
|
//throw new ArgumentNullException(nameof(templateId), $"Не найден шаблон с Id: {templateId}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.Job!.Group!.IsAutoDistributionEnabled == true)
|
||||||
|
{
|
||||||
|
// включено автораспределение
|
||||||
|
logger.LogDebug("Включено автораспределение");
|
||||||
|
|
||||||
|
if (template.Job!.Group.DistributionConfig == null)
|
||||||
|
{
|
||||||
|
logger.LogError("Для шаблона {templateId}, jobGroupId {jobGroupId}, указано автораспределение, но отсутствует конфиг в таблице {GroupDistributionConfigs}", template.Id, template.Job.GroupId, nameof(JobGroupDistributionConfig));
|
||||||
|
// throw new ArgumentNullException(nameof(JobGroupDistributionConfig), $"Для jobGroupId: {template.Job.GroupId} отсутствует конфигурация автораспределения в таблице {nameof(JobGroupDistributionConfig)}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var startDate = GetDateStart();
|
||||||
|
var duration = GetDurationDays(template.Job.Group.DistributionConfig);
|
||||||
|
var excludeWeekends = template.Job.Group.DistributionConfig.IsExcludeWeekends;
|
||||||
|
var targetTemplate = new TemplateNextRunDto(template.Id, template.NextRun);
|
||||||
|
var templateStatusType = TemplateStatusTypeEnum.Used;
|
||||||
|
|
||||||
|
var jobGroup = template.Job.Group;
|
||||||
|
|
||||||
|
// получаем все шаблоны из этой же группы что и template
|
||||||
|
var allTemplatesQuery = templateService.Get()
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(t => t.Job)
|
||||||
|
.Where(t => t.StatusTypeId == templateStatusType && t.Job!.GroupId == jobGroup.Id);
|
||||||
|
|
||||||
|
// группировать по РГ
|
||||||
|
var isGroupingByWorkGroup = jobGroup.DistributionConfig.IsGroupingByWorkGroup;
|
||||||
|
|
||||||
|
// использовать часовой пояс РГ
|
||||||
|
var isResponseAreaTimeZone = jobGroup.IsResponseAreaTimezone;
|
||||||
|
|
||||||
|
if (isGroupingByWorkGroup)
|
||||||
|
{
|
||||||
|
var targetTemplateWorkGroup = await shortcodesService.ApplyShortcodesAsync(template.Job.WorkGroupMask, template);
|
||||||
|
|
||||||
|
// группировать по РГ
|
||||||
|
logger.LogDebug("Нужно группировать по РГ");
|
||||||
|
|
||||||
|
// получаем для всех шаблонов РГ и группируем их по РГ
|
||||||
|
var templatesByWorkGroup = new Dictionary<string?, List<Template>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var allTemplates = await allTemplatesQuery.ToListAsync();
|
||||||
|
foreach (var templateItem in allTemplates)
|
||||||
|
{
|
||||||
|
var templateWorkGroupName = await shortcodesService.ApplyShortcodesAsync(templateItem.Job!.WorkGroupMask, templateItem);
|
||||||
|
|
||||||
|
// Если даже workGroupName == null, ну и ладно, сгруппируем по null
|
||||||
|
if (templateWorkGroupName == null)
|
||||||
|
logger.LogWarning("Для шаблона {id}, с маской РГ '{workGroupMask}', не смог с помощью шорткода определить рабочую группу, шорткод сервис вернул РГ: '{workGroupName}'",
|
||||||
|
templateItem.Id, templateItem.Job!.WorkGroupMask, templateWorkGroupName);
|
||||||
|
|
||||||
|
// Добавляем шаблон в группу
|
||||||
|
if (!templatesByWorkGroup.TryGetValue(templateWorkGroupName, out var templatesList))
|
||||||
|
{
|
||||||
|
templatesList = new List<Template>();
|
||||||
|
templatesByWorkGroup[templateWorkGroupName] = templatesList;
|
||||||
|
}
|
||||||
|
templatesList.Add(templateItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Берем шаблоны только нашей РГ workGroupName
|
||||||
|
templatesByWorkGroup.TryGetValue(targetTemplateWorkGroup, out var templatesWithWorkGroup);
|
||||||
|
|
||||||
|
var templatesByWorkGroupDto = (templatesWithWorkGroup ?? new List<Template>()).Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList();
|
||||||
|
|
||||||
|
logger.LogDebug("Шаблонов в РГ {targetTemplateWorkGroup} - {count} шт.", targetTemplateWorkGroup, templatesByWorkGroupDto.Count);
|
||||||
|
|
||||||
|
if (isResponseAreaTimeZone)
|
||||||
|
{
|
||||||
|
// использовать часовой пояс РГ
|
||||||
|
|
||||||
|
var targetTemplateResponseArea = await shortcodesService.ApplyShortcodesAsync(template.Job.ResponseAreaMask, template);
|
||||||
|
|
||||||
|
logger.LogDebug("Использовать часовой пояс РГ '{responseAreaName}'", targetTemplateResponseArea);
|
||||||
|
|
||||||
|
var offset = GetOffsetForDistributionByResponseArea(targetTemplateResponseArea);
|
||||||
|
var referenceDate = GetReferenceDate(jobGroup, targetTemplateResponseArea);
|
||||||
|
|
||||||
|
var nextRun = await templateDistributor.GetNextRunForTemplateAsync(startDate, duration, referenceDate, offset, targetTemplate, templatesByWorkGroupDto, excludeWeekends, isNew);
|
||||||
|
|
||||||
|
return nextRun.NextRun;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// не нужно использовать часовой пояс РГ (используем часовой пояс УЗ ЕСПП)
|
||||||
|
logger.LogDebug("Не нужно использовать часовой пояс РГ (используем часовой пояс УЗ ЕСПП)");
|
||||||
|
|
||||||
|
var offset = GetOffsetForDistributionByResponseArea();
|
||||||
|
var referenceDate = GetReferenceDate(jobGroup, null);
|
||||||
|
|
||||||
|
var nextRun = await templateDistributor.GetNextRunForTemplateAsync(startDate, duration, referenceDate, offset, targetTemplate, templatesByWorkGroupDto, excludeWeekends, isNew);
|
||||||
|
|
||||||
|
return nextRun.NextRun;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// не нужно группировать по РГ
|
||||||
|
logger.LogDebug("Не нужно группировать по РГ");
|
||||||
|
|
||||||
|
if (isResponseAreaTimeZone)
|
||||||
|
{
|
||||||
|
// использовать ЧАСОВОЙ ПОЯС ЗО
|
||||||
|
|
||||||
|
var responseAreaName = await shortcodesService.ApplyShortcodesAsync(template.Job.ResponseAreaMask, template);
|
||||||
|
|
||||||
|
logger.LogDebug("Нужно использовать часовой пояс ЗО '{responseAreaName}'", responseAreaName);
|
||||||
|
|
||||||
|
// получить все шаблоны, сгруппировать их по ЗО, получить nextRun в рамках переданной ЗО
|
||||||
|
var referenceDate = GetReferenceDate(jobGroup, responseAreaName);
|
||||||
|
var offset = GetOffsetForDistributionByResponseArea(responseAreaName);
|
||||||
|
var allTemplates = await allTemplatesQuery.ToListAsync();
|
||||||
|
|
||||||
|
// получаем для каждого шаблона ЗО и сразу группируем по ЗО
|
||||||
|
var templatesByResponseArea = new Dictionary<string?, List<Template>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (var templateItem in allTemplates)
|
||||||
|
{
|
||||||
|
var responseArea = await shortcodesService.ApplyShortcodesAsync(templateItem.Job!.ResponseAreaMask, templateItem);
|
||||||
|
if (responseArea == null)
|
||||||
|
logger.LogWarning("Для шаблона {id}, с маской ЗО '{responseAreaMask}', не смог с помощью шорткода определить ЗО, шорткод сервис вернул ЗО: '{responseArea}'",
|
||||||
|
templateItem.Id, templateItem.Job!.ResponseAreaMask, responseArea);
|
||||||
|
|
||||||
|
// Добавляем шаблон в группу
|
||||||
|
if (!templatesByResponseArea.TryGetValue(responseArea, out var templateList))
|
||||||
|
{
|
||||||
|
templateList = new List<Template>();
|
||||||
|
templatesByResponseArea[responseArea] = templateList;
|
||||||
|
}
|
||||||
|
templateList.Add(templateItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// из сгруппированных шаблонов, получаем существующие с ЗО нашего шаблона responseAreaName
|
||||||
|
templatesByResponseArea.TryGetValue(responseAreaName, out var templatesWithResponseArea);
|
||||||
|
var templatesWithResponseAreaDto = (templatesWithResponseArea ?? new List<Template>()).Select(t => new TemplateNextRunDto(t.Id, t.NextRun)).ToList();
|
||||||
|
|
||||||
|
logger.LogDebug("Существующих шаблонов в БД с responseAreaName: {responseAreaName} - {count} шт.", responseAreaName, templatesWithResponseAreaDto.Count);
|
||||||
|
|
||||||
|
var nextRun = await templateDistributor.GetNextRunForTemplateAsync(startDate, duration, referenceDate, offset, targetTemplate, templatesWithResponseAreaDto, excludeWeekends, isNew);
|
||||||
|
|
||||||
|
return nextRun.NextRun;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// не нужно использовать часовой пояс ЗО
|
||||||
|
logger.LogDebug("Не нужно использовать часовой пояс ЗО.");
|
||||||
|
|
||||||
|
var referenceDate = GetReferenceDate(jobGroup, null);
|
||||||
|
var offset = GetOffsetForDistributionByResponseArea();
|
||||||
|
var allTemplates = await allTemplatesQuery
|
||||||
|
.Select(t => new TemplateNextRunDto(t.Id, t.NextRun))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var nextRun = await templateDistributor.GetNextRunForTemplateAsync(startDate, duration, referenceDate, offset, targetTemplate, allTemplates, excludeWeekends, isNew);
|
||||||
|
|
||||||
|
return nextRun.NextRun;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// метод расчета ЕСПП
|
||||||
|
logger.LogDebug("Метод расчета ЕСПП");
|
||||||
|
|
||||||
|
if (template.Job.Group.IsResponseAreaTimezone)
|
||||||
|
{
|
||||||
|
// использовать часовой пояс ЗО
|
||||||
|
var responseAreaName = await shortcodesService.ApplyShortcodesAsync(template.Job.ResponseAreaMask, template);
|
||||||
|
var jobGroup = template.Job.Group;
|
||||||
|
|
||||||
|
var referenceDate = GetReferenceDate(jobGroup, responseAreaName);
|
||||||
|
var offset = GetOffsetForDistributionByResponseArea(responseAreaName);
|
||||||
|
|
||||||
|
logger.LogDebug("Расчет nextRun используя метод ЕСПП, использую часовой пояс ЗО '{responseAreaName}, referenceDate: {referenceDate}, offset: {offset}'", responseAreaName, referenceDate, offset);
|
||||||
|
|
||||||
|
var nextRun = await esppScheduleTransformService.GetNextDateAsync(jobGroup.Id, referenceDate, offset);
|
||||||
|
|
||||||
|
return nextRun;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// не использовать часовой пояс ЗО
|
||||||
|
// так как это классическое расписание еспп, и не используется часовой пояс РГ, то нам нужно считать в часовом поясе УЗ ЕСПП, т.е. МСК
|
||||||
|
|
||||||
|
var referenceDate = GetReferenceDate(template.Job.Group, null);
|
||||||
|
var offset = GetOffsetForDistributionByResponseArea();
|
||||||
|
|
||||||
|
logger.LogDebug("Расчет nextRun используя метод ЕСПП, не использую часовой пояс ЗО, использую часовой пояс УЗ ЕСПП, referenceDate: {referenceDate}, offset: {offset}", referenceDate, offset);
|
||||||
|
|
||||||
|
var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job.GroupId, referenceDate, offset);
|
||||||
|
|
||||||
|
return nextRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ namespace PARR.Test.NextRun
|
|||||||
// новый шаблон - еспп
|
// новый шаблон - еспп
|
||||||
//var nextRunForNewTemplateEspp = await nextRunServiceV2.GetNextRunForNewTemplateAsync(Guid.Parse("692531d6-4ef4-4a6d-99be-d2ef375d520f"), workGroupName: "ЦКИТ-ЗСИБ", responseAreaName: "83-ЗСИБ");
|
//var nextRunForNewTemplateEspp = await nextRunServiceV2.GetNextRunForNewTemplateAsync(Guid.Parse("692531d6-4ef4-4a6d-99be-d2ef375d520f"), workGroupName: "ЦКИТ-ЗСИБ", responseAreaName: "83-ЗСИБ");
|
||||||
|
|
||||||
|
// существующий шаблон - автодистриб
|
||||||
|
//var nextRunForExistTemplateDistib = await nextRunServiceV2.GetNextRunForTemplateAsync(Guid.Parse("05769f8d-9630-4683-b07a-070d69e1dc12"), false);
|
||||||
|
|
||||||
|
// существующий шаблон - еспп
|
||||||
|
var nextRunForExistTemplateEspp = await nextRunServiceV2.GetNextRunForTemplateAsync(Guid.Parse("1329dfca-5e09-4b19-a2e6-560a4896080c"), false);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user