2026-01-22 11:46:05 +10:00
using Microsoft.EntityFrameworkCore ;
2025-12-22 17:03:41 +10:00
using Microsoft.Extensions.Logging ;
2026-01-21 12:19:27 +10:00
using PARR.Constants ;
2026-02-03 16:15:19 +10:00
using PARR.DAL.Contracts ;
2026-01-21 12:19:27 +10:00
using PARR.DAL.DomainServices.Shortcodes ;
using PARR.DAL.Models ;
using PARR.DAL.Models.Job ;
using PARR.DAL.NextRunServices.Models ;
2026-01-20 15:04:36 +10:00
using PARR.DAL.NextRunServices.Subservices ;
2025-12-22 17:03:41 +10:00
using PARR.DAL.Services.Interfaces ;
using PARR.DAL.Services.Interfaces.Job ;
2026-02-03 16:15:19 +10:00
using PARR.DAL.Services.Interfaces.Schedule ;
2025-12-22 17:03:41 +10:00
namespace PARR.DAL.NextRunServices
{
internal class NextRunService : INextRunService
{
private readonly ILogger < NextRunService > logger ;
private readonly ITemplateService templateService ;
private readonly IJobGroupService jobGroupService ;
private readonly IEsppScheduleTransformService esppScheduleTransformService ;
2026-01-20 15:04:36 +10:00
private readonly ITemplateDistributor templateDistributor ;
2026-01-21 12:19:27 +10:00
private readonly IShortcodesService shortcodesService ;
2026-02-03 16:15:19 +10:00
private readonly SettingsFromDb settingsFromDb ;
private readonly IScheduleResponseAreaTimeOffsetService scheduleResponseAreaTimeOffsetService ;
2025-12-22 17:03:41 +10:00
public NextRunService (
ILogger < NextRunService > logger ,
ITemplateService templateService ,
IJobGroupService jobGroupService ,
2026-01-20 15:04:36 +10:00
IEsppScheduleTransformService esppScheduleTransformService ,
2026-01-21 12:19:27 +10:00
ITemplateDistributor templateDistributor ,
2026-02-03 16:15:19 +10:00
IShortcodesService shortcodesService ,
SettingsFromDb settingsFromDb ,
IScheduleResponseAreaTimeOffsetService scheduleResponseAreaTimeOffsetService
2025-12-22 17:03:41 +10:00
)
{
this . logger = logger ;
this . templateService = templateService ;
this . jobGroupService = jobGroupService ;
this . esppScheduleTransformService = esppScheduleTransformService ;
2026-01-20 15:04:36 +10:00
this . templateDistributor = templateDistributor ;
2026-01-21 12:19:27 +10:00
this . shortcodesService = shortcodesService ;
2026-02-03 16:15:19 +10:00
this . settingsFromDb = settingsFromDb ;
this . scheduleResponseAreaTimeOffsetService = scheduleResponseAreaTimeOffsetService ;
2025-12-22 17:03:41 +10:00
}
2026-01-21 12:19:27 +10:00
public async Task < List < TemplateNextRunResultDto > ? > GetNextRunForJobGroupWithAutoDistributionAsync ( Guid jobGroupId )
2025-12-22 17:03:41 +10:00
{
2026-01-21 12:19:27 +10:00
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 ) ;
2026-01-26 14:29:47 +10:00
//получаем шаблоны только в статусе Used
2026-01-21 12:19:27 +10:00
var allTemplates = await templateService . Get ( )
. Include ( t = > t . Job )
2026-01-26 14:29:47 +10:00
. Where ( t = > t . Job ! . GroupId = = jobGroupId & & t . StatusTypeId = = TemplateStatusTypeEnum . Used )
2026-01-21 12:19:27 +10:00
. AsNoTracking ( )
. ToListAsync ( ) ;
if ( ! allTemplates . Any ( ) )
{
2026-01-26 14:29:47 +10:00
logger . LogInformation ( "В группе c ИД {jobGroupId} отсутствуют шаблоны в статусе Used" , jobGroupId ) ;
2026-01-21 12:19:27 +10:00
return null ;
}
2026-01-26 14:29:47 +10:00
logger . LogDebug ( "В с е г о шаблонов для распределения в статусе Used: {count} шт." , allTemplates . Count ) ;
2026-01-21 12:19:27 +10:00
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 ;
2025-12-22 17:03:41 +10:00
}
2026-02-05 15:41:36 +10:00
//public async Task<DateTimeOffset> GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId)
//{
// var jobGroup = await jobGroupService.Get().AsNoTracking().FirstOrDefaultAsync(t => t.Id == jobGroupId);
2026-01-23 09:28:14 +10:00
2026-02-05 15:41:36 +10:00
// if (jobGroup == null)
// {
// logger.LogError("Н е найдена группа работ с Id: {jobGroupId}.", jobGroupId);
// throw new ArgumentNullException(nameof(jobGroupId), $"Н е найдена группа работ с Id: {jobGroupId}");
// }
2026-01-23 09:28:14 +10:00
2026-02-05 15:41:36 +10:00
// // Берем из обычного расписания ЕСПП
// //return await esppScheduleTransformService.GetNextDateAsync(jobGroupId, jobGroup.ReferenceDate);
// return await GetNextRunForEsppStandardScheduleAsync(template);
//}
2026-01-21 15:36:54 +10:00
2026-02-05 15:41:36 +10:00
public async Task < DateTimeOffset > GetNextRunForNewTemplateAsync ( Guid jobGroupId , string responseArea )
2025-12-22 17:03:41 +10:00
{
2026-01-21 15:36:54 +10:00
// определяю это автораспределение или нет, вызываю соответствующий рассчет
var jobGroup = await jobGroupService . Get ( )
. Include ( t = > t . DistributionConfig )
. ThenInclude ( t = > t . DistributionPeriod )
. AsNoTracking ( )
. FirstOrDefaultAsync ( t = > t . Id = = jobGroupId ) ;
2025-12-22 17:03:41 +10:00
if ( jobGroup = = null )
{
logger . LogError ( "Н е найдена группа работ с Id: {jobGroupId}." , jobGroupId ) ;
throw new ArgumentNullException ( nameof ( jobGroupId ) , $"Н е найдена группа работ с Id: {jobGroupId}" ) ;
}
2026-01-21 15:36:54 +10:00
if ( jobGroup . IsAutoDistributionEnabled )
{
// тут автораспределение
if ( jobGroup . DistributionConfig = = null )
{
logger . LogError ( "Для группы работ {jobGroupId}, указано автораспределение, но отсутствует конфиг в таблице {GroupDistributionConfigs}" , jobGroupId , nameof ( JobGroupDistributionConfig ) ) ;
throw new ArgumentNullException ( nameof ( JobGroupDistributionConfig ) , $"Для jobGroupId: {jobGroupId} отсутствует конфигурация автораспределения в таблице {nameof(JobGroupDistributionConfig)}" ) ;
}
#region В ы н е с т и в о д т е л ь н ы й м е т о д , п о ч т и в с е п о в т о р я е т с я
var dateStart = GetDateStart ( jobGroup . ReferenceDate ) ;
var duration = GetDurationDays ( jobGroup . DistributionConfig ) ;
var result = await templateDistributor . GetValidNextRunForTemplateAsync ( dateStart ,
duration ,
jobGroup . ReferenceDate ,
new TemplateNextRunDto ( Guid . Empty , null ) ,
//TODO: тут пока не получаем список шаблонов, но позже, когда будем строить каждый раз план, нужно будет сюда передавать список связанных шаблонов
new List < TemplateNextRunDto > ( ) ,
jobGroup . DistributionConfig . IsExcludeWeekends ,
isNew : true
) ;
#endregion
logger . LogDebug ( "Получил nextRun {nextRun} по jobGroupId {jobGroupId} для нового шаблона, тип расписания: автораспределение" , result . NextRun , jobGroupId ) ;
return result . NextRun ;
}
else
{
// тут расписание ЕСПП
2026-02-05 15:41:36 +10:00
//var nextRun = await esppScheduleTransformService.GetNextDateAsync(jobGroup.Id, jobGroup.ReferenceDate);
var nextRun = await GetNextRunForEsppStandardScheduleAsync ( jobGroupId , jobGroup . ReferenceDate , jobGroup . IsResponseAreaTimezone , responseArea ) ;
2026-01-21 15:36:54 +10:00
logger . LogDebug ( "Получил nextRun {nextRun} по jobGroupId {jobGroupId}, тип расписания ЕСПП" , nextRun , jobGroupId ) ;
return nextRun ;
}
2025-12-22 17:03:41 +10:00
}
2026-01-21 15:36:54 +10:00
public async Task < DateTimeOffset > GetNextRunForTemplateAsync ( Guid templateId , bool isNew )
2025-12-22 17:03:41 +10:00
{
var template = await templateService . Get ( )
2026-01-21 15:36:54 +10:00
. Include ( t = > t . Job )
. ThenInclude ( t = > t . Group ) . ThenInclude ( t = > t . DistributionConfig ) . ThenInclude ( t = > t . DistributionPeriod )
2025-12-22 17:03:41 +10:00
. AsNoTracking ( )
. FirstOrDefaultAsync ( t = > t . Id = = templateId ) ;
if ( template = = null )
{
2026-01-21 15:36:54 +10:00
logger . LogError ( "Н е найден шаблон с Id: {templateId}." , templateId ) ;
throw new ArgumentNullException ( nameof ( templateId ) , $"Н е найден шаблон с Id: {templateId}" ) ;
2025-12-22 17:03:41 +10:00
}
if ( template . Job ! . Group ! . IsAutoDistributionEnabled = = true )
{
// включено автораспределение
2026-01-21 15:36:54 +10:00
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)}" ) ;
}
#region В ы н е с т и в о д т е л ь н ы й м е т о д , п о ч т и в с е п о в т о р я е т с я
var dateStart = GetDateStart ( template . Job ! . Group . ReferenceDate ) ;
var duration = GetDurationDays ( template . Job ! . Group . DistributionConfig ) ;
var result = await templateDistributor . GetValidNextRunForTemplateAsync ( dateStart ,
duration ,
template . Job . Group . ReferenceDate ,
new TemplateNextRunDto ( template . Id , template . NextRun ) ,
//TODO: тут пока не получаем список шаблонов, но позже, когда будем строить каждый раз план, нужно будет сюда передавать список связанных шаблонов
new List < TemplateNextRunDto > ( ) ,
template . Job . Group . DistributionConfig . IsExcludeWeekends ,
isNew
) ;
#endregion
logger . LogDebug ( "Получил nextRun {nextRun} по templateId {templateId}, isNew: {isNew}, тип расписания: автораспределение" , result . NextRun , templateId , isNew ) ;
return result . NextRun ;
2025-12-22 17:03:41 +10:00
}
else
{
// считаем как ЕСПП
2026-02-05 15:41:36 +10:00
//var offset = GetOffsetTest();
//var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job.Group.Id, template.Job.Group.ReferenceDate, offset);
//var nextRun = await GetNextRunForEsppStandardScheduleAsync(template.Job.Group.Id, template.Job.Group.ReferenceDate, template);
var responseArea = await shortcodesService . ApplyShortcodesAsync ( template . Job . ResponseAreaMask , template ) ;
var nextRun = await GetNextRunForEsppStandardScheduleAsync ( template . Job . GroupId , template . Job . Group . ReferenceDate , template . Job . Group . IsResponseAreaTimezone , responseArea ) ;
2026-01-21 15:36:54 +10:00
logger . LogDebug ( "Получил nextRun {nextRun} по templateId {templateId}, isNew: {isNew}, тип расписания: ЕСПП" , nextRun , templateId , isNew ) ;
return nextRun ;
2025-12-22 17:03:41 +10:00
}
}
2026-01-21 12:19:27 +10:00
2026-01-21 15:36:54 +10:00
2026-02-05 15:41:36 +10:00
/// <summary>
/// Расчет nextRun по расписанию ЕСПП
/// </summary>
/// <param name="jobGroupId"></param>
/// <param name="referenceDate"></param>
/// <param name="template">Template with include Job, Group</param>
/// <returns></returns>
private async Task < DateTimeOffset > GetNextRunForEsppStandardScheduleAsync ( Guid jobGroupId , DateTimeOffset referenceDate , bool isResponseAreaTimezone , string? responseArea )
{
//var isResponseAreaTimezone = template.Job?.Group?.IsResponseAreaTimezone ?? false;
//string? responseArea = null;
//if (isResponseAreaTimezone)
//{
// var responseAreaMask = template.Job!.ResponseAreaMask;
// responseArea = await shortcodesService.ApplyShortcodesAsync(responseAreaMask, template);
//}
var offset = GetTimeOffset ( isResponseAreaTimezone , responseArea ) ;
//var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template.Job!.Group!.ReferenceDate, offset);
var nextRun = await esppScheduleTransformService . GetNextDateAsync ( jobGroupId , referenceDate , offset ) ;
return nextRun ;
}
2026-01-21 15:36:54 +10:00
2026-02-09 15:48:30 +10:00
#region Ok
2026-01-21 15:36:54 +10:00
2026-01-21 12:19:27 +10:00
/// <summary>
/// Получить продолжительность в днях
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
2026-01-26 14:29:47 +10:00
public int GetDurationDays ( JobGroupDistributionConfig config )
2026-01-21 12:19:27 +10:00
{
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 ;
}
2026-02-09 15:48:30 +10:00
#endregion
2026-01-21 12:19:27 +10:00
/// <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 ) ;
}
2026-01-26 14:29:47 +10:00
2026-01-28 14:40:40 +10:00
public async Task < List < DateOnly > > GetWorkDaysAsync ( DateOnly start , DateOnly end , bool excludeWeekends , DateTimeOffset referenceDate )
2026-01-26 14:29:47 +10:00
{
2026-01-28 14:40:40 +10:00
//return await templateDistributor.GetWorkDaysAsync(start, end, excludeWeekends);
2026-01-28 16:19:19 +10:00
return await templateDistributor . GetWorkDaysV2Async ( start , end , excludeWeekends , referenceDate ) ;
2026-01-28 14:40:40 +10:00
}
public async Task < HashSet < DateOnly > > GetWeekendsAsync ( DateOnly startDate , DateOnly endDate , DateTimeOffset referenceDate )
{
2026-01-28 16:19:19 +10:00
return await templateDistributor . GetWeekendsV2Async ( startDate , endDate , referenceDate ) ;
2026-01-26 14:29:47 +10:00
}
2026-02-03 16:15:19 +10:00
public DateTimeOffset GetNextRunWithTimezoneEsppAndResponseArea ( DateTimeOffset nextRun , bool? isResponseAreaTimezone = null , string? responseArea = null )
{
2026-02-05 15:41:36 +10:00
//logger.LogDebug("Начинаю получать nextRun с учетом У З ЕСПП и З О , входные параметры: nextRun: {nextRun}, isResponseAreaTimezone: {isResponseAreaTimezone}, responseArea: {responseArea}", nextRun, isResponseAreaTimezone, responseArea);
//var esppOffset = GetEsppAccountOffset();
//// смещение У З ЕСПП
//var resultNextRun = nextRun.Add(esppOffset);
//logger.LogDebug("Смещение nextRun с учетом смещения У З ЕСПП, новое значение: {resultNextRun}", resultNextRun);
//// если включено использовать таймзону З О
//if (isResponseAreaTimezone == true && !string.IsNullOrEmpty(responseArea))
//{
// // resultNextRun = офсет У З ЕСПП - offset З О
// var responseAreaOffset = scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea).UtcTimeOffset;
// var resultOffset = esppOffset - responseAreaOffset;
// resultNextRun = resultNextRun.Add(resultOffset);
// logger.LogDebug("Смещение nextRun с учетом З О , смещение З О : {responseAreaOffset}, смещение с учетом смещения У З ЕСПП: {resultOffset}, новое значение: {resultNextRun}", responseAreaOffset, resultOffset, resultNextRun);
//}
////var resulstStr = EsppScheduleHelpers.GetNextRun(resultNextRun);
////logger.LogDebug("Результат в формате ЕСПП: {resulstStr}", resulstStr);
//return resultNextRun;
var offset = GetTimeOffset ( isResponseAreaTimezone ? ? false , responseArea ) ;
return nextRun . Add ( offset ) ;
}
private TimeSpan GetTimeOffset ( bool isResponseAreaTimezone , string? responseArea = null )
{
// logger.LogDebug("Начинаю получать nextRun с учетом У З ЕСПП и З О , входные параметры: nextRun: {nextRun}, isResponseAreaTimezone: {isResponseAreaTimezone}, responseArea: {responseArea}", nextRun, isResponseAreaTimezone, responseArea);
2026-02-03 16:15:19 +10:00
var esppOffset = GetEsppAccountOffset ( ) ;
2026-02-05 15:41:36 +10:00
logger . LogDebug ( "Получил оффсет {esppOffset}, для параметров: isResponseAreaTimezone: {isResponseAreaTimezone}, responseArea: {responseArea}" , esppOffset , isResponseAreaTimezone , responseArea ) ;
2026-02-03 16:15:19 +10:00
2026-02-05 15:41:36 +10:00
//if (isResponseAreaTimezone == true && !string.IsNullOrEmpty(responseArea))
//{
// // resultNextRun = офсет У З ЕСПП - offset З О
// var responseAreaOffset = scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea).UtcTimeOffset;
2026-02-03 16:15:19 +10:00
2026-02-05 15:41:36 +10:00
// var resultOffset = esppOffset- responseAreaOffset;
2026-02-03 16:15:19 +10:00
2026-02-05 15:41:36 +10:00
// return resultOffset;
// //logger.LogDebug("Смещение nextRun с учетом З О , смещение З О : {responseAreaOffset}, смещение с учетом смещения У З ЕСПП: {resultOffset}, новое значение: {resultNextRun}", responseAreaOffset, resultOffset, resultNextRun);
//}
return esppOffset ;
// var resultOffset =
//// смещение У З ЕСПП
//var resultNextRun = nextRun.Add(esppOffset);
//logger.LogDebug("Смещение nextRun с учетом смещения У З ЕСПП, новое значение: {resultNextRun}", resultNextRun);
//// если включено использовать таймзону З О
//if (isResponseAreaTimezone == true && !string.IsNullOrEmpty(responseArea))
//{
// // resultNextRun = офсет У З ЕСПП - offset З О
// var responseAreaOffset = scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea).UtcTimeOffset;
// var resultOffset = esppOffset - responseAreaOffset;
// resultNextRun = resultNextRun.Add(resultOffset);
// logger.LogDebug("Смещение nextRun с учетом З О , смещение З О : {responseAreaOffset}, смещение с учетом смещения У З ЕСПП: {resultOffset}, новое значение: {resultNextRun}", responseAreaOffset, resultOffset, resultNextRun);
//}
2026-02-03 16:15:19 +10:00
2026-02-05 15:41:36 +10:00
////var resulstStr = EsppScheduleHelpers.GetNextRun(resultNextRun);
////logger.LogDebug("Результат в формате ЕСПП: {resulstStr}", resulstStr);
2026-02-03 16:15:19 +10:00
2026-02-05 15:41:36 +10:00
//return resultNextRun;
2026-02-03 16:15:19 +10:00
}
2026-02-09 15:48:30 +10:00
//// был паблик
//private DateTimeOffset GetNextRunWithResponseAreaOffset(DateTimeOffset nextRun, string responseArea)
//{
// var responseAreaOffset = scheduleResponseAreaTimeOffsetService.GetByResponseAreaOrDefault(responseArea).UtcTimeOffset;
// var resulstNextRun = nextRun.Add(responseAreaOffset);
// logger.LogDebug("Смещение nextRun для З О {responseArea}, входящий: {nextRun}, смещение: {offset}, результат: {result}", responseArea, nextRun, responseAreaOffset, resulstNextRun);
2026-02-03 16:15:19 +10:00
2026-02-09 15:48:30 +10:00
// return resulstNextRun;
//}
2026-02-03 16:15:19 +10:00
/// <summary>
/// Получить смещение У З ЕСПП
/// </summary>
/// <returns></returns>
private TimeSpan GetEsppAccountOffset ( )
{
var esppOffset = new TimeSpan ( settingsFromDb . EsppRobotAccountTimeZoneHour , 0 , 0 ) ;
logger . LogDebug ( "Оффсет У З ЕСПП: {esppOffset}" , esppOffset ) ;
return esppOffset ;
}
2025-12-22 17:03:41 +10:00
}
}