2024-02-05 16:05:02 +10:00
using Microsoft.EntityFrameworkCore ;
using Microsoft.Extensions.DependencyInjection ;
using Microsoft.Extensions.Logging ;
using PARR.BLL.Services.Interfaces ;
2024-10-08 16:37:58 +10:00
using PARR.Common.Domain ;
2025-12-01 15:27:18 +10:00
using PARR.Constants ;
2026-01-22 11:46:05 +10:00
using PARR.DAL.NextRunServices ;
2024-02-05 16:05:02 +10:00
using PARR.DAL.Services.Interfaces ;
2025-11-25 16:49:28 +10:00
using PARR.DAL.Services.Interfaces.Job ;
2024-02-05 16:05:02 +10:00
using PARR.NextRun.Settings ;
namespace PARR.NextRun
{
2026-02-27 14:05:25 +10:00
/// <summary>
/// Расчет nextRun по интервалу
/// </summary>
internal class NextRunIntervalService : INextRunIntervalService
2024-02-05 16:05:02 +10:00
{
private readonly WorkerSettings workerSettings ;
2026-02-27 14:05:25 +10:00
private readonly ILogger < NextRunIntervalService > logger ;
2024-02-05 16:05:02 +10:00
private readonly IIntervalService intervalService ;
private readonly IServiceProvider serviceProvider ;
2026-02-27 14:05:25 +10:00
public NextRunIntervalService (
2024-02-05 16:05:02 +10:00
WorkerSettings workerSettings ,
2026-02-27 14:05:25 +10:00
ILogger < NextRunIntervalService > logger ,
2024-02-05 16:05:02 +10:00
IIntervalService intervalService ,
IServiceProvider serviceProvider
)
{
this . workerSettings = workerSettings ;
this . logger = logger ;
this . intervalService = intervalService ;
this . serviceProvider = serviceProvider ;
}
public async Task StartAsync ( )
{
logger . LogInformation ( "Запуск сервиса рассчета времени следующего создания наряда (nextRun)" ) ;
await intervalService . IntervalInitAsync ( async ( ) = >
{
using ( var scope = serviceProvider . CreateScope ( ) )
{
2024-07-03 15:19:09 +10:00
//var appInWorkService = scope.ServiceProvider.GetService<IApplicationsInWorkService>();
2026-01-22 11:46:05 +10:00
//var esppSchService = scope.ServiceProvider.GetService<IEsppScheduleTransformService>();
2024-07-03 15:19:09 +10:00
var templateService = scope . ServiceProvider . GetService < ITemplateService > ( ) ;
2025-11-25 16:49:28 +10:00
var jobGroupService = scope . ServiceProvider . GetService < IJobGroupService > ( ) ;
2026-03-05 10:19:54 +10:00
var nextRunService = scope . ServiceProvider . GetService < INextRunService > ( ) ;
2024-02-05 16:05:02 +10:00
2026-01-22 11:46:05 +10:00
if ( templateService = = null | | nextRunService = = null | | jobGroupService = = null )
2026-03-05 10:19:54 +10:00
throw new Exception ( $"Н е смог получить серивс {nameof(ITemplateService)} или {nameof(INextRunService)} или {nameof(IJobGroupService)}" ) ;
2024-02-05 16:05:02 +10:00
2026-01-22 11:46:05 +10:00
await HandlerAsync ( templateService , nextRunService , jobGroupService ) ;
2024-02-05 16:05:02 +10:00
}
} , workerSettings . RepeatEvery ) ;
}
/// <summary>
/// Рассчет следующей даты срабатываения
/// </summary>
/// <returns></returns>
2026-03-05 10:19:54 +10:00
private async Task HandlerAsync ( ITemplateService templateService , INextRunService nextRunService , IJobGroupService jobGroupService )
2024-02-05 16:05:02 +10:00
{
2026-01-23 09:28:14 +10:00
logger . LogInformation ( "Начинаю обновлять NextRun по расписанию" ) ;
2024-02-05 16:05:02 +10:00
2026-02-05 15:41:36 +10:00
//// обновляем для групп у которых не включено автораспределение
//await UpdateNextRunWithEsppScheduleAsync(templateService, nextRunService, jobGroupService);
2026-01-23 09:28:14 +10:00
2026-02-05 15:41:36 +10:00
//// для групп у которых включено автораспределение
//await UpdateNextRunWithAutodistributeScheduleAsync(templateService, nextRunService, jobGroupService);
await UpdateNextRunAsync ( templateService , nextRunService , jobGroupService ) ;
2026-01-23 09:28:14 +10:00
logger . LogInformation ( $"Завершено обновление полей NextRun." ) ;
}
2026-03-05 10:19:54 +10:00
private async Task UpdateNextRunAsync ( ITemplateService templateService , INextRunService nextRunService , IJobGroupService jobGroupService )
2026-02-05 15:41:36 +10:00
{
// выбираем все шаблоны с просроченным nextRun в статусе Used
var templatesForUpdate = await templateService . Get ( )
. Where ( t = >
t . StatusTypeId = = TemplateStatusTypeEnum . Used
& & t . NextRun < DateTimeOffset . UtcNow
) . ToListAsync ( ) ;
logger . LogInformation ( "Найдено шаблонов в статусе Used с просроченным NextRun {count} шт." , templatesForUpdate . Count ) ;
if ( ! templatesForUpdate . Any ( ) )
return ;
foreach ( var template in templatesForUpdate )
{
var newNextRun = await nextRunService . GetNextRunForTemplateAsync ( template . Id , false ) ;
2026-02-16 16:54:06 +10:00
if ( newNextRun . HasValue )
{
template . LastRun = template . NextRun ;
template . NextRun = newNextRun . Value ;
}
else
{
logger . LogError ( "При расчете nextRun для шаблона {templateId}, '{templateName}', nextRun=null. Это значит что при расчете возникла ошибка." , template . Id , template . Name ) ;
}
2026-02-05 15:41:36 +10:00
}
if ( await templateService . CommitAsync ( new HistoryInitiator { InitiatorComment = "Обновлён NextRun" , InitiatorParrComponentId = ParrComponentsEnum . NextRun } ) )
{
logger . LogInformation ( "Обновлены значения полей NextRun для шаблонов в статусе Used, {count} шт." , templatesForUpdate . Count ) ;
}
else
{
logger . LogError ( "Ошибка при обновлении значений полей NextRun, для шаблонов в статусе Used, {count} шт." , templatesForUpdate . Count ) ;
}
}
2026-02-27 14:05:25 +10:00
2024-02-05 16:05:02 +10:00
}
}