2026-03-11 12:10:11 +10:00
using Microsoft.EntityFrameworkCore ;
using Microsoft.Extensions.Logging ;
2026-04-30 10:35:31 +10:00
using PARR.Core.Repositories.Interfaces ;
2026-05-04 11:55:07 +10:00
using PARR.Core.Services.NextRunServices ;
2026-04-30 10:35:31 +10:00
using PARR.Domain.Entities ;
2026-04-13 16:58:30 +10:00
using PARR.Domain.Entities.Base.History ;
2026-04-14 12:01:49 +10:00
using PARR.Domain.Enums ;
2026-03-11 12:10:11 +10:00
namespace PARR.NextRun.Services
{
internal class NextRunUpdateService : INextRunUpdateService
{
private readonly ILogger < NextRunUpdateService > logger ;
2026-04-30 10:35:31 +10:00
private readonly ITemplateRepository templateService ;
2026-03-11 12:10:11 +10:00
private readonly INextRunService nextRunService ;
2026-04-30 10:35:31 +10:00
private readonly IRobotConfigurationRepository robotConfigurationService ;
2026-03-11 12:10:11 +10:00
public NextRunUpdateService (
ILogger < NextRunUpdateService > logger ,
2026-04-30 10:35:31 +10:00
ITemplateRepository templateService ,
2026-03-11 12:10:11 +10:00
INextRunService nextRunService ,
2026-04-30 10:35:31 +10:00
IRobotConfigurationRepository robotConfigurationService
2026-03-11 12:10:11 +10:00
)
{
this . logger = logger ;
this . templateService = templateService ;
this . nextRunService = nextRunService ;
this . robotConfigurationService = robotConfigurationService ;
}
public async Task UpdateNextRunForTemplatesAsync ( Func < IQueryable < Template > , IQueryable < Template > > filter , Func < IHistoryInitiator > getInitiator , string operationName )
{
var query = templateService . Get ( )
. Include ( t = > t . RobotConfigurations )
. Where ( t = > t . StatusTypeId = = TemplateStatusTypeEnum . Used ) ;
var templates = await filter ( query ) . ToListAsync ( ) ;
logger . LogInformation ( "[{operationName}] Найдено шаблонов в статусе Used для обработки: {count}" , operationName , templates . Count ) ;
if ( ! templates . Any ( ) )
{
logger . LogInformation ( "[{operationName}] Шаблоны не найдены, выходим" , operationName ) ;
return ;
}
var updatedCount = 0 ;
foreach ( var template in templates )
{
var wasUpdated = await UpdateNextRunAsync ( template ) ;
if ( wasUpdated )
updatedCount + + ;
}
if ( updatedCount = = 0 )
{
logger . LogInformation ( "[{operationName}] Нет изменённых nextRun, сохранение не требуется" , operationName ) ;
return ;
}
var initiator = getInitiator ( ) ;
var commitResult = await templateService . CommitAsync ( initiator ) ;
if ( commitResult )
logger . LogInformation ( "[{operationName}] Успешно обновлено {count} шаблонов" , operationName , updatedCount ) ;
else
logger . LogError ( "[{operationName}] Ошибка при сохранении {count} шаблонов в БД" , operationName , updatedCount ) ;
}
/// <summary>
/// Обновляет если надо nextRun для одного шаблона, если может, ставит задание на обновление
/// </summary>
/// <param name="template"></param>
/// <param name="nextRunService"></param>
/// <param name="robotConfigurationService"></param>
/// <param name="templateName"></param>
/// <param name="logger"></param>
/// <returns></returns>
private async Task < bool > UpdateNextRunAsync ( Template template )
{
var newNextRun = await nextRunService . GetNextRunForTemplateAsync ( template . Id , false ) ;
if ( ! newNextRun . HasValue )
{
logger . LogError ( "При расчете nextRun для шаблона {templateId}, '{templateName}' вернулся null. Это значит что при расчете возникла ошибка." , template . Id , template . Name ) ;
return false ;
}
if ( template . NextRun = = newNextRun . Value )
{
logger . LogDebug ( "NextRun для шаблона {templateId}, '{templateName}' не изменился: {nextRun}" , template . Id , template . Name , newNextRun . Value ) ;
return false ;
}
logger . LogInformation ( "Обновление NextRun: шаблон {templateId}, '{templateName}'. Было: {oldNextRun}, стало: {newNextRun}" , template . Id , template . Name , template . NextRun , newNextRun . Value ) ;
template . LastRun = template . NextRun ;
template . NextRun = newNextRun . Value ;
//так как nextRun обновился, пробуем поставить задание на обновление
var config = robotConfigurationService . GetFromTemplateByRobotCode ( RobotsEnum . ScheduleOrder , template ) ;
robotConfigurationService . SetUpdateTaskStatusIfAllow ( config ) ;
//шаблон изменен и нужен Commit
return true ;
}
}
}