@@ -1,6 +1,11 @@
using Microsoft.EntityFrameworkCore ;
using Microsoft.Extensions.Logging ;
using PARR.Constants ;
using PARR.DAL.DomainServices.Shortcodes ;
using PARR.DAL.Models ;
using PARR.DAL.Models.Job ;
using PARR.DAL.NextRunServices.Models ;
using PARR.DAL.NextRunServices.Subservices ;
using PARR.DAL.Services.Interfaces ;
using PARR.DAL.Services.Interfaces.Job ;
@@ -15,13 +20,15 @@ namespace PARR.DAL.NextRunServices
private readonly IJobGroupService jobGroupService ;
private readonly IEsppScheduleTransformService esppScheduleTransformService ;
private readonly ITemplateDistributor templateDistributor ;
private readonly IShortcodesService shortcodesService ;
public NextRunService (
ILogger < NextRunService > logger ,
ITemplateService templateService ,
IJobGroupService jobGroupService ,
IEsppScheduleTransformService esppScheduleTransformService ,
ITemplateDistributor templateDistributor
ITemplateDistributor templateDistributor ,
IShortcodesService shortcodesService
)
{
this . logger = logger ;
@@ -29,14 +36,94 @@ namespace PARR.DAL.NextRunServices
this . jobGroupService = jobGroupService ;
this . esppScheduleTransformService = esppScheduleTransformService ;
this . templateDistributor = templateDistributor ;
this . shortcodesService = shortcodesService ;
}
public async Task < List < ( Guid TemplateId , DateTimeOffset NextRun ) > > GetNextRunForJobGroupWithAutoDistributionAsync ( Guid jobGroupId )
public async Task < List < TemplateNextRunResultDto > ? > GetNextRunForJobGroupWithAutoDistributionAsync ( Guid jobGroupId )
{
//TODO:
throw new NotImplementedException ( ) ;
//var ditributedTemplateList = await templateDistributor.DistributeTemplatesAsync();
logger . LogInformation ( "Начинаю распределять шаблоны для группы работ {gobGroupId}" , jobGroupId ) ;
var jobGroup = await jobGroupService . Get ( )
. Include ( t = > t . DistributionConfig )
. ThenInclude ( t = > t . DistributionPeriod )
. AsNoTracking ( )
. FirstOrDefaultAsync ( t = > t . Id = = jobGroupId ) ;
if ( jobGroup = = null )
{
logger . LogError ( "Н е найдена группа работа с id: {id}" , jobGroupId ) ;
return null ;
}
if ( ! jobGroup . IsAutoDistributionEnabled | | jobGroup . DistributionConfig = = null )
{
logger . LogError ( "Группа работ id: {id} не подходит для автораспределения, у нее или отсутствуют настройки или не включено автораспределение. IsAutoDistributionEnabled: {IsAutoDistributionEnabled}. Есть конфиг: {DistributionConfig}" , jobGroupId , jobGroup . IsAutoDistributionEnabled , jobGroup . DistributionConfig ! = null ) ;
return null ;
}
logger . LogInformation ( "Параметры распределения. groupId: {groupId}, name: {groupName}, referenceDate: {referenceDate}, " +
"distributionPeriodName: {distributionPeriodName}, distributionPeriodDuration: {distributionPeriodDuration}, " +
"distributionPeriodType: {distributionPeriodType}, IsExcludeWeekends: {IsExcludeWeekends}, IsGroupingByWorkGroup: {IsGroupingByWorkGroup}" ,
jobGroupId , jobGroup . GroupName , jobGroup . ReferenceDate , jobGroup . DistributionConfig . DistributionPeriod . Name , jobGroup . DistributionConfig . DistributionPeriod . Duration , jobGroup . DistributionConfig . DistributionPeriod . Type ,
jobGroup . DistributionConfig . IsExcludeWeekends , jobGroup . DistributionConfig . IsGroupingByWorkGroup
) ;
var duration = GetDurationDays ( jobGroup . DistributionConfig ) ;
var dateStart = GetDateStart ( jobGroup . ReferenceDate ) ;
var allTemplates = await templateService . Get ( )
. Include ( t = > t . Job )
. Where ( t = > t . Job ! . GroupId = = jobGroupId )
. AsNoTracking ( )
. ToListAsync ( ) ;
if ( ! allTemplates . Any ( ) )
{
logger . LogInformation ( "В группе c ИД {jobGroupId} отсутствуют шаблоны" , jobGroupId ) ;
return null ;
}
logger . LogDebug ( "В с е г о шаблонов для распределения: {count} шт." , allTemplates . Count ) ;
var result = new List < TemplateNextRunResultDto > ( ) ;
if ( jobGroup . DistributionConfig . IsGroupingByWorkGroup )
{
// Нужно группировать по РГ
// список шаблонов с полученной из шорткода РГ
var templatesWithWorkGroup = new List < TemplateWithWorkGroupDto > ( ) ;
foreach ( var template in allTemplates )
{
var workGroupName = await shortcodesService . ApplyShortcodesAsync ( template . Job ! . WorkGroupMask , template ) ;
templatesWithWorkGroup . Add ( new TemplateWithWorkGroupDto ( template . Id , template . NextRun , workGroupName ) ) ;
}
var grouping = templatesWithWorkGroup . GroupBy ( t = > t . WorkGroup ) ;
//распределяем
foreach ( var workGroupTemplates in grouping )
{
logger . LogInformation ( "Начинаю распределять шаблоны для рабочей группы: {workGroup}. В с е г о шаблонов: {countTemplates} шт." , workGroupTemplates . Key , workGroupTemplates . Count ( ) ) ;
var templatesForDistribute = workGroupTemplates . Select ( t = > new TemplateNextRunDto ( t . Id , t . NextRun ) ) . ToList ( ) ;
var distributedResult = await templateDistributor . DistributeTemplatesAsync ( dateStart , duration , jobGroup . ReferenceDate , templatesForDistribute , jobGroup . DistributionConfig . IsExcludeWeekends ) ;
result . AddRange ( distributedResult ) ;
}
}
else
{
// Н е нужна группировка по РГ
// сразу распределяем все шаблоны
var templatesForDistribute = allTemplates . Select ( t = > new TemplateNextRunDto ( t . Id , t . NextRun ) ) . ToList ( ) ;
result = await templateDistributor . DistributeTemplatesAsync ( dateStart , duration , jobGroup . ReferenceDate , templatesForDistribute , jobGroup . DistributionConfig . IsExcludeWeekends ) ;
}
logger . LogInformation ( "Завершено распределение шаблонов для группы {jobGroupId}. В с е г о распределено шаблонов: {count} шт." , jobGroupId , result . Count ) ;
return result ;
}
@@ -81,5 +168,57 @@ namespace PARR.DAL.NextRunServices
return await esppScheduleTransformService . GetNextDateAsync ( template . Job . Group . Id , template . Job . Group . ReferenceDate ) ;
}
}
/// <summary>
/// Получить продолжительность в днях
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
private int GetDurationDays ( JobGroupDistributionConfig config )
{
var period = config . DistributionPeriod ;
var periodType = period ! . Type ;
int . TryParse ( period . Duration , out var duration ) ;
var periodDays = duration ;
if ( periodType = = DistributionPeriodTypeEnum . Day . ToString ( ) )
periodDays = duration ;
if ( periodType = = DistributionPeriodTypeEnum . Month . ToString ( ) )
// в месяце 30 дней, duration*30
periodDays = duration * 30 ;
if ( periodType = = DistributionPeriodTypeEnum . Year . ToString ( ) )
// в году 365 дней, duration*365
periodDays = duration * 365 ;
logger . LogDebug ( "Период распределения: {name}, duration: {duration}, type: {type}. Итого в днях: {days}" , period . Name , period . Duration , period . Type , periodDays ) ;
if ( periodDays = = 0 )
logger . LogWarning ( "Период распределения 0 дней. Неверный конфиг распределения в таблице {table}. {name}, duration: {duration}, type: {type}" , nameof ( DistributionPeriod ) , period . Name , period . Duration , period . Type ) ;
return periodDays ;
}
/// <summary>
/// Получить дату начала распределения
/// </summary>
/// <param name="referenceDate"></param>
/// <returns></returns>
private DateOnly GetDateStart ( DateTimeOffset referenceDate )
{
var today = DateTime . UtcNow ;
if ( today < referenceDate )
return DateOnly . FromDateTime ( referenceDate . Date ) ;
else
return DateOnly . FromDateTime ( today . Date ) ;
}
}
}