feat(templateDistributor): логика распределения шаблонов по периоду
This commit is contained in:
@@ -3,6 +3,7 @@ using PARR.Constants;
|
|||||||
using PARR.DAL.Contracts;
|
using PARR.DAL.Contracts;
|
||||||
using PARR.DAL.DomainModels;
|
using PARR.DAL.DomainModels;
|
||||||
using PARR.DAL.Extensions;
|
using PARR.DAL.Extensions;
|
||||||
|
using PARR.DAL.Models;
|
||||||
using PARR.DAL.Services.Interfaces;
|
using PARR.DAL.Services.Interfaces;
|
||||||
|
|
||||||
namespace PARR.DAL.TransformServices
|
namespace PARR.DAL.TransformServices
|
||||||
@@ -10,6 +11,7 @@ namespace PARR.DAL.TransformServices
|
|||||||
internal class EsppScheduleTransformService : IEsppScheduleTransformService
|
internal class EsppScheduleTransformService : IEsppScheduleTransformService
|
||||||
{
|
{
|
||||||
private readonly IEsppSchTypeConfigService esppSchTypeConfigService;
|
private readonly IEsppSchTypeConfigService esppSchTypeConfigService;
|
||||||
|
private readonly IApplicationsInWorkService applicationsInWorkService;
|
||||||
private readonly ILogger<EsppScheduleTransformService> logger;
|
private readonly ILogger<EsppScheduleTransformService> logger;
|
||||||
|
|
||||||
private readonly Dictionary<string, int> monthDict = new Dictionary<string, int>()
|
private readonly Dictionary<string, int> monthDict = new Dictionary<string, int>()
|
||||||
@@ -49,11 +51,14 @@ namespace PARR.DAL.TransformServices
|
|||||||
};
|
};
|
||||||
|
|
||||||
public EsppScheduleTransformService(
|
public EsppScheduleTransformService(
|
||||||
|
ILogger<EsppScheduleTransformService> logger,
|
||||||
IEsppSchTypeConfigService esppSchTypeConfigService,
|
IEsppSchTypeConfigService esppSchTypeConfigService,
|
||||||
ILogger<EsppScheduleTransformService> logger
|
IApplicationsInWorkService applicationsInWorkService
|
||||||
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.esppSchTypeConfigService = esppSchTypeConfigService;
|
this.esppSchTypeConfigService = esppSchTypeConfigService;
|
||||||
|
this.applicationsInWorkService = applicationsInWorkService;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +135,9 @@ namespace PARR.DAL.TransformServices
|
|||||||
|
|
||||||
public async Task<DateTimeOffset> GetNextDateAsync(Guid applicationInWorkId, DateTimeOffset lastRun)
|
public async Task<DateTimeOffset> GetNextDateAsync(Guid applicationInWorkId, DateTimeOffset lastRun)
|
||||||
{
|
{
|
||||||
return GetNextDate(await GetEsppScheduleAsync(applicationInWorkId), lastRun);
|
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||||
|
|
||||||
|
return GetNextDate(esppSchedule, lastRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -337,10 +344,6 @@ namespace PARR.DAL.TransformServices
|
|||||||
|
|
||||||
case (DistributionPeriodTypeEnum.Year):
|
case (DistributionPeriodTypeEnum.Year):
|
||||||
return lastRun.AddYears(ParseInt(distributionPeriod));
|
return lastRun.AddYears(ParseInt(distributionPeriod));
|
||||||
|
|
||||||
//case (DistributionPeriodTypeEnum.TimeSpan):
|
|
||||||
// var timeSpan = ParseTimeSpan(distributionPeriod);
|
|
||||||
// return timeSpan.Days > 0 ? startPeriod.AddDays();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -348,6 +351,23 @@ namespace PARR.DAL.TransformServices
|
|||||||
return lastRun;
|
return lastRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<DateOnly> GetStartPeriodForDateAsync(Guid applicationInWorkId, DateTimeOffset date, DateTimeOffset refrenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
||||||
|
{
|
||||||
|
|
||||||
|
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||||
|
|
||||||
|
var currentStartPeriod = refrenceDate;
|
||||||
|
var currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod,periodType,distributionPeriod);
|
||||||
|
|
||||||
|
while (!(date>=currentStartPeriod && date< currentEndPeriod))
|
||||||
|
{
|
||||||
|
currentStartPeriod = currentEndPeriod;
|
||||||
|
currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod, periodType, distributionPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DateOnly.FromDateTime(currentStartPeriod.DateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private int ParseInt(string value)
|
private int ParseInt(string value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,5 +49,14 @@ namespace PARR.DAL.TransformServices
|
|||||||
/// <param name="distributionPeriod"></param>
|
/// <param name="distributionPeriod"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
DateTimeOffset GetNextDateForDistributionRun(DateTimeOffset lastRun, DistributionPeriodTypeEnum periodType, string distributionPeriod);
|
DateTimeOffset GetNextDateForDistributionRun(DateTimeOffset lastRun, DistributionPeriodTypeEnum periodType, string distributionPeriod);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить дату начала периода распределения относительно опорной даты (Reference Date)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="applicationInWorkId"></param>
|
||||||
|
/// <param name="date"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DateOnly> GetStartPeriodForDateAsync(Guid applicationInWorkId, DateTimeOffset date, DateTimeOffset refrenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace PARR.TemplateDistributor
|
|||||||
/// <param name="templates"></param>
|
/// <param name="templates"></param>
|
||||||
/// <param name="applicationInWorkId"></param>
|
/// <param name="applicationInWorkId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId);
|
Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId, Guid workGroupid);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновляет расписание запуска шаблонов по РР (сохраняет в БД)
|
/// Обновляет расписание запуска шаблонов по РР (сохраняет в БД)
|
||||||
|
|||||||
@@ -1,12 +1,74 @@
|
|||||||
namespace PARR.TemplateDistributor
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PARR.BLL.Domain.Mq;
|
||||||
|
using PARR.BLL.Services.Interfaces;
|
||||||
|
using PARR.TemplateDistributor.Services;
|
||||||
|
using PARR.TemplateDistributor.Settings;
|
||||||
|
|
||||||
|
namespace PARR.TemplateDistributor
|
||||||
{
|
{
|
||||||
internal class MqTemplateDistributor : IMqTemplateDistributor
|
internal class MqTemplateDistributor : IMqTemplateDistributor
|
||||||
{
|
{
|
||||||
public void Start() {
|
private readonly MqSettings mqSettings;
|
||||||
|
private readonly IMqService mqService;
|
||||||
|
private readonly ILogger<MqTemplateDistributor> logger;
|
||||||
|
private readonly ITransformService transformService;
|
||||||
|
private readonly IValidatorService validatorService;
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
// принимать TemplateDistributorMq
|
public MqTemplateDistributor(MqSettings mqSettings,
|
||||||
|
IMqService mqService,
|
||||||
|
ILogger<MqTemplateDistributor> logger,
|
||||||
|
ITransformService transformService,
|
||||||
|
IValidatorService validatorService,
|
||||||
|
IServiceProvider serviceProvider
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.mqSettings = mqSettings;
|
||||||
|
this.mqService = mqService;
|
||||||
|
this.logger = logger;
|
||||||
|
this.transformService = transformService;
|
||||||
|
this.validatorService = validatorService;
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
var isConnected = mqService.InitConsumer(mqSettings, UpdateScheduleAsync);
|
||||||
|
|
||||||
|
if (!isConnected)
|
||||||
|
throw new Exception("Ошибка при подключении к RabbitMq");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
mqService.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateScheduleAsync(string msg)
|
||||||
|
{
|
||||||
|
logger.LogInformation($"Получили запрос: {msg}");
|
||||||
|
|
||||||
|
var query = transformService.GetModelFromJson<TemplateDistributorMq>(msg);
|
||||||
|
if (query == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!await validatorService.IsValidApplicationAndWorksAsync(query.ApplicationInWorkId))
|
||||||
|
{
|
||||||
|
logger.LogError($"Некорректные параметры регалментной работы {nameof(query.ApplicationInWorkId)}: {query.ApplicationInWorkId}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var scope = serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
var service = scope.ServiceProvider.GetService<ITemplateDistributor>();
|
||||||
|
if (service == null)
|
||||||
|
throw new Exception($"Не найден сервис: {nameof(service.GetType)}");
|
||||||
|
|
||||||
|
await service.UpdateScheduleAsync(query.ApplicationInWorkId);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop() { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
PARR.TemplateDistributor/Services/IValidatorService.cs
Normal file
7
PARR.TemplateDistributor/Services/IValidatorService.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace PARR.TemplateDistributor.Services
|
||||||
|
{
|
||||||
|
internal interface IValidatorService
|
||||||
|
{
|
||||||
|
Task<bool> IsValidApplicationAndWorksAsync(Guid applicationInWorkId);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
PARR.TemplateDistributor/Services/ValidatorService.cs
Normal file
50
PARR.TemplateDistributor/Services/ValidatorService.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PARR.DAL.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace PARR.TemplateDistributor.Services
|
||||||
|
{
|
||||||
|
internal class ValidatorService : IValidatorService
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
private readonly ILogger<ValidatorService> logger;
|
||||||
|
|
||||||
|
public ValidatorService(IServiceProvider serviceProvider,
|
||||||
|
ILogger<ValidatorService> logger
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
public async Task<bool> IsValidApplicationAndWorksAsync(Guid applicationInWorkId)
|
||||||
|
{
|
||||||
|
using (var scope = serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
var service = scope.ServiceProvider.GetService<IApplicationsInWorkService>();
|
||||||
|
|
||||||
|
if (service == null)
|
||||||
|
throw new Exception($"Не найден сервис: {nameof(IApplicationsInWorkService)}");
|
||||||
|
|
||||||
|
var appInWork = await service.Get()
|
||||||
|
.Include(aiw => aiw.EsppSchValues)
|
||||||
|
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||||
|
|
||||||
|
if (appInWork == null)
|
||||||
|
{
|
||||||
|
logger.LogError($"Не найдена регалментная работа {nameof(applicationInWorkId)}: {applicationInWorkId}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appInWork.IsAutoDistributionEnabled && appInWork.EsppSchValues.Count !=1)
|
||||||
|
{
|
||||||
|
logger.LogError($"Регалментная работа {nameof(applicationInWorkId)}: {applicationInWorkId} должна иметь только одно значение EsppSchTypeValue" +
|
||||||
|
$", соответствующее режиму равномерного распределения по периоду");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,40 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PARR.BLL.Services.Interfaces;
|
||||||
|
using PARR.Constants;
|
||||||
using PARR.DAL.Models;
|
using PARR.DAL.Models;
|
||||||
using PARR.DAL.Services.Interfaces;
|
using PARR.DAL.Services.Interfaces;
|
||||||
|
using PARR.DAL.TransformServices;
|
||||||
|
|
||||||
namespace PARR.TemplateDistributor
|
namespace PARR.TemplateDistributor
|
||||||
{
|
{
|
||||||
internal class TemplateDistributor : ITemplateDistributor
|
internal class TemplateDistributor : ITemplateDistributor
|
||||||
{
|
{
|
||||||
|
private readonly ILogger<TemplateDistributor> logger;
|
||||||
|
private readonly ITemplateService templateService;
|
||||||
private readonly IApplicationsInWorkService applicationsInWorkService;
|
private readonly IApplicationsInWorkService applicationsInWorkService;
|
||||||
|
private readonly IEsppSchTypeScheduleService esppSchTypeScheduleService;
|
||||||
|
private readonly ICalendarService calendarService;
|
||||||
|
private readonly IEsppScheduleTransformService esppScheduleTransformService;
|
||||||
|
private readonly IWeekendDayService weekendDayService;
|
||||||
|
|
||||||
public TemplateDistributor(IApplicationsInWorkService applicationsInWorkService)
|
public TemplateDistributor(
|
||||||
|
ILogger<TemplateDistributor> logger,
|
||||||
|
ITemplateService templateService,
|
||||||
|
IApplicationsInWorkService applicationsInWorkService,
|
||||||
|
IEsppSchTypeScheduleService esppSchTypeScheduleService,
|
||||||
|
ICalendarService calendarService,
|
||||||
|
IEsppScheduleTransformService esppScheduleTransformService,
|
||||||
|
IWeekendDayService weekendDayService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
this.templateService = templateService;
|
||||||
this.applicationsInWorkService = applicationsInWorkService;
|
this.applicationsInWorkService = applicationsInWorkService;
|
||||||
|
this.esppSchTypeScheduleService = esppSchTypeScheduleService;
|
||||||
|
this.calendarService = calendarService;
|
||||||
|
this.esppScheduleTransformService = esppScheduleTransformService;
|
||||||
|
this.weekendDayService = weekendDayService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -20,27 +44,204 @@ namespace PARR.TemplateDistributor
|
|||||||
// группирует по РР
|
// группирует по РР
|
||||||
// -> DistributeTemplateForPeriodAsync
|
// -> DistributeTemplateForPeriodAsync
|
||||||
// сохранить в БД
|
// сохранить в БД
|
||||||
|
//applicationInWorkId = Guid.Parse("bdfefd77-bce3-4f62-a484-5042c06f4467");
|
||||||
|
|
||||||
|
var appInWork = await applicationsInWorkService.Get()
|
||||||
|
.Include(aiw => aiw.EsppSchValues)
|
||||||
|
.ThenInclude(esv => esv.EsppSchTypeValue)
|
||||||
|
.ThenInclude(etv => etv!.DistributionPeriod)
|
||||||
|
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||||
|
|
||||||
|
var templates = await templateService.Get()
|
||||||
|
.Include(t => t.Host)
|
||||||
|
.ThenInclude(h => h.WorkGroup)
|
||||||
|
.Where(t => t.ApplicationInWorkId == applicationInWorkId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
|
||||||
|
//var refDate = appInWork!.ReferenceDate;
|
||||||
|
//var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||||
|
|
||||||
|
//DistributionPeriodTypeEnum periodType = (DistributionPeriodTypeEnum)Enum.Parse(typeof(DistributionPeriodTypeEnum), period!.Type);
|
||||||
|
|
||||||
|
//var workGroupsWithTemplates = templates.GroupBy(t => new { t.Host!.WorkGroupId, t.NextRun});
|
||||||
|
var workGroupsWithTemplates = templates.GroupBy(t => t.Host!.WorkGroupId);
|
||||||
|
|
||||||
|
//var startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(applicationInWorkId, DateTimeOffset.UtcNow/*.AddDays(45)*/, refDate, periodType, period.Duration);
|
||||||
|
//var workdays = calendarService.GetWorkDatesForPeriod(startPeriod, periodType, period.Duration, weekendDayService.GetWeekends);
|
||||||
|
//var templatePerWorkDay = (int)Math.Ceiling((double)templates.Count() / workdays.Count());//
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var item in workGroupsWithTemplates)
|
||||||
|
{
|
||||||
|
var wgId = item.Key ?? Guid.NewGuid();//TODO сделать правильно
|
||||||
|
var values = item.ToList();
|
||||||
|
|
||||||
|
var distrTemplates = await DistributeTemplateAsync(values, applicationInWorkId, wgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// saveChanges
|
||||||
|
if (!await applicationsInWorkService.CommitAsync())
|
||||||
|
logger.LogError($"Ошибка записи изменений в БД при перераспределении NextRun шаблонов");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId)
|
public async Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId, Guid workGroupid)
|
||||||
|
//public async Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId)
|
||||||
{
|
{
|
||||||
//TODO: ЗАГУЛШКА переделать!
|
//TODO: ЗАГУЛШКА переделать!
|
||||||
|
|
||||||
// распределить?
|
// распределить?
|
||||||
// не распределить, NextRun = appInWork.ReferenceDate
|
// не распределить, NextRun = appInWork.ReferenceDate
|
||||||
|
|
||||||
var appInWork = await applicationsInWorkService.Get().FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
var appInWork = await applicationsInWorkService.Get()
|
||||||
if (appInWork == null)
|
.Include(aiw => aiw.EsppSchValues)
|
||||||
|
.ThenInclude(esv => esv.EsppSchTypeValue)
|
||||||
|
.ThenInclude(etv => etv!.DistributionPeriod)
|
||||||
|
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||||
|
|
||||||
|
//appInWork!.IsAutoDistributionEnabled = true;//!!!!!!!!!!!!!!!!!!!КОСТЫЛЬ пока нет связки с фронтом
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Проверяем наличие распределения РР на период
|
||||||
|
if (appInWork!.IsAutoDistributionEnabled)
|
||||||
{
|
{
|
||||||
throw new Exception("ERROROORORO!!!");
|
var existingTemplates = new List<Template>();
|
||||||
|
//Если распределенная РР получаем начало
|
||||||
|
//DateOnly startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(applicationInWorkId,DateTimeOffset.UtcNow);
|
||||||
|
var refDate = appInWork.ReferenceDate;
|
||||||
|
var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||||
|
//if(period != null) {
|
||||||
|
DistributionPeriodTypeEnum periodType = (DistributionPeriodTypeEnum)Enum.Parse(typeof(DistributionPeriodTypeEnum), period!.Type);
|
||||||
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
//periodType = DistributionPeriodTypeEnum.Day;
|
||||||
|
//period.Duration = "90";
|
||||||
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
var startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(applicationInWorkId, DateTimeOffset.UtcNow/*.AddDays(45)*/, appInWork.ReferenceDate, periodType, period.Duration);
|
||||||
|
var workdays = calendarService.GetWorkDatesForPeriod(startPeriod, periodType, period.Duration, weekendDayService.GetWeekends);
|
||||||
|
|
||||||
|
var d = new Dictionary<DateOnly, int>();
|
||||||
|
foreach (var wd in workdays)
|
||||||
|
{
|
||||||
|
var wrokDateTimeOffset = new DateTimeOffset(
|
||||||
|
wd.Year, wd.Month, wd.Day,
|
||||||
|
refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
new TimeSpan(0, 0, 0)); ;
|
||||||
|
var assignedTemplateCount = existingTemplates.Where(t => t.NextRun == wrokDateTimeOffset).Count();
|
||||||
|
d.Add(wd, assignedTemplateCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//templates = templates.Take(5).ToList();
|
||||||
|
|
||||||
templates.ForEach(t => t.NextRun = appInWork.ReferenceDate);
|
//var templatesPerStep = (int)Math.Ceiling((double)templates.Count() / workdays.Count());//
|
||||||
|
var templatesPerStep = (double)templates.Count() / workdays.Count();//
|
||||||
|
//templatesPerStep = (templatesPerStep < 1) ? 1 : templatesPerStep;
|
||||||
|
|
||||||
|
var currentDay = new DateTimeOffset(
|
||||||
|
startPeriod.Year, startPeriod.Month, startPeriod.Day,
|
||||||
|
refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
new TimeSpan(0, 0, 0)); ;
|
||||||
|
|
||||||
|
var balance = templates.Count();
|
||||||
|
var step = 0;
|
||||||
|
var stepDays = (int)Math.Floor((double)workdays.Count() / templates.Count());
|
||||||
|
stepDays = (stepDays < 1) ? 1 : stepDays;
|
||||||
|
|
||||||
|
|
||||||
|
var currentTemplateStep = (int)Math.Ceiling(templatesPerStep);
|
||||||
|
var delta = templatesPerStep - currentTemplateStep;
|
||||||
|
templates.First().NextRun = currentDay;
|
||||||
|
var templateDistributed = 0;
|
||||||
|
|
||||||
|
//Отталкиваясь от количества
|
||||||
|
while (templateDistributed < templates.Count())
|
||||||
|
{
|
||||||
|
var wdCounts = d.Select(wd => wd.Value).OrderBy(count => count).ToArray();
|
||||||
|
// = existingTemplates.Select(t => t.NextRun).OrderBy(nextRun => nextRun).Distinct().ToArray();//managers.Select(m => m.Orders.Count).OrderBy(count => count).Distinct().ToArray();
|
||||||
|
var templateCountDelta = d.Max(t => t.Value) - d.Max(t => t.Value);
|
||||||
|
var addingTemplatesCount = wdCounts.Length > 1 ?
|
||||||
|
(templateCountDelta == 0) ? (int)Math.Ceiling(templatesPerStep) : templateCountDelta :
|
||||||
|
(int)Math.Ceiling(templatesPerStep);
|
||||||
|
var workDaysWithMinTemplates = d.Where(wd => wd.Value == wdCounts[0]).ToArray();
|
||||||
|
|
||||||
|
if (workDaysWithMinTemplates.Length * addingTemplatesCount < templates.Count())
|
||||||
|
{
|
||||||
|
foreach (var wd in workDaysWithMinTemplates)
|
||||||
|
{
|
||||||
|
//Считаем DateTimeOffset, потому что у нас только дата пока
|
||||||
|
currentDay = new DateTimeOffset(
|
||||||
|
wd.Key.Year, wd.Key.Month, wd.Key.Day,
|
||||||
|
refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
new TimeSpan(0, 0, 0));
|
||||||
|
if (currentDay < DateTimeOffset.UtcNow)
|
||||||
|
currentDay = esppScheduleTransformService.GetNextDateForDistributionRun(currentDay, periodType, period.Duration);
|
||||||
|
templates.Skip(templateDistributed).Take(addingTemplatesCount).ToList().ForEach(t => t.NextRun = currentDay);
|
||||||
|
templateDistributed += addingTemplatesCount;
|
||||||
|
d[wd.Key] = wd.Value + addingTemplatesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (templateDistributed < templates.Count())
|
||||||
|
{
|
||||||
|
//var wdIndex = templateDistributed % workDaysWithMinTemplates.Length;
|
||||||
|
//var wd = workDaysWithMinTemplates[wdIndex];
|
||||||
|
|
||||||
|
var wd = d.Where(wd => wd.Value == d.Min(t => t.Value)).First();
|
||||||
|
//Считаем DateTimeOffset, потому что у нас только дата пока
|
||||||
|
currentDay = new DateTimeOffset(
|
||||||
|
wd.Key.Year, wd.Key.Month, wd.Key.Day,
|
||||||
|
refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
new TimeSpan(0, 0, 0));
|
||||||
|
if (currentDay < DateTimeOffset.UtcNow)
|
||||||
|
currentDay = esppScheduleTransformService.GetNextDateForDistributionRun(currentDay, periodType, period.Duration);
|
||||||
|
|
||||||
|
templates.Skip(templateDistributed).Take(addingTemplatesCount).ToList().ForEach(t => t.NextRun = currentDay);
|
||||||
|
d[wd.Key] = wd.Value + addingTemplatesCount;
|
||||||
|
|
||||||
|
templateDistributed += addingTemplatesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////Отталкиваясь от количества рабочих дней
|
||||||
|
//foreach (var wd in workdays)
|
||||||
|
//{
|
||||||
|
// if (currentTemplateStep > 1 && currentTemplateStep >= templatesPerStep)
|
||||||
|
// {
|
||||||
|
// var roundedCurTemplStep = (int)Math.Round(currentTemplateStep);
|
||||||
|
// //Считаем DateTimeOffset, потому что у нас только дата пока
|
||||||
|
// currentDay = new DateTimeOffset(
|
||||||
|
// wd.Year, wd.Month, wd.Day,
|
||||||
|
// refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
// new TimeSpan(0, 0, 0));
|
||||||
|
// if (currentDay < DateTimeOffset.UtcNow)
|
||||||
|
// currentDay = esppScheduleTransformService.GetNextDateForDistributionRun(currentDay, periodType, period.Duration);
|
||||||
|
|
||||||
|
// templates.Skip(templates.Count - balance).Take(roundedCurTemplStep).ToList().ForEach(t =>
|
||||||
|
// {
|
||||||
|
// t.NextRun = currentDay;
|
||||||
|
// });
|
||||||
|
// balance -= roundedCurTemplStep;
|
||||||
|
|
||||||
|
// delta = currentTemplateStep - roundedCurTemplStep;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// delta = currentTemplateStep;
|
||||||
|
|
||||||
|
// currentTemplateStep = delta + templatesPerStep;
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
templates.ForEach(t => t.NextRun = appInWork!.ReferenceDate);
|
||||||
|
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PARR.BLL;
|
using PARR.BLL;
|
||||||
using PARR.DAL;
|
using PARR.DAL;
|
||||||
|
using PARR.TemplateDistributor.Services;
|
||||||
using PARR.TemplateDistributor.Settings;
|
using PARR.TemplateDistributor.Settings;
|
||||||
|
|
||||||
namespace PARR.TemplateDistributor
|
namespace PARR.TemplateDistributor
|
||||||
@@ -19,6 +20,7 @@ namespace PARR.TemplateDistributor
|
|||||||
|
|
||||||
services.AddTransient<ITemplateDistributor, TemplateDistributor>();
|
services.AddTransient<ITemplateDistributor, TemplateDistributor>();
|
||||||
services.AddTransient<IMqTemplateDistributor, MqTemplateDistributor>();
|
services.AddTransient<IMqTemplateDistributor, MqTemplateDistributor>();
|
||||||
|
services.AddTransient<IValidatorService,ValidatorService>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user