diff --git a/PARR.API/Controllers/V1/RobotTaskController.cs b/PARR.API/Controllers/V1/RobotTaskController.cs index dac301e3..1533a48c 100644 --- a/PARR.API/Controllers/V1/RobotTaskController.cs +++ b/PARR.API/Controllers/V1/RobotTaskController.cs @@ -201,21 +201,28 @@ namespace PARR.API.Controllers.V1 { var template = task.Template!; + #region old // передаем LastRun, если его нет, то NextRun //var nextRun = await esppScheduleTransformService.GetNextDateAsync(task.Template!.ApplicationInWorkId, task.Template.ApplicationsInWork!.LastRun ?? task.Template.ApplicationsInWork.NextRun); // всегда считаем по nextRun - var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template.NextRun); + //var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template.NextRun); + #endregion + + //пока у нас выключено автораспределение, считает по refDate + //TODO: когда заработает автораспределение, будем думать!!!!! + + var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template!.Job!.Group!.ReferenceDate); if (nextRun != template.NextRun) { logger.LogDebug($"Для шаблона id {template.Id} обновляю nextRun, новое значение {nextRun}, старое значение {template.NextRun}"); - if (template.NextRun < DateTimeOffset.UtcNow) - { - logger.LogDebug($"Для шаблона id {template.Id} обновляю lastRun, новое значение {template.NextRun}, старое значение {template.LastRun}"); - template.LastRun = template.NextRun; - } - + //if (template.NextRun < DateTimeOffset.UtcNow) + //{ + // logger.LogDebug($"Для шаблона id {template.Id} обновляю lastRun, новое значение {template.NextRun}, старое значение {template.LastRun}"); + // template.LastRun = template.NextRun; + //} + template.LastRun = template.NextRun; template.NextRun = nextRun; await robotConfigurationService.CommitAsync(new HistoryInitiator { InitiatorComment = "При получении задания роботом, обновил NextRun", InitiatorIp = clientService.GetClientIp()?.ToString(), InitiatorParrComponentId = ParrComponentsEnum.Api }); diff --git a/PARR.DAL/Models/Template.cs b/PARR.DAL/Models/Template.cs index d842a405..9b64cc24 100644 --- a/PARR.DAL/Models/Template.cs +++ b/PARR.DAL/Models/Template.cs @@ -33,7 +33,7 @@ namespace PARR.DAL.Models public bool IsActiveSchedule { get; set; } /// - /// Шаблон не используется : перестал подходить условиям Job'а + /// Шаблон не используется : перестал подходить условиям Job'а. true - не используется /// public bool IsUnused { get; set; } = false; @@ -60,9 +60,9 @@ namespace PARR.DAL.Models //public Guid ApplicationInWorkId { get; set; } - public Guid JobId { get; set; }//TODO Вернуть не NULL!!! + public Guid JobId { get; set; } - public Guid UnitId { get; set; }//TODO Вернуть не NULL!!! + public Guid UnitId { get; set; } //public Guid HostId { get; set; } diff --git a/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs b/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs index be50736b..628eabc0 100644 --- a/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs +++ b/PARR.DAL/Services/Implementations/EsppSchTypeConfigService.cs @@ -31,76 +31,97 @@ namespace PARR.DAL.Services.Implementations .ThenInclude(t => t!.EsppSchValues); } + public async Task GetEsppScheduleDtoAsync(Guid jobGroupId) { //Формирует расписание в нормальном понятном виде из БД - var schValues = await dataContext.EsppSchValues - .Include(t => t.EsppSchTypeConfig) - .ThenInclude(t => t!.EsppSchTypeSchedule) - .Include(t => t.EsppSchTypeConfig) - .ThenInclude(t => t.EsppSchType) - .Include(t => t.EsppSchTypeValue) - .Include(t => t.JobGroup) - .Where(t => t.JobGroup!.Id == jobGroupId)//TODO Migration to job - .OrderBy(t => t.EsppSchTypeConfig!.Order) - .ToListAsync(); + var items = await dataContext.EsppSchValues.Where(t => t.JobGroupId == jobGroupId) + .Select(t => new + { + t.EsppSchTypeConfig!.Order, + Type = t.EsppSchTypeConfig.EsppSchType!, + Value = t.EsppSchTypeValue!, + TypeSchedule = t.EsppSchTypeConfig.EsppSchTypeSchedule! + }) + .OrderBy(t => t.Order) + .ToListAsync(); - - //var configs = await GetWithSchIncludes() - // .Where(t => t.EsppSchValues.Any(x => x.ApplicationsInWorkId == applicationInWorksId)) - // .ToListAsync(); - - //if (!configs.Any()) - // return null; - - if (!schValues.Any()) + if (items.Count == 0) return null; - - var values = new List(); - - //foreach (var config in configs) - //{ - // var value = new EsppScheduleValDto - // { - // Order = config.Order, - // Type = config.EsppSchType!, - // Value = config.EsppSchValues.First().EsppSchTypeValue! - // }; - - // values.Add(value); - //} - - foreach (var schValue in schValues) - { - var value = new EsppScheduleValDto - { - Order = schValue.EsppSchTypeConfig!.Order, - Type = schValue.EsppSchTypeConfig!.EsppSchType!, - Value = schValue.EsppSchTypeValue! - }; - - values.Add(value); - } - + var typeSchedule = items.First().TypeSchedule; var dto = new EsppScheduleDto { - TypeSchedule = schValues.First().EsppSchTypeConfig!.EsppSchTypeSchedule!, - Values = values.OrderBy(t => t.Order).ToList() + TypeSchedule = typeSchedule, + Values = items.Select(t => new EsppScheduleValDto + { + Order = t.Order, + Type = t.Type, + Value = t.Value + }).ToList() }; - return dto; } + + #region original GetEsppScheduleDtoAsync + //public async Task GetEsppScheduleDtoAsync(Guid jobGroupId) + //{ + // //Формирует расписание в нормальном понятном виде из БД + + // var schValues = await dataContext.EsppSchValues + // .AsNoTracking() + // .Include(t => t.EsppSchTypeConfig) + // .ThenInclude(t => t!.EsppSchTypeSchedule) + // .Include(t => t.EsppSchTypeConfig) + // .ThenInclude(t => t.EsppSchType) + // .Include(t => t.EsppSchTypeValue) + // .Include(t => t.JobGroup) + // .Where(t => t.JobGroup!.Id == jobGroupId) + // .OrderBy(t => t.EsppSchTypeConfig!.Order) + // .ToListAsync(); + + + // if (!schValues.Any()) + // return null; + + + // var values = new List(); + + // foreach (var schValue in schValues) + // { + // var value = new EsppScheduleValDto + // { + // Order = schValue.EsppSchTypeConfig!.Order, + // Type = schValue.EsppSchTypeConfig!.EsppSchType!, + // Value = schValue.EsppSchTypeValue! + // }; + + // values.Add(value); + // } + + + // var dto = new EsppScheduleDto + // { + // TypeSchedule = schValues.First().EsppSchTypeConfig!.EsppSchTypeSchedule!, + // Values = values.OrderBy(t => t.Order).ToList() + // }; + + + // return dto; + //} + #endregion + + public EsppScheduleDto? GetEsppScheduleDto(Guid jobGroupId) { var result = Task.Run(async () => { return await GetEsppScheduleDtoAsync(jobGroupId); - }).Result; + }).GetAwaiter().GetResult(); return result; } diff --git a/PARR.NextRun/NextRunManager.cs b/PARR.NextRun/NextRunManager.cs index dbfbe99c..6058dd8c 100644 --- a/PARR.NextRun/NextRunManager.cs +++ b/PARR.NextRun/NextRunManager.cs @@ -3,7 +3,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using PARR.BLL.Services.Interfaces; using PARR.Common.Domain; +using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; +using PARR.DAL.Services.Interfaces.Job; using PARR.DAL.TransformServices; using PARR.NextRun.Settings; @@ -40,11 +42,12 @@ namespace PARR.NextRun //var appInWorkService = scope.ServiceProvider.GetService(); var esppSchService = scope.ServiceProvider.GetService(); var templateService = scope.ServiceProvider.GetService(); + var jobGroupService = scope.ServiceProvider.GetService(); - if (templateService == null || esppSchService == null) - throw new Exception($"Не смог получить серивс {nameof(ITemplateService)} или {nameof(IEsppScheduleTransformService)}"); + if (templateService == null || esppSchService == null || jobGroupService == null) + throw new Exception($"Не смог получить серивс {nameof(ITemplateService)} или {nameof(IEsppScheduleTransformService)} или {nameof(IJobGroupService)}"); - await HandlerAsync(templateService, esppSchService); + await HandlerAsync(templateService, esppSchService, jobGroupService); } }, workerSettings.RepeatEvery); } @@ -54,33 +57,90 @@ namespace PARR.NextRun /// Рассчет следующей даты срабатываения /// /// - private async Task HandlerAsync(ITemplateService templateService, IEsppScheduleTransformService esppScheduleTransformService) + private async Task HandlerAsync(ITemplateService templateService, IEsppScheduleTransformService esppScheduleTransformService, IJobGroupService jobGroupService) { - var templates = await templateService.Get() - .Include(t => t.Job) - .ThenInclude(t => t.Group) - .Where(t => t.NextRun < DateTimeOffset.UtcNow).ToListAsync(); + #region логика для групп у которых не включено автораспределение - logger.LogDebug($"Шаблонов для обновления: {templates.Count()} шт."); + // выбираем шаблоны которые не учавствуют в автораспределении + // и у которых IsUnuser==false + // затем группируем по GroupId, так как nextRun и расписание настраивается для группы, то для всех дочерних шаблонов, nextRun будет одинаковым - int errorsCount = 0; - foreach (var template in templates) + var groups = await jobGroupService.Get() + .Where(t => t.IsAutoDistributionEnabled == false) + .Select(t => new { t.Id, t.ReferenceDate }) + .ToListAsync(); + + logger.LogInformation("Найдено {GroupCount} групп для обработки.", groups.Count); + + foreach (var group in groups) { - var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template.NextRun); - template.LastRun = template.NextRun; - template.NextRun = nextRun; + //получаем по каждой группе следующий nextRun и сравниваем с существующим, если не равны, то обновляем + var nextRun = await esppScheduleTransformService.GetNextDateAsync(group.Id, group.ReferenceDate); + + // Загружаем только шаблоны текущей группы где nextRun в БД не равен расчетному + var templatesToUpdate = await templateService.Get() + .Where(t => t.IsUnused == false && t.Job!.GroupId == group.Id && t.NextRun != nextRun) + .ToListAsync(); + + if (!templatesToUpdate.Any()) + continue; + + // Обновляем + foreach (var template in templatesToUpdate) + { + template.LastRun = template.NextRun; + template.NextRun = nextRun; + } + + // Коммитим изменения для этой группы if (await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Обновлён NextRun", InitiatorParrComponentId = Constants.ParrComponentsEnum.NextRun })) - logger.LogDebug($"Обновлены значения полей NextRun: {template.NextRun}, LastRun: {template.LastRun} для шаблона {template.Name}, {template.Id}"); + logger.LogInformation($"Обновлены значения полей NextRun для шаблонов группы: {group.Id}, " + + $"refDate: {group.ReferenceDate}. Обновлен nextRun: {nextRun} для шаблонов {templatesToUpdate.Count} шт."); else { - logger.LogError($"Ошибка при обновлении значений полей NextRun: {template.NextRun}, LastRun: {template.LastRun} для шаблона {template.Name}, {template.Id}"); - errorsCount++; + logger.LogError($"Ошибка при обновлении значений полей NextRun: {nextRun}, для шаблонов {templatesToUpdate.Count} шт., группы {group.Id}, refDate: {group.ReferenceDate} "); } } - logger.LogInformation($"Завершено обновление полей NextRun. Полей в задании: {templates.Count()}, обновлено: {templates.Count() - errorsCount}, ошибок: {errorsCount}"); + #endregion + + //todo: когда будет автораспределение, для него придумать логику как считать + + + + + #region old logic + //var templates = await templateService.Get() + // .Include(t => t.Job) + // .ThenInclude(t => t.Group) + // .Where(t => t.NextRun < DateTimeOffset.UtcNow).ToListAsync(); + + //logger.LogDebug($"Шаблонов для обновления: {templates.Count()} шт."); + + //int errorsCount = 0; + + //foreach (var template in templates) + //{ + // var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template.NextRun); + // template.LastRun = template.NextRun; + // template.NextRun = nextRun; + + // if (await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Обновлён NextRun", InitiatorParrComponentId = Constants.ParrComponentsEnum.NextRun })) + // logger.LogDebug($"Обновлены значения полей NextRun: {template.NextRun}, LastRun: {template.LastRun} для шаблона {template.Name}, {template.Id}"); + // else + // { + // logger.LogError($"Ошибка при обновлении значений полей NextRun: {template.NextRun}, LastRun: {template.LastRun} для шаблона {template.Name}, {template.Id}"); + // errorsCount++; + // } + //} + + //logger.LogInformation($"Завершено обновление полей NextRun. Полей в задании: {templates.Count()}, обновлено: {templates.Count() - errorsCount}, ошибок: {errorsCount}"); + + #endregion + + logger.LogInformation($"Завершено обновление полей NextRun."); } } }