feat(templateDistributor): Изменен метод распределения РР по периоду(DistributeTemplateAsync), EsppScheduleTransformService.GetNextDateAsync теперь проверяет метод распределения РР и возвращает нужную дату
This commit is contained in:
@@ -3,7 +3,6 @@ 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
|
||||||
@@ -135,8 +134,18 @@ namespace PARR.DAL.TransformServices
|
|||||||
|
|
||||||
public async Task<DateTimeOffset> GetNextDateAsync(Guid applicationInWorkId, DateTimeOffset lastRun)
|
public async Task<DateTimeOffset> GetNextDateAsync(Guid applicationInWorkId, DateTimeOffset lastRun)
|
||||||
{
|
{
|
||||||
|
var appInWork = await applicationsInWorkService.GetAsync(applicationInWorkId);
|
||||||
|
|
||||||
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||||
|
|
||||||
|
if (appInWork!.IsAutoDistributionEnabled)
|
||||||
|
{
|
||||||
|
var period = esppSchedule!.Values.FirstOrDefault()!.Value!.DistributionPeriod;
|
||||||
|
var periodType = ParseDistributionPeriodType(period!.Type);
|
||||||
|
|
||||||
|
return GetNextDateForDistributionRun(lastRun, periodType, period.Duration);
|
||||||
|
}
|
||||||
|
|
||||||
return GetNextDate(esppSchedule, lastRun);
|
return GetNextDate(esppSchedule, lastRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,23 +355,46 @@ namespace PARR.DAL.TransformServices
|
|||||||
return lastRun.AddYears(ParseInt(distributionPeriod));
|
return lastRun.AddYears(ParseInt(distributionPeriod));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//return startPeriod.AddDays(duration.Days).AddDays(-1);
|
|
||||||
return lastRun;
|
return lastRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DateOnly> GetStartPeriodForDateAsync(Guid applicationInWorkId, DateTimeOffset date, DateTimeOffset refrenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
private DateTimeOffset GetPrevDateForDistributionRun(DateTimeOffset lastRun, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
||||||
|
{
|
||||||
|
switch (periodType)
|
||||||
|
{
|
||||||
|
case (DistributionPeriodTypeEnum.Day):
|
||||||
|
return lastRun.AddDays(-ParseInt(distributionPeriod));
|
||||||
|
|
||||||
|
case (DistributionPeriodTypeEnum.Month):
|
||||||
|
return lastRun.AddMonths(-ParseInt(distributionPeriod));
|
||||||
|
|
||||||
|
case (DistributionPeriodTypeEnum.Year):
|
||||||
|
return lastRun.AddYears(-ParseInt(distributionPeriod));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DateOnly> GetStartPeriodForDateAsync(Guid applicationInWorkId, DateTimeOffset date, DateTimeOffset referenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
||||||
{
|
{
|
||||||
|
|
||||||
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||||
|
|
||||||
var currentStartPeriod = refrenceDate;
|
var currentStartPeriod = referenceDate;
|
||||||
var currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod,periodType,distributionPeriod);
|
var currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod, periodType, distributionPeriod);
|
||||||
|
|
||||||
while (!(date>=currentStartPeriod && date< currentEndPeriod))
|
while (!(date >= currentStartPeriod && date < currentEndPeriod))
|
||||||
{
|
{
|
||||||
currentStartPeriod = currentEndPeriod;
|
if (date > currentEndPeriod)
|
||||||
currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod, periodType, distributionPeriod);
|
{
|
||||||
|
currentStartPeriod = currentEndPeriod;
|
||||||
|
currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod, periodType, distributionPeriod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentEndPeriod = currentStartPeriod;
|
||||||
|
currentStartPeriod = GetPrevDateForDistributionRun(currentStartPeriod, periodType, distributionPeriod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateOnly.FromDateTime(currentStartPeriod.DateTime);
|
return DateOnly.FromDateTime(currentStartPeriod.DateTime);
|
||||||
@@ -381,5 +413,12 @@ namespace PARR.DAL.TransformServices
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DistributionPeriodTypeEnum ParseDistributionPeriodType(string value)
|
||||||
|
{
|
||||||
|
var result = (DistributionPeriodTypeEnum)Enum.Parse(typeof(DistributionPeriodTypeEnum), value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ namespace PARR.TemplateDistributor
|
|||||||
// сохранить в БД
|
// сохранить в БД
|
||||||
//applicationInWorkId = Guid.Parse("bdfefd77-bce3-4f62-a484-5042c06f4467");
|
//applicationInWorkId = Guid.Parse("bdfefd77-bce3-4f62-a484-5042c06f4467");
|
||||||
|
|
||||||
var appInWork = await applicationsInWorkService.Get()
|
//var appInWork = await applicationsInWorkService.Get()
|
||||||
.Include(aiw => aiw.EsppSchValues)
|
// .Include(aiw => aiw.EsppSchValues)
|
||||||
.ThenInclude(esv => esv.EsppSchTypeValue)
|
// .ThenInclude(esv => esv.EsppSchTypeValue)
|
||||||
.ThenInclude(etv => etv!.DistributionPeriod)
|
// .ThenInclude(etv => etv!.DistributionPeriod)
|
||||||
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
// .FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||||
|
|
||||||
var templates = await templateService.Get()
|
var templates = await templateService.Get()
|
||||||
.Include(t => t.Host)
|
.Include(t => t.Host)
|
||||||
@@ -59,23 +59,15 @@ namespace PARR.TemplateDistributor
|
|||||||
.ToListAsync();
|
.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 workGroupsWithTemplates = templates.GroupBy(t => t.Host!.WorkGroupId);
|
||||||
|
|
||||||
//var startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(applicationInWorkId, DateTimeOffset.UtcNow/*.AddDays(45)*/, refDate, periodType, period.Duration);
|
foreach (var workGroupWithTemplates in workGroupsWithTemplates)
|
||||||
//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 wgId = workGroupWithTemplates.Key ?? Guid.NewGuid();//TODO сделать правильно
|
||||||
var values = item.ToList();
|
var values = workGroupWithTemplates.ToList();
|
||||||
|
|
||||||
|
if (!values.Any())
|
||||||
|
continue;
|
||||||
|
|
||||||
var distrTemplates = await DistributeTemplateAsync(values, applicationInWorkId, wgId);
|
var distrTemplates = await DistributeTemplateAsync(values, applicationInWorkId, wgId);
|
||||||
}
|
}
|
||||||
@@ -86,153 +78,132 @@ namespace PARR.TemplateDistributor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId, Guid workGroupid)
|
public async Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId, Guid workGroupId)
|
||||||
{
|
{
|
||||||
//TODO: ЗАГУЛШКА переделать!
|
|
||||||
|
|
||||||
// распределить?
|
|
||||||
// не распределить, NextRun = appInWork.ReferenceDate
|
|
||||||
|
|
||||||
var appInWork = await applicationsInWorkService.Get()
|
var appInWork = await applicationsInWorkService.Get()
|
||||||
.Include(aiw => aiw.EsppSchValues)
|
.Include(aiw => aiw.EsppSchValues)
|
||||||
.ThenInclude(esv => esv.EsppSchTypeValue)
|
.ThenInclude(esv => esv.EsppSchTypeValue)
|
||||||
.ThenInclude(etv => etv!.DistributionPeriod)
|
.ThenInclude(etv => etv!.DistributionPeriod)
|
||||||
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||||
|
var refDate = appInWork!.ReferenceDate;
|
||||||
//appInWork!.IsAutoDistributionEnabled = true;//!!!!!!!!!!!!!!!!!!!КОСТЫЛЬ пока нет связки с фронтом
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Проверяем наличие распределения РР на период
|
//Проверяем наличие распределения РР на период
|
||||||
if (appInWork!.IsAutoDistributionEnabled)
|
if (appInWork!.IsAutoDistributionEnabled)
|
||||||
{
|
{
|
||||||
var existingTemplates = new List<Template>();
|
var existingTemplates = await templateService.Get()
|
||||||
|
.Include(t => t.Host)
|
||||||
|
.Where(t => t.ApplicationInWorkId == applicationInWorkId && t.Host!.WorkGroupId == workGroupId)
|
||||||
|
.ToListAsync();
|
||||||
//Если распределенная РР получаем начало
|
//Если распределенная РР получаем начало
|
||||||
//DateOnly startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(applicationInWorkId,DateTimeOffset.UtcNow);
|
|
||||||
var refDate = appInWork.ReferenceDate;
|
|
||||||
var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||||
//if(period != null) {
|
var periodType = ParseDistributionPeriodType(period!.Type);
|
||||||
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 = await GetWorkDaysAsync(appInWork);
|
||||||
var workdays = calendarService.GetWorkDatesForPeriod(startPeriod, periodType, period.Duration, weekendDayService.GetWeekends);
|
|
||||||
|
|
||||||
var d = new Dictionary<DateOnly, int>();
|
//Готовим план распределения
|
||||||
foreach (var wd in workdays)
|
var distrPlan = GetDistributionPlan(workDays, templates.Count + existingTemplates.Count);
|
||||||
|
|
||||||
|
var templateToDistrib = new List<Template>();
|
||||||
|
|
||||||
|
if (existingTemplates.Count > 0)
|
||||||
|
templates = GetTemplatesToDistribute(ref distrPlan, existingTemplates);
|
||||||
|
|
||||||
|
templateToDistrib.AddRange(templates);
|
||||||
|
|
||||||
|
var distributedTemplates = 0;
|
||||||
|
|
||||||
|
foreach (var workDay in distrPlan)
|
||||||
{
|
{
|
||||||
var wrokDateTimeOffset = new DateTimeOffset(
|
var templatesCountForCurDay = workDay.Value;
|
||||||
wd.Year, wd.Month, wd.Day,
|
|
||||||
refDate.Hour, refDate.Minute, refDate.Second,
|
templateToDistrib.Skip(distributedTemplates).Take(templatesCountForCurDay).ToList().ForEach(t =>
|
||||||
new TimeSpan(0, 0, 0)); ;
|
{
|
||||||
var assignedTemplateCount = existingTemplates.Where(t => t.NextRun == wrokDateTimeOffset).Count();
|
var nextRun = new DateTimeOffset(
|
||||||
d.Add(wd, assignedTemplateCount);
|
workDay.Key.Year, workDay.Key.Month, workDay.Key.Day,
|
||||||
|
refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
new TimeSpan(0, 0, 0));
|
||||||
|
if (nextRun < DateTimeOffset.UtcNow)
|
||||||
|
nextRun = esppScheduleTransformService.GetNextDateForDistributionRun(nextRun, periodType, period.Duration);
|
||||||
|
|
||||||
|
t.NextRun = nextRun;
|
||||||
|
});
|
||||||
|
|
||||||
|
distributedTemplates += templatesCountForCurDay;
|
||||||
}
|
}
|
||||||
|
|
||||||
//templates = templates.Take(5).ToList();
|
return templateToDistrib;
|
||||||
|
|
||||||
//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;
|
|
||||||
|
|
||||||
//Отталкиваясь от количества
|
//var d = new Dictionary<DateOnly, List<Template>>();
|
||||||
while (templateDistributed < templates.Count())
|
//foreach (var wd in workDays)
|
||||||
{
|
|
||||||
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 wrokDateTimeOffset = new DateTimeOffset(
|
||||||
// {
|
// wd.Year, wd.Month, wd.Day,
|
||||||
// var roundedCurTemplStep = (int)Math.Round(currentTemplateStep);
|
// refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
// //Считаем DateTimeOffset, потому что у нас только дата пока
|
// new TimeSpan(0, 0, 0));
|
||||||
// currentDay = new DateTimeOffset(
|
// if (wrokDateTimeOffset < DateTimeOffset.UtcNow)
|
||||||
// wd.Year, wd.Month, wd.Day,
|
// wrokDateTimeOffset = esppScheduleTransformService.GetNextDateForDistributionRun(wrokDateTimeOffset, periodType, period.Duration);
|
||||||
// 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 =>
|
// var assignedTemplates = existingTemplates.Where(t => t.NextRun == wrokDateTimeOffset).ToList();
|
||||||
// {
|
// d.Add(wd, assignedTemplates);
|
||||||
// t.NextRun = currentDay;
|
|
||||||
// });
|
|
||||||
// balance -= roundedCurTemplStep;
|
|
||||||
|
|
||||||
// delta = currentTemplateStep - roundedCurTemplStep;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// delta = currentTemplateStep;
|
|
||||||
|
|
||||||
// currentTemplateStep = delta + templatesPerStep;
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
//var templatesPerStep = (double)templates.Count() / workDays.Count();//
|
||||||
|
//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();
|
||||||
|
// var templateCountDelta = d.Max(t => t.Value.Count()) - d.Min(t => t.Value.Count());
|
||||||
|
// 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, потому что у нас только дата пока
|
||||||
|
// var currentDay = new DateTimeOffset(
|
||||||
|
// wd.Key.Year, wd.Key.Month, wd.Key.Day,
|
||||||
|
// refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
// new TimeSpan(0, 0, 0));
|
||||||
|
|
||||||
|
// templates.Skip(templateDistributed).Take(addingTemplatesCount).ToList().ForEach(t =>
|
||||||
|
// {
|
||||||
|
// t.NextRun = currentDay;
|
||||||
|
// d[wd.Key].Add(t);
|
||||||
|
// });
|
||||||
|
// templateDistributed += addingTemplatesCount;
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// while (templateDistributed < templates.Count())
|
||||||
|
// {
|
||||||
|
// var wd = d.Where(wd => wd.Value == d.Min(t => t.Value)).First();
|
||||||
|
// //Считаем DateTimeOffset, потому что у нас только дата пока
|
||||||
|
// var currentDay = new DateTimeOffset(
|
||||||
|
// wd.Key.Year, wd.Key.Month, wd.Key.Day,
|
||||||
|
// refDate.Hour, refDate.Minute, refDate.Second,
|
||||||
|
// new TimeSpan(0, 0, 0));
|
||||||
|
|
||||||
|
// templates.Skip(templateDistributed).Take(addingTemplatesCount).ToList().ForEach(t =>
|
||||||
|
// {
|
||||||
|
// t.NextRun = currentDay;
|
||||||
|
// d[wd.Key].Add(t);
|
||||||
|
// });
|
||||||
|
// templateDistributed += addingTemplatesCount;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
templates.ForEach(t => t.NextRun = appInWork!.ReferenceDate);
|
templates.ForEach(t => t.NextRun = appInWork!.ReferenceDate);
|
||||||
@@ -240,6 +211,104 @@ namespace PARR.TemplateDistributor
|
|||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<List<DateOnly>> GetWorkDaysAsync(ApplicationsInWork appInWork)
|
||||||
|
{
|
||||||
|
|
||||||
|
var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||||
|
var periodType = ParseDistributionPeriodType(period!.Type);
|
||||||
|
var startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(appInWork.Id, appInWork.ReferenceDate, appInWork.ReferenceDate, periodType, period.Duration);
|
||||||
|
|
||||||
|
var result = calendarService.GetWorkDatesForPeriod(startPeriod, periodType, period.Duration, weekendDayService.GetWeekends);
|
||||||
|
|
||||||
|
result.ForEach(wd =>
|
||||||
|
{
|
||||||
|
var wrokDateTimeOffset = new DateTimeOffset(
|
||||||
|
wd.Year, wd.Month, wd.Day,
|
||||||
|
0, 0, 0,
|
||||||
|
new TimeSpan(0, 0, 0));
|
||||||
|
if (wrokDateTimeOffset < DateTimeOffset.UtcNow)
|
||||||
|
{
|
||||||
|
wrokDateTimeOffset = esppScheduleTransformService.GetNextDateForDistributionRun(wrokDateTimeOffset, periodType, period.Duration);
|
||||||
|
wd = DateOnly.FromDateTime(wrokDateTimeOffset.DateTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<Template> GetTemplatesToDistribute(ref Dictionary<DateOnly, int> distributionPlan, List<Template> templates)
|
||||||
|
{
|
||||||
|
var result = new List<Template>();
|
||||||
|
|
||||||
|
foreach (var wd in distributionPlan)
|
||||||
|
{
|
||||||
|
var templatesInWd = templates.Where(t => DateOnly.FromDateTime(t.NextRun.DateTime) == wd.Key).ToList();
|
||||||
|
|
||||||
|
var templatesToDistribute = templatesInWd.Skip(wd.Value).Take(templatesInWd.Count - wd.Value).ToList();
|
||||||
|
|
||||||
|
distributionPlan[wd.Key] -= templatesInWd.Count;
|
||||||
|
|
||||||
|
result.AddRange(templatesToDistribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DistributionPeriodTypeEnum ParseDistributionPeriodType(string value)
|
||||||
|
{
|
||||||
|
var result = (DistributionPeriodTypeEnum)Enum.Parse(typeof(DistributionPeriodTypeEnum), value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Dictionary<DateOnly, int> GetDistributionPlan(List<DateOnly> workDays, int templateCount)
|
||||||
|
{
|
||||||
|
var d = new Dictionary<DateOnly, int>();
|
||||||
|
foreach (var wd in workDays)
|
||||||
|
{
|
||||||
|
var workDateTimeOffset = new DateOnly(wd.Year, wd.Month, wd.Day);
|
||||||
|
d.Add(workDateTimeOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var templateDistributed = 0;
|
||||||
|
|
||||||
|
if (templateCount > workDays.Count)
|
||||||
|
{
|
||||||
|
var mainPartTemplateCountToDistribute = templateCount / workDays.Count;
|
||||||
|
foreach (var item in d)
|
||||||
|
{
|
||||||
|
d[item.Key] = mainPartTemplateCountToDistribute;
|
||||||
|
|
||||||
|
templateDistributed += mainPartTemplateCountToDistribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var templatesPerWorkDay = (double)workDays.Count / (templateCount % workDays.Count);
|
||||||
|
var currentStep = (double)Math.Floor(templatesPerWorkDay);//??????? точно double?
|
||||||
|
var balance = (double)templatesPerWorkDay - Math.Floor(currentStep);
|
||||||
|
var currentIndex = 0;
|
||||||
|
|
||||||
|
while (templateDistributed < templateCount)
|
||||||
|
{
|
||||||
|
if (currentStep > 0)
|
||||||
|
{
|
||||||
|
d[d.ElementAt(currentIndex).Key] += 1;
|
||||||
|
templateDistributed++;
|
||||||
|
currentIndex += (int)Math.Floor(currentStep);
|
||||||
|
|
||||||
|
currentStep = templatesPerWorkDay + balance;
|
||||||
|
balance = currentStep - templatesPerWorkDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user