feat(all): ! Критические изменения логики работы всех сервисорв, База Данных имееет неокончательную версию. Template, Scheduler переведены на работу с Unit+Job+JobGroup вместо Host+ApplicationsInWork
This commit is contained in:
17
PARR.API/Contracts/V1/Responses/JobBaseResponse.cs
Normal file
17
PARR.API/Contracts/V1/Responses/JobBaseResponse.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace PARR.API.Contracts.V1.Responses
|
||||
{
|
||||
public class JobBaseResponse
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
|
||||
public required string TemplateNameMask { get; set; }
|
||||
public TnkResponse? Tnk { get; set; }
|
||||
}
|
||||
|
||||
public class JobResponse : JobBaseResponse
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
public required string TnkEsppId { get; set; }
|
||||
|
||||
public required string WorkName { get; set; }
|
||||
public required string WorkEsppId { get; set; }
|
||||
//public required string WorkEsppId { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
public class StatHostTemplateResponse
|
||||
{
|
||||
public int AllHosts { get; set; }
|
||||
public int AllUnits { get; set; }
|
||||
public int HostsInTemplates { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
|
||||
public bool IsAutoDistributionEnabled { get; set; }
|
||||
|
||||
public HostTemplateResponse? Host { get; set; }
|
||||
//public HostTemplateResponse? Host { get; set; }
|
||||
public UnitBaseResponse? Unit { get; set; }
|
||||
|
||||
public WorkResponse? Work { get; set; }
|
||||
public JobBaseResponse? Job { get; set; }
|
||||
|
||||
//public WorkResponse? Work { get; set; }
|
||||
public ProcessResponse? Process { get; set; }
|
||||
public SubprocessResponse? Subprocess { get; set; }
|
||||
public TnkResponse? Tnk { get; set; }
|
||||
|
||||
@@ -22,15 +22,4 @@
|
||||
public List<AttributeResponse>? Attributes { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ using PARR.Constants;
|
||||
using PARR.DAL.DomainModels;
|
||||
using PARR.DAL.Models;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
using PARR.DAL.Services.Interfaces.Unit;
|
||||
|
||||
namespace PARR.API.Controllers.V1
|
||||
{
|
||||
@@ -29,6 +30,7 @@ namespace PARR.API.Controllers.V1
|
||||
private readonly IMapper mapper;
|
||||
private readonly ITemplateService templateService;
|
||||
private readonly IClientService clientService;
|
||||
private readonly IUnitService unitService;
|
||||
private readonly ILogger<AgentHistoryController> logger;
|
||||
|
||||
public AgentHistoryController(
|
||||
@@ -38,6 +40,7 @@ namespace PARR.API.Controllers.V1
|
||||
IMapper mapper,
|
||||
ITemplateService templateService,
|
||||
IClientService clientService,
|
||||
IUnitService unitService,
|
||||
ILogger<AgentHistoryController> logger
|
||||
)
|
||||
{
|
||||
@@ -47,6 +50,7 @@ namespace PARR.API.Controllers.V1
|
||||
this.mapper = mapper;
|
||||
this.templateService = templateService;
|
||||
this.clientService = clientService;
|
||||
this.unitService = unitService;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@@ -121,16 +125,22 @@ namespace PARR.API.Controllers.V1
|
||||
|
||||
|
||||
var clientIp = clientService.GetClientIp()?.ToString();
|
||||
var template = await templateService.Get().Include(t => t.Host).FirstOrDefaultAsync(t => t.Id == request.TemplateId);
|
||||
var template = await templateService.Get()
|
||||
.Include(t => t.Unit)
|
||||
.ThenInclude(t => t!.UnitValues)
|
||||
|
||||
.FirstOrDefaultAsync(t => t.Id == request.TemplateId);
|
||||
|
||||
if (template == null)
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { FieldName = nameof(request.TemplateId), Message = $"Не найден шаблон с Id: {request.TemplateId}" } }));
|
||||
|
||||
//проверять что этот этот шаблон привязан к этому серверу по ip
|
||||
if (template.Host?.IP != clientIp)
|
||||
var unit = await unitService.GetWithIncludes().AsNoTracking().FirstOrDefaultAsync(t => t.Id == template.UnitId);
|
||||
var unitIp = unit?.UnitValues.FirstOrDefault(t => t.Field!.AihitName == "IP_АДРЕС")!.Value!.Value;
|
||||
if (unitIp != clientIp)
|
||||
{
|
||||
logger.LogWarning($"Клиент с ip: {clientIp} пытается записать историю агента для templateId: {request.TemplateId}, " +
|
||||
$"но у шаблона ip: {template.Host?.IP}, доступ запрещен так как их ip не равны.");
|
||||
$"но у шаблона ip: {unitIp}, доступ запрещен так как их ip не равны.");
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using PARR.API.Services.Interfaces;
|
||||
using PARR.Constants;
|
||||
using PARR.DAL.Contracts;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
using PARR.DAL.Services.Interfaces.Unit;
|
||||
using PARR.DAL.TransformServices;
|
||||
|
||||
namespace PARR.API.Controllers.V1
|
||||
@@ -22,18 +23,21 @@ namespace PARR.API.Controllers.V1
|
||||
{
|
||||
private readonly IClientService clientService;
|
||||
private readonly ITemplateService templateService;
|
||||
private readonly IUnitService unitService;
|
||||
private readonly IEsppScheduleTransformService esppScheduleTransformService;
|
||||
private readonly ILogger<AgentTaskController> logger;
|
||||
|
||||
public AgentTaskController(
|
||||
IClientService clientService,
|
||||
ITemplateService templateService,
|
||||
IUnitService unitService,
|
||||
IEsppScheduleTransformService esppScheduleTransformService,
|
||||
ILogger<AgentTaskController> logger
|
||||
)
|
||||
{
|
||||
this.clientService = clientService;
|
||||
this.templateService = templateService;
|
||||
this.unitService = unitService;
|
||||
this.esppScheduleTransformService = esppScheduleTransformService;
|
||||
this.logger = logger;
|
||||
}
|
||||
@@ -62,19 +66,21 @@ namespace PARR.API.Controllers.V1
|
||||
//Агент получает задания, если `IsAgent = true`, шаблон и расписания активны, и статус синхронизации шаблона и расписания `= Ok`, и `NextRun = сегодня`, так же если у ApplicationInWork есть расписание.
|
||||
|
||||
// С одним IP может быть несколько информационных систем, так что может быть несколько хостов
|
||||
var units = await unitService.GetWithIncludes().AsNoTracking().Where(t => t.UnitValues.Any(v => v.Field!.AihitName == "IP_АДРЕС" && v.Value!.Value == ip)).ToListAsync();
|
||||
var templates = await templateService.Get()
|
||||
.Include(t => t.RobotConfigurations)
|
||||
.Include(t => t.ApplicationsInWork)
|
||||
.Include(t => t.Job)
|
||||
.ThenInclude(t=>t!.Group)
|
||||
.ThenInclude(t => t!.EsppSchValues)
|
||||
.Include(t => t.Host)
|
||||
.Where(t => t.Host!.IP == ip
|
||||
&& t.ApplicationsInWork!.IsAgent == true
|
||||
.Include(t => t.Unit)
|
||||
.Where(t => units.Any(u=>u.Id == t.UnitId)
|
||||
//&& t.ApplicationsInWork!.IsAgent == true//TODO Migration to job
|
||||
&& t.IsActiveTemplate == true
|
||||
&& t.IsActiveSchedule == true
|
||||
//&& t.ApplicationsInWork!.NextRun.DateTime.Date == date.Date.Date
|
||||
&& t.NextRun.DateTime.Date == date.Date.Date
|
||||
&& t.RobotConfigurations.All(c => c.TaskStatusCode == (int)TaskStatusEnum.Ok)
|
||||
&& t.ApplicationsInWork.EsppSchValues.Any()
|
||||
&& t.Job!.Group!.EsppSchValues.Any()//.ApplicationsInWork.EsppSchValues.Any()
|
||||
).ToListAsync();
|
||||
|
||||
if (!templates.Any())
|
||||
@@ -88,26 +94,26 @@ namespace PARR.API.Controllers.V1
|
||||
foreach (var template in templates)
|
||||
{
|
||||
//var templateSchedule = await esppScheduleTransformService.GetNextScheduleAsync(template.ApplicationInWorkId, template.ApplicationsInWork!.LastRun ?? template.ApplicationsInWork!.NextRun);
|
||||
var templateSchedule = await esppScheduleTransformService.GetNextScheduleAsync(template.ApplicationInWorkId, template.NextRun);
|
||||
var templateSchedule = await esppScheduleTransformService.GetNextScheduleAsync(template.Job!.GroupId, template.NextRun);
|
||||
|
||||
if (!templateSchedule.Any())
|
||||
{
|
||||
logger.LogWarning($"Запросили раписание для агента по NextRun и вернулся пустой список! Такого не должно быть! " +
|
||||
$"ApplicationInWorkId: {template.ApplicationInWorkId}, latRun: {template.LastRun}, NextRun: {template.NextRun}, ip: {ip}, date: {date}");
|
||||
$"JobGroupId: {template.Job.GroupId}, latRun: {template.LastRun}, NextRun: {template.NextRun}, ip: {ip}, date: {date}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(template.ApplicationsInWork.AgentName) && string.IsNullOrEmpty(template.ApplicationsInWork.AgentScript))
|
||||
if (string.IsNullOrEmpty(template.Job.Group!.AgentName) && string.IsNullOrEmpty(template.Job.Group!.AgentScript))
|
||||
{
|
||||
logger.LogWarning($"Запросили задание для агента с пустыми значениями AgentName && AgentScript. Такого не должно быть! " +
|
||||
$"ApplicationInWorkId: {template.ApplicationInWorkId}, AgentName: {template.ApplicationsInWork.AgentName}, AgentScript: {template.ApplicationsInWork.AgentScript} , ip: {ip}, date: {date}");
|
||||
$"JobGroupId: {template.Job.GroupId}, AgentName: {template.Job.Group.AgentName}, AgentScript: {template.Job.Group.AgentScript} , ip: {ip}, date: {date}");
|
||||
continue;
|
||||
}
|
||||
|
||||
templateSchedule.ForEach(item => response.Scheduled.Add(new AgentTaskMinScheduleResponse
|
||||
{
|
||||
Name = template.ApplicationsInWork!.AgentName ?? "",
|
||||
Script = template.ApplicationsInWork!.AgentScript ?? "",
|
||||
Name = template.Job.Group.AgentName ?? "",
|
||||
Script = template.Job.Group.AgentScript ?? "",
|
||||
StartAt = item,
|
||||
TemplateId = template.Id
|
||||
}));
|
||||
|
||||
@@ -62,53 +62,53 @@ namespace PARR.API.Controllers.V1
|
||||
/// Получить список заданий на выполнение работ(ApplicationInWork) постранично
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.Job.GetAll)]
|
||||
public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] ApplicationInWorkQuery filter)
|
||||
{
|
||||
var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
|
||||
//[HttpGet(ApiRoutes.Job.GetAll)]
|
||||
//public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] ApplicationInWorkQuery filter)
|
||||
//{
|
||||
// var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
|
||||
|
||||
IQueryable<ApplicationsInWork> query = applicationsInWorkService.Get().Include(t => t.Application).ThenInclude(t => t!.ApplicationType);
|
||||
// IQueryable<ApplicationsInWork> query = applicationsInWorkService.Get().Include(t => t.Application).ThenInclude(t => t!.ApplicationType);
|
||||
|
||||
if (filter.IsLight != true)
|
||||
{
|
||||
query = query
|
||||
.Include(t => t.Work)
|
||||
//.Include(t => t.Templates) - большой запрос, делаем его отдельно
|
||||
.Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
.Include(t => t.JobAutoControl);
|
||||
}
|
||||
// if (filter.IsLight != true)
|
||||
// {
|
||||
// query = query
|
||||
// .Include(t => t.Work)
|
||||
// //.Include(t => t.Templates) - большой запрос, делаем его отдельно
|
||||
// .Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
// .Include(t => t.JobAutoControl);
|
||||
// }
|
||||
|
||||
query = query.OrderBy(t => t.ShortDescription).ThenBy(t => t.Application!.Name);
|
||||
// query = query.OrderBy(t => t.ShortDescription).ThenBy(t => t.Application!.Name);
|
||||
|
||||
if (!string.IsNullOrEmpty(filter.ShortDescription))
|
||||
query = query.Where(t => t.ShortDescription.ToLower().Contains(filter.ShortDescription.ToLower()));
|
||||
// if (!string.IsNullOrEmpty(filter.ShortDescription))
|
||||
// query = query.Where(t => t.ShortDescription.ToLower().Contains(filter.ShortDescription.ToLower()));
|
||||
|
||||
if (filter.WorkId.HasValue)
|
||||
query = query.Where(t => t.WorkId == filter.WorkId.Value);
|
||||
// if (filter.WorkId.HasValue)
|
||||
// query = query.Where(t => t.WorkId == filter.WorkId.Value);
|
||||
|
||||
var appInWorks = await applicationsInWorkService.GetPage(query, paginationFilter).ToListAsync();
|
||||
// var appInWorks = await applicationsInWorkService.GetPage(query, paginationFilter).ToListAsync();
|
||||
|
||||
if (!appInWorks.Any())
|
||||
return NoContent();
|
||||
// if (!appInWorks.Any())
|
||||
// return NoContent();
|
||||
|
||||
var response = mapper.Map<List<ApplicationInWorkResponse>>(appInWorks);
|
||||
// var response = mapper.Map<List<ApplicationInWorkResponse>>(appInWorks);//TODO Migration to job
|
||||
|
||||
if (filter.IsLight != true)
|
||||
{
|
||||
//Если запрос не легкий, загружаем кол-во шаблонов отдельно, это значительно ускоряет запрос
|
||||
foreach (var item in response)
|
||||
{
|
||||
item.TemplatesCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == item.Id);
|
||||
// if (filter.IsLight != true)
|
||||
// {
|
||||
// //Если запрос не легкий, загружаем кол-во шаблонов отдельно, это значительно ускоряет запрос
|
||||
// foreach (var item in response)
|
||||
// {
|
||||
// item.TemplatesCount = await templateService.Get().CountAsync(t => t.JobId == item.Id);
|
||||
|
||||
var statistics = await GetStatisticsAsync(item.Id);
|
||||
BindStatistics(item, statistics);
|
||||
}
|
||||
}
|
||||
// var statistics = await GetStatisticsAsync(item.Id);
|
||||
// BindStatistics(item, statistics);
|
||||
// }
|
||||
// }
|
||||
|
||||
var paginationResponse = new PagedResponse<ApplicationInWorkResponse>(response, true).GetPaginatedProps(paginationFilter, query);
|
||||
// var paginationResponse = new PagedResponse<ApplicationInWorkResponse>(response, true).GetPaginatedProps(paginationFilter, query);
|
||||
|
||||
return Ok(paginationResponse);
|
||||
}
|
||||
// return Ok(paginationResponse);
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -116,28 +116,28 @@ namespace PARR.API.Controllers.V1
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.Job.Get)]
|
||||
public async Task<IActionResult> GetById([FromRoute] Guid id)
|
||||
{
|
||||
var applicationInWork = await applicationsInWorkService.Get()
|
||||
.Include(t => t.Application).ThenInclude(t => t!.ApplicationType)
|
||||
.Include(t => t.Work)
|
||||
//.Include(t => t.Templates)
|
||||
.Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
.Include(t => t.JobAutoControl)
|
||||
.FirstOrDefaultAsync(t => t.Id == id);
|
||||
//[HttpGet(ApiRoutes.Job.Get)]
|
||||
//public async Task<IActionResult> GetById([FromRoute] Guid id)
|
||||
//{
|
||||
// var applicationInWork = await applicationsInWorkService.Get()
|
||||
// .Include(t => t.Application).ThenInclude(t => t!.ApplicationType)
|
||||
// .Include(t => t.Work)
|
||||
// //.Include(t => t.Templates)
|
||||
// .Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
// .Include(t => t.JobAutoControl)
|
||||
// .FirstOrDefaultAsync(t => t.Id == id);
|
||||
|
||||
if (applicationInWork == null)
|
||||
return NotFound();
|
||||
// if (applicationInWork == null)
|
||||
// return NotFound();
|
||||
|
||||
var response = mapper.Map<ApplicationInWorkResponse>(applicationInWork);
|
||||
response.TemplatesCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == id);
|
||||
// var response = mapper.Map<ApplicationInWorkResponse>(applicationInWork);
|
||||
// response.TemplatesCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == id);
|
||||
|
||||
var statistics = await GetStatisticsAsync(response.Id);
|
||||
BindStatistics(response, statistics);
|
||||
// var statistics = await GetStatisticsAsync(response.Id);
|
||||
// BindStatistics(response, statistics);
|
||||
|
||||
return Ok(new Response<ApplicationInWorkResponse>(response, true));
|
||||
}
|
||||
// return Ok(new Response<ApplicationInWorkResponse>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -145,80 +145,80 @@ namespace PARR.API.Controllers.V1
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(ApiRoutes.Job.Create)]
|
||||
public async Task<IActionResult> Create([FromBody] ApplicationInWorkRequest request)
|
||||
{
|
||||
var resultValidate = await validator.ValidateAsync(request);
|
||||
//[HttpPost(ApiRoutes.Job.Create)]
|
||||
//public async Task<IActionResult> Create([FromBody] ApplicationInWorkRequest request)
|
||||
//{
|
||||
// var resultValidate = await validator.ValidateAsync(request);
|
||||
|
||||
if (!resultValidate.IsValid)
|
||||
return BadRequest(new Response(resultValidate.Errors));
|
||||
// if (!resultValidate.IsValid)
|
||||
// return BadRequest(new Response(resultValidate.Errors));
|
||||
|
||||
//уникальная запись по полям ApplicationId, WorkId
|
||||
var existSameAiW = await applicationsInWorkService.GetAsync(request.ApplicationId, request.WorkId);
|
||||
if (existSameAiW != null)
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Задание на выполнение работ с такими ПО и работой уже существует" } }));
|
||||
// //уникальная запись по полям ApplicationId, WorkId
|
||||
// var existSameAiW = await applicationsInWorkService.GetAsync(request.ApplicationId, request.WorkId);
|
||||
// if (existSameAiW != null)
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Задание на выполнение работ с такими ПО и работой уже существует" } }));
|
||||
|
||||
var applicationInWork = new ApplicationsInWork
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
WorkId = request.WorkId,
|
||||
ApplicationId = request.ApplicationId,
|
||||
TemplateDuration = request.TemplateDuration,
|
||||
ShortDescription = request.ShortDescription.Trim(),
|
||||
FullDescription = request.FullDescription.Trim(),
|
||||
Solution = request.Solution.Trim(),
|
||||
//NextRun = request.NextRun,
|
||||
IsAutoDistributionEnabled = request.IsAutoDistributionEnabled,
|
||||
ReferenceDate = request.ReferenceDate,
|
||||
IsAgent = request.IsAgent,
|
||||
AgentName = request.AgentName?.Trim(),
|
||||
AgentTimeOutSec = request.AgentTimeOutSec,
|
||||
AgentScript = request.AgentScript?.Trim()
|
||||
};
|
||||
// var applicationInWork = new ApplicationsInWork
|
||||
// {
|
||||
// Id = Guid.NewGuid(),
|
||||
// WorkId = request.WorkId,
|
||||
// ApplicationId = request.ApplicationId,
|
||||
// TemplateDuration = request.TemplateDuration,
|
||||
// ShortDescription = request.ShortDescription.Trim(),
|
||||
// FullDescription = request.FullDescription.Trim(),
|
||||
// Solution = request.Solution.Trim(),
|
||||
// //NextRun = request.NextRun,
|
||||
// IsAutoDistributionEnabled = request.IsAutoDistributionEnabled,
|
||||
// ReferenceDate = request.ReferenceDate,
|
||||
// IsAgent = request.IsAgent,
|
||||
// AgentName = request.AgentName?.Trim(),
|
||||
// AgentTimeOutSec = request.AgentTimeOutSec,
|
||||
// AgentScript = request.AgentScript?.Trim()
|
||||
// };
|
||||
|
||||
//Добавляем настройки планировщика
|
||||
request.Schedule.ForEach(item =>
|
||||
{
|
||||
applicationInWork.EsppSchValues.Add(new EsppSchValue
|
||||
{
|
||||
ApplicationsInWorkId = applicationInWork.Id,
|
||||
TypeConfigId = item.TypeConfigId,
|
||||
TypeValueId = item.TypeValueId
|
||||
});
|
||||
});
|
||||
// //Добавляем настройки планировщика
|
||||
// request.Schedule.ForEach(item =>
|
||||
// {
|
||||
// applicationInWork.EsppSchValues.Add(new EsppSchValue
|
||||
// {
|
||||
// ApplicationsInWorkId = applicationInWork.Id,
|
||||
// TypeConfigId = item.TypeConfigId,
|
||||
// TypeValueId = item.TypeValueId
|
||||
// });
|
||||
// });
|
||||
|
||||
//Добавляем рабочие группы
|
||||
request.WorkGroups.ForEach(workGroupId =>
|
||||
{
|
||||
applicationInWork.WorkGroups.Add(new AppInWorkInWorkGroup
|
||||
{
|
||||
ApplicationsInWorkId = applicationInWork.Id,
|
||||
WorkGroupId = workGroupId
|
||||
});
|
||||
});
|
||||
// //Добавляем рабочие группы
|
||||
// request.WorkGroups.ForEach(workGroupId =>
|
||||
// {
|
||||
// applicationInWork.WorkGroups.Add(new AppInWorkInWorkGroup
|
||||
// {
|
||||
// ApplicationsInWorkId = applicationInWork.Id,
|
||||
// WorkGroupId = workGroupId
|
||||
// });
|
||||
// });
|
||||
|
||||
if (!await applicationsInWorkService.CreateAsync(applicationInWork) || !await applicationsInWorkService.CommitAsync())
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при созании задания на выполнение работ" } }));
|
||||
// if (!await applicationsInWorkService.CreateAsync(applicationInWork) || !await applicationsInWorkService.CommitAsync())
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при созании задания на выполнение работ" } }));
|
||||
|
||||
logger.LogInformation($"Пользователь {User.Identity?.Name} добавил задание на выполнение работ: {applicationInWork.Id}, {applicationInWork.ShortDescription}, {applicationInWork.Solution}");
|
||||
// logger.LogInformation($"Пользователь {User.Identity?.Name} добавил задание на выполнение работ: {applicationInWork.Id}, {applicationInWork.ShortDescription}, {applicationInWork.Solution}");
|
||||
|
||||
|
||||
var createdApplicationInWork = await applicationsInWorkService.Get()
|
||||
.Include(t => t.Application).ThenInclude(t => t!.ApplicationType)
|
||||
.Include(t => t.Work)
|
||||
//.Include(t => t.Templates)
|
||||
.Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
.Include(t => t.JobAutoControl)
|
||||
.FirstAsync(t => t.Id == applicationInWork.Id);
|
||||
// var createdApplicationInWork = await applicationsInWorkService.Get()
|
||||
// .Include(t => t.Application).ThenInclude(t => t!.ApplicationType)
|
||||
// .Include(t => t.Work)
|
||||
// //.Include(t => t.Templates)
|
||||
// .Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
// .Include(t => t.JobAutoControl)
|
||||
// .FirstAsync(t => t.Id == applicationInWork.Id);
|
||||
|
||||
var locationUri = uriService.GetUri(ApiRoutes.Job.Get, ApiRoutes.Job.getParam, createdApplicationInWork.Id);
|
||||
// var locationUri = uriService.GetUri(ApiRoutes.Job.Get, ApiRoutes.Job.getParam, createdApplicationInWork.Id);
|
||||
|
||||
var response = mapper.Map<ApplicationInWorkResponse>(createdApplicationInWork);
|
||||
// так как мы только что создали AppInW, то у него нет шаблонов, смело ставим = 0 (ускоряем запрос)
|
||||
response.TemplatesCount = 0;
|
||||
// var response = mapper.Map<ApplicationInWorkResponse>(createdApplicationInWork);
|
||||
// // так как мы только что создали AppInW, то у него нет шаблонов, смело ставим = 0 (ускоряем запрос)
|
||||
// response.TemplatesCount = 0;
|
||||
|
||||
return Created(locationUri, new Response<ApplicationInWorkResponse>(response, true));
|
||||
}
|
||||
// return Created(locationUri, new Response<ApplicationInWorkResponse>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -227,114 +227,114 @@ namespace PARR.API.Controllers.V1
|
||||
/// <param name="id"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut(ApiRoutes.Job.Update)]
|
||||
public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] ApplicationInWorkRequest request)
|
||||
{
|
||||
var resultValidate = await validator.ValidateAsync(request);
|
||||
if (!resultValidate.IsValid)
|
||||
return BadRequest(new Response(resultValidate.Errors));
|
||||
//[HttpPut(ApiRoutes.Job.Update)]
|
||||
//public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] ApplicationInWorkRequest request)
|
||||
//{
|
||||
// var resultValidate = await validator.ValidateAsync(request);
|
||||
// if (!resultValidate.IsValid)
|
||||
// return BadRequest(new Response(resultValidate.Errors));
|
||||
|
||||
//уникальная запись по полям ApplicationId, WorkId у которой id!=[FromRoute]id
|
||||
var existSameAiW = await applicationsInWorkService.Get()
|
||||
.FirstOrDefaultAsync(t => t.Id != id && t.ApplicationId == request.ApplicationId && t.WorkId == request.WorkId);
|
||||
if (existSameAiW != null)
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Задание на выполнение работ с такими ПО и работой уже существует" } }));
|
||||
// //уникальная запись по полям ApplicationId, WorkId у которой id!=[FromRoute]id
|
||||
// var existSameAiW = await applicationsInWorkService.Get()
|
||||
// .FirstOrDefaultAsync(t => t.Id != id && t.ApplicationId == request.ApplicationId && t.WorkId == request.WorkId);
|
||||
// if (existSameAiW != null)
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Задание на выполнение работ с такими ПО и работой уже существует" } }));
|
||||
|
||||
var orig = await applicationsInWorkService.Get()
|
||||
.Include(t => t.WorkGroups)
|
||||
.Include(t => t.EsppSchValues)
|
||||
.FirstOrDefaultAsync(t => t.Id == id);
|
||||
// var orig = await applicationsInWorkService.Get()
|
||||
// .Include(t => t.WorkGroups)
|
||||
// .Include(t => t.EsppSchValues)
|
||||
// .FirstOrDefaultAsync(t => t.Id == id);
|
||||
|
||||
if (orig == null)
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при изменении задания на выполнение работ. Не найдено задание с Id: {id}" } }));
|
||||
// if (orig == null)
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при изменении задания на выполнение работ. Не найдено задание с Id: {id}" } }));
|
||||
|
||||
//Расписание было изменено, ниже добавим задание в очередь на обновление расписаний у связанных шаблонов
|
||||
var isScheduleChanged = IsScheduleChanged(orig, request);
|
||||
// //Расписание было изменено, ниже добавим задание в очередь на обновление расписаний у связанных шаблонов
|
||||
// var isScheduleChanged = IsScheduleChanged(orig, request);
|
||||
|
||||
orig.WorkId = request.WorkId;
|
||||
orig.ApplicationId = request.ApplicationId;
|
||||
orig.TemplateDuration = request.TemplateDuration;
|
||||
orig.ShortDescription = request.ShortDescription.Trim();
|
||||
orig.FullDescription = request.FullDescription.Trim();
|
||||
orig.Solution = request.Solution.Trim();
|
||||
//orig.NextRun = request.NextRun;
|
||||
orig.ReferenceDate = request.ReferenceDate;
|
||||
orig.IsAutoDistributionEnabled = request.IsAutoDistributionEnabled;
|
||||
orig.IsAgent = request.IsAgent;
|
||||
orig.AgentName = request.AgentName?.Trim();
|
||||
orig.AgentTimeOutSec = request.AgentTimeOutSec;
|
||||
orig.AgentScript = request.AgentScript?.Trim();
|
||||
orig.DateModified = DateTimeOffset.UtcNow;
|
||||
// orig.WorkId = request.WorkId;
|
||||
// orig.ApplicationId = request.ApplicationId;
|
||||
// orig.TemplateDuration = request.TemplateDuration;
|
||||
// orig.ShortDescription = request.ShortDescription.Trim();
|
||||
// orig.FullDescription = request.FullDescription.Trim();
|
||||
// orig.Solution = request.Solution.Trim();
|
||||
// //orig.NextRun = request.NextRun;
|
||||
// orig.ReferenceDate = request.ReferenceDate;
|
||||
// orig.IsAutoDistributionEnabled = request.IsAutoDistributionEnabled;
|
||||
// orig.IsAgent = request.IsAgent;
|
||||
// orig.AgentName = request.AgentName?.Trim();
|
||||
// orig.AgentTimeOutSec = request.AgentTimeOutSec;
|
||||
// orig.AgentScript = request.AgentScript?.Trim();
|
||||
// orig.DateModified = DateTimeOffset.UtcNow;
|
||||
|
||||
//обновляем планировщик
|
||||
orig.EsppSchValues.Clear();
|
||||
request.Schedule.ForEach(item =>
|
||||
{
|
||||
orig.EsppSchValues.Add(new EsppSchValue
|
||||
{
|
||||
ApplicationsInWorkId = orig.Id,
|
||||
TypeConfigId = item.TypeConfigId,
|
||||
TypeValueId = item.TypeValueId
|
||||
});
|
||||
});
|
||||
// //обновляем планировщик
|
||||
// orig.EsppSchValues.Clear();
|
||||
// request.Schedule.ForEach(item =>
|
||||
// {
|
||||
// orig.EsppSchValues.Add(new EsppSchValue
|
||||
// {
|
||||
// ApplicationsInWorkId = orig.Id,
|
||||
// TypeConfigId = item.TypeConfigId,
|
||||
// TypeValueId = item.TypeValueId
|
||||
// });
|
||||
// });
|
||||
|
||||
//Обновляем рабочие группы
|
||||
orig.WorkGroups.Clear();
|
||||
request.WorkGroups.ForEach(workGroupId =>
|
||||
{
|
||||
orig.WorkGroups.Add(new AppInWorkInWorkGroup
|
||||
{
|
||||
ApplicationsInWorkId = orig.Id,
|
||||
WorkGroupId = workGroupId
|
||||
});
|
||||
});
|
||||
// //Обновляем рабочие группы
|
||||
// orig.WorkGroups.Clear();
|
||||
// request.WorkGroups.ForEach(workGroupId =>
|
||||
// {
|
||||
// orig.WorkGroups.Add(new AppInWorkInWorkGroup
|
||||
// {
|
||||
// ApplicationsInWorkId = orig.Id,
|
||||
// WorkGroupId = workGroupId
|
||||
// });
|
||||
// });
|
||||
|
||||
|
||||
if (!await applicationsInWorkService.CommitAsync())
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при изменении задания на выполнение работ." } }));
|
||||
// if (!await applicationsInWorkService.CommitAsync())
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при изменении задания на выполнение работ." } }));
|
||||
|
||||
logger.LogInformation($"Пользователь {User.Identity?.Name} обновил задание на выполнение работ: {orig.Id}," +
|
||||
$" {orig.WorkId}, {orig.ApplicationId}, {orig.TemplateDuration}, {orig.ShortDescription}," +
|
||||
$" {orig.FullDescription}, {orig.Solution}, {nameof(orig.IsAutoDistributionEnabled)}: {orig.IsAutoDistributionEnabled}, {orig.IsAgent}, {orig.AgentName}, {orig.AgentTimeOutSec}, {orig.AgentScript}");
|
||||
// logger.LogInformation($"Пользователь {User.Identity?.Name} обновил задание на выполнение работ: {orig.Id}," +
|
||||
// $" {orig.WorkId}, {orig.ApplicationId}, {orig.TemplateDuration}, {orig.ShortDescription}," +
|
||||
// $" {orig.FullDescription}, {orig.Solution}, {nameof(orig.IsAutoDistributionEnabled)}: {orig.IsAutoDistributionEnabled}, {orig.IsAgent}, {orig.AgentName}, {orig.AgentTimeOutSec}, {orig.AgentScript}");
|
||||
|
||||
|
||||
if (isScheduleChanged)
|
||||
{
|
||||
//расписание было обновлено, отправим задание в очередь на перерасчет NextRun
|
||||
var requestToMq = new TemplateDistributorMq
|
||||
{
|
||||
ApplicationInWorkId = id
|
||||
};
|
||||
// if (isScheduleChanged)
|
||||
// {
|
||||
// //расписание было обновлено, отправим задание в очередь на перерасчет NextRun
|
||||
// var requestToMq = new TemplateDistributorMq
|
||||
// {
|
||||
// ApplicationInWorkId = id
|
||||
// };
|
||||
|
||||
var msg = JsonSerializer.Serialize(requestToMq);
|
||||
// var msg = JsonSerializer.Serialize(requestToMq);
|
||||
|
||||
logger.LogDebug($"Расписание в РР applicationInWorkId: {id} было изменено. Отправляем задание в очередь на перерасчет NextRun");
|
||||
// logger.LogDebug($"Расписание в РР applicationInWorkId: {id} было изменено. Отправляем задание в очередь на перерасчет NextRun");
|
||||
|
||||
var sendResult = mqService.Send(mqSettings.TemplateDistributor, new[] { msg });
|
||||
// var sendResult = mqService.Send(mqSettings.TemplateDistributor, new[] { msg });
|
||||
|
||||
if (sendResult.IsSuccess)
|
||||
logger.LogInformation($"Задание на перерасчет NextRun успешно отправлено в очередь MQ {mqSettings.TemplateDistributor.QueueName}");
|
||||
else
|
||||
logger.LogError($"Ошибка при отправке задания на перерасчет NextRun в очередь MQ {mqSettings.TemplateDistributor.QueueName}");
|
||||
}
|
||||
// if (sendResult.IsSuccess)
|
||||
// logger.LogInformation($"Задание на перерасчет NextRun успешно отправлено в очередь MQ {mqSettings.TemplateDistributor.QueueName}");
|
||||
// else
|
||||
// logger.LogError($"Ошибка при отправке задания на перерасчет NextRun в очередь MQ {mqSettings.TemplateDistributor.QueueName}");
|
||||
// }
|
||||
|
||||
var updatedApplicationInWork = await applicationsInWorkService.Get()
|
||||
.Include(t => t.Application).ThenInclude(t => t!.ApplicationType)
|
||||
.Include(t => t.Work)
|
||||
//.Include(t => t.Templates)
|
||||
.Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
.Include(t => t.JobAutoControl)
|
||||
.FirstAsync(t => t.Id == orig.Id);
|
||||
// var updatedApplicationInWork = await applicationsInWorkService.Get()
|
||||
// .Include(t => t.Application).ThenInclude(t => t!.ApplicationType)
|
||||
// .Include(t => t.Work)
|
||||
// //.Include(t => t.Templates)
|
||||
// .Include(t => t.WorkGroups).ThenInclude(t => t.WorkGroup)
|
||||
// .Include(t => t.JobAutoControl)
|
||||
// .FirstAsync(t => t.Id == orig.Id);
|
||||
|
||||
var response = mapper.Map<ApplicationInWorkResponse>(updatedApplicationInWork);
|
||||
response.TemplatesCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == id);
|
||||
// var response = mapper.Map<ApplicationInWorkResponse>(updatedApplicationInWork);
|
||||
// response.TemplatesCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == id);
|
||||
|
||||
var statistics = await GetStatisticsAsync(response.Id);
|
||||
BindStatistics(response, statistics);
|
||||
// var statistics = await GetStatisticsAsync(response.Id);
|
||||
// BindStatistics(response, statistics);
|
||||
|
||||
return Ok(new Response<ApplicationInWorkResponse>(response, true));
|
||||
// return Ok(new Response<ApplicationInWorkResponse>(response, true));
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -342,38 +342,38 @@ namespace PARR.API.Controllers.V1
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete(ApiRoutes.Job.Delete)]
|
||||
public async Task<IActionResult> Delete([FromRoute] Guid id)
|
||||
{
|
||||
var applicationsInWork = await applicationsInWorkService.Get()
|
||||
//.Include(t => t.Templates)
|
||||
.FirstOrDefaultAsync(t => t.Id == id);
|
||||
//[HttpDelete(ApiRoutes.Job.Delete)]
|
||||
//public async Task<IActionResult> Delete([FromRoute] Guid id)
|
||||
//{
|
||||
// var applicationsInWork = await applicationsInWorkService.Get()
|
||||
// //.Include(t => t.Templates)
|
||||
// .FirstOrDefaultAsync(t => t.Id == id);
|
||||
|
||||
if (applicationsInWork == null)
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
|
||||
Message = $"Ошибка при удалении задания на выполнение работ. Не найдено задание на выполнение работ Id: {id}"
|
||||
} }));
|
||||
// if (applicationsInWork == null)
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
|
||||
// Message = $"Ошибка при удалении задания на выполнение работ. Не найдено задание на выполнение работ Id: {id}"
|
||||
// } }));
|
||||
|
||||
var templateCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == id);
|
||||
// var templateCount = await templateService.Get().CountAsync(t => t.ApplicationInWorkId == id);
|
||||
|
||||
//if (applicationsInWork.Templates.Any())
|
||||
if (templateCount > 0)
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
|
||||
Message = $"Ошибка при удалении задания на выполнение работ. С данным заданием связаны шаблоны: {templateCount} шт."
|
||||
} }));
|
||||
// //if (applicationsInWork.Templates.Any())
|
||||
// if (templateCount > 0)
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
|
||||
// Message = $"Ошибка при удалении задания на выполнение работ. С данным заданием связаны шаблоны: {templateCount} шт."
|
||||
// } }));
|
||||
|
||||
if (!applicationsInWorkService.Delete(applicationsInWork) || !await applicationsInWorkService.CommitAsync())
|
||||
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
|
||||
Message = $"Ошибка при удалении задания на выполнение работ"
|
||||
} }));
|
||||
// if (!applicationsInWorkService.Delete(applicationsInWork) || !await applicationsInWorkService.CommitAsync())
|
||||
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
|
||||
// Message = $"Ошибка при удалении задания на выполнение работ"
|
||||
// } }));
|
||||
|
||||
logger.LogInformation($"Пользователь {User.Identity?.Name} удалил задание на выполнение работ: {applicationsInWork.Id},{applicationsInWork.WorkId}," +
|
||||
$" {applicationsInWork.ApplicationId}, {applicationsInWork.TemplateDuration}, {applicationsInWork.ShortDescription}," +
|
||||
$" {applicationsInWork.FullDescription}, {applicationsInWork.Solution}, {nameof(applicationsInWork.IsAutoDistributionEnabled)}: {applicationsInWork.IsAutoDistributionEnabled}, {applicationsInWork.IsAgent}," +
|
||||
$" {applicationsInWork.AgentName}, {applicationsInWork.AgentTimeOutSec}, {applicationsInWork.AgentScript}");
|
||||
// logger.LogInformation($"Пользователь {User.Identity?.Name} удалил задание на выполнение работ: {applicationsInWork.Id},{applicationsInWork.WorkId}," +
|
||||
// $" {applicationsInWork.ApplicationId}, {applicationsInWork.TemplateDuration}, {applicationsInWork.ShortDescription}," +
|
||||
// $" {applicationsInWork.FullDescription}, {applicationsInWork.Solution}, {nameof(applicationsInWork.IsAutoDistributionEnabled)}: {applicationsInWork.IsAutoDistributionEnabled}, {applicationsInWork.IsAgent}," +
|
||||
// $" {applicationsInWork.AgentName}, {applicationsInWork.AgentTimeOutSec}, {applicationsInWork.AgentScript}");
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
// return NoContent();
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -382,31 +382,31 @@ namespace PARR.API.Controllers.V1
|
||||
/// <param name="orig"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
private bool IsScheduleChanged(ApplicationsInWork orig, ApplicationInWorkRequest request)
|
||||
{
|
||||
var isScheduleChanged = false;
|
||||
//private bool IsScheduleChanged(ApplicationsInWork orig, ApplicationInWorkRequest request)
|
||||
//{
|
||||
// var isScheduleChanged = false;
|
||||
|
||||
if (orig.ReferenceDate != request.ReferenceDate)
|
||||
isScheduleChanged = true;
|
||||
// if (orig.ReferenceDate != request.ReferenceDate)
|
||||
// isScheduleChanged = true;
|
||||
|
||||
if (request.Schedule.Count() != orig.EsppSchValues.Count())
|
||||
isScheduleChanged = true;
|
||||
// if (request.Schedule.Count() != orig.EsppSchValues.Count())
|
||||
// isScheduleChanged = true;
|
||||
|
||||
if (request.IsAutoDistributionEnabled != orig.IsAutoDistributionEnabled)
|
||||
isScheduleChanged = true;
|
||||
// if (request.IsAutoDistributionEnabled != orig.IsAutoDistributionEnabled)
|
||||
// isScheduleChanged = true;
|
||||
|
||||
request.Schedule.ForEach(requestSchedule =>
|
||||
{
|
||||
var schExist = orig.EsppSchValues.FirstOrDefault(t => t.ApplicationsInWorkId == orig.Id
|
||||
&& t.TypeValueId == requestSchedule.TypeValueId
|
||||
&& t.TypeConfigId == requestSchedule.TypeConfigId);
|
||||
// request.Schedule.ForEach(requestSchedule =>
|
||||
// {
|
||||
// var schExist = orig.EsppSchValues.FirstOrDefault(t => t.ApplicationsInWorkId == orig.Id
|
||||
// && t.TypeValueId == requestSchedule.TypeValueId
|
||||
// && t.TypeConfigId == requestSchedule.TypeConfigId);
|
||||
|
||||
if (schExist == null)
|
||||
isScheduleChanged = true;
|
||||
});
|
||||
// if (schExist == null)
|
||||
// isScheduleChanged = true;
|
||||
// });
|
||||
|
||||
return isScheduleChanged;
|
||||
}
|
||||
// return isScheduleChanged;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -414,28 +414,28 @@ namespace PARR.API.Controllers.V1
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorkId"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<AppInWorkStatModel> GetStatisticsAsync(Guid applicationInWorkId)
|
||||
{
|
||||
var statResult = await applicationsInWorkService.Get()
|
||||
.Include(t => t.Templates).ThenInclude(t => t.RobotConfigurations)
|
||||
.Where(x => x.Id == applicationInWorkId)
|
||||
.Select(t => new
|
||||
{
|
||||
TemplateActivated = t.Templates.Count(x => x.IsActiveTemplate),
|
||||
TemplateSynchronized = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.TaskStatusCode == (int)TaskStatusEnum.Ok && c.RobotCode == (int)RobotsEnum.TemplateOrder)),
|
||||
TemplateErrors = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.RobotStatusCode == (int)RobotStatusEnum.Error && c.RobotCode == (int)RobotsEnum.TemplateOrder)),
|
||||
ScheduleActivated = t.Templates.Count(x => x.IsActiveSchedule),
|
||||
ScheduleSynchronized = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.TaskStatusCode == (int)TaskStatusEnum.Ok && c.RobotCode == (int)RobotsEnum.ScheduleOrder)),
|
||||
ScheduleErrors = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.RobotStatusCode == (int)RobotStatusEnum.Error && c.RobotCode == (int)RobotsEnum.ScheduleOrder))
|
||||
//private async Task<AppInWorkStatModel> GetStatisticsAsync(Guid applicationInWorkId)
|
||||
//{
|
||||
// var statResult = await applicationsInWorkService.Get()
|
||||
// .Include(t => t.Templates).ThenInclude(t => t.RobotConfigurations)
|
||||
// .Where(x => x.Id == applicationInWorkId)
|
||||
// .Select(t => new
|
||||
// {
|
||||
// TemplateActivated = t.Templates.Count(x => x.IsActiveTemplate),
|
||||
// TemplateSynchronized = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.TaskStatusCode == (int)TaskStatusEnum.Ok && c.RobotCode == (int)RobotsEnum.TemplateOrder)),
|
||||
// TemplateErrors = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.RobotStatusCode == (int)RobotStatusEnum.Error && c.RobotCode == (int)RobotsEnum.TemplateOrder)),
|
||||
// ScheduleActivated = t.Templates.Count(x => x.IsActiveSchedule),
|
||||
// ScheduleSynchronized = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.TaskStatusCode == (int)TaskStatusEnum.Ok && c.RobotCode == (int)RobotsEnum.ScheduleOrder)),
|
||||
// ScheduleErrors = t.Templates.Count(x => x.RobotConfigurations.Any(c => c.RobotStatusCode == (int)RobotStatusEnum.Error && c.RobotCode == (int)RobotsEnum.ScheduleOrder))
|
||||
|
||||
}).FirstOrDefaultAsync();
|
||||
// }).FirstOrDefaultAsync();
|
||||
|
||||
return new AppInWorkStatModel
|
||||
{
|
||||
ScheduleStatistics = new ScheduleStats { Activated = statResult?.ScheduleActivated ?? 0, Errors = statResult?.ScheduleErrors ?? 0, Synchronized = statResult?.ScheduleSynchronized ?? 0 },
|
||||
TemplateStatistics = new TemplateStats { Activated = statResult?.TemplateActivated ?? 0, Errors = statResult?.TemplateErrors ?? 0, Synchronized = statResult?.TemplateSynchronized ?? 0 }
|
||||
};
|
||||
}
|
||||
// return new AppInWorkStatModel
|
||||
// {
|
||||
// ScheduleStatistics = new ScheduleStats { Activated = statResult?.ScheduleActivated ?? 0, Errors = statResult?.ScheduleErrors ?? 0, Synchronized = statResult?.ScheduleSynchronized ?? 0 },
|
||||
// TemplateStatistics = new TemplateStats { Activated = statResult?.TemplateActivated ?? 0, Errors = statResult?.TemplateErrors ?? 0, Synchronized = statResult?.TemplateSynchronized ?? 0 }
|
||||
// };
|
||||
//}
|
||||
|
||||
|
||||
private void BindStatistics(ApplicationInWorkResponse applicationsInWork, AppInWorkStatModel statistics)
|
||||
|
||||
@@ -71,11 +71,11 @@ namespace PARR.API.Controllers.V1
|
||||
case RobotsEnum.TemplateOrder:
|
||||
// шаблоны
|
||||
query = query.Include(t => t.Template)
|
||||
.ThenInclude(t => t!.Host).ThenInclude(t => t!.ResponseArea)
|
||||
.ThenInclude(t => t!.Hosts).ThenInclude(t => t.WorkGroup).ThenInclude(t => t!.ResponseArea)
|
||||
.ThenInclude(t => t!.Unit)
|
||||
//.ThenInclude(t => t!.Hosts).ThenInclude(t => t.WorkGroup).ThenInclude(t => t!.ResponseArea)
|
||||
.Include(t => t.Template)
|
||||
.ThenInclude(a => a!.ApplicationsInWork)
|
||||
.ThenInclude(w => w!.Work)
|
||||
.ThenInclude(a => a!.Job)
|
||||
//.ThenInclude(w => w!.Work)
|
||||
.ThenInclude(t => t!.Tnk)
|
||||
.ThenInclude(s => s!.Subprocess)
|
||||
.ThenInclude(p => p!.Process);
|
||||
@@ -84,10 +84,12 @@ namespace PARR.API.Controllers.V1
|
||||
//расписание
|
||||
// тут не делаем AsSplitQuery, не может подтянуть все таблицы
|
||||
query = query.Include(t => t.Template)
|
||||
.ThenInclude(t => t!.Host).ThenInclude(t => t!.ResponseArea)
|
||||
.ThenInclude(t => t!.Hosts).ThenInclude(t => t.WorkGroup)
|
||||
.ThenInclude(t => t!.Unit)//.ThenInclude(t => t!.ResponseArea)
|
||||
//.ThenInclude(t => t!.Hosts).ThenInclude(t => t.WorkGroup)
|
||||
.Include(t => t.Template)
|
||||
.ThenInclude(t => t!.ApplicationsInWork)
|
||||
.ThenInclude(t => t!.Job)
|
||||
.ThenInclude(t => t!.Group)
|
||||
//.ThenInclude(t => t!.ApplicationsInWork)
|
||||
.ThenInclude(t => t!.EsppSchValues)
|
||||
.ThenInclude(t => t!.EsppSchTypeConfig)
|
||||
.ThenInclude(t => t!.EsppSchTypeSchedule);
|
||||
@@ -169,7 +171,7 @@ namespace PARR.API.Controllers.V1
|
||||
// передаем LastRun, если его нет, то NextRun
|
||||
//var nextRun = await esppScheduleTransformService.GetNextDateAsync(task.Template!.ApplicationInWorkId, task.Template.ApplicationsInWork!.LastRun ?? task.Template.ApplicationsInWork.NextRun);
|
||||
// всегда считаем по nextRun
|
||||
var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.ApplicationInWorkId, template.NextRun);
|
||||
var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template.NextRun);
|
||||
|
||||
if (nextRun != template.NextRun)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using PARR.API.Controllers.V1.Base;
|
||||
using PARR.BLL.Services.Interfaces;
|
||||
using PARR.Constants;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
using PARR.DAL.Services.Interfaces.Unit;
|
||||
|
||||
namespace PARR.API.Controllers.V1.Statistics
|
||||
{
|
||||
@@ -19,11 +20,17 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
public class StatHostController : BaseApiController
|
||||
{
|
||||
private readonly IHostService hostService;
|
||||
private readonly IUnitService unitService;
|
||||
private readonly ICalendarService calendarService;
|
||||
|
||||
public StatHostController(IHostService hostService, ICalendarService calendarService)
|
||||
public StatHostController(
|
||||
IHostService hostService,
|
||||
IUnitService unitService,
|
||||
ICalendarService calendarService
|
||||
)
|
||||
{
|
||||
this.hostService = hostService;
|
||||
this.unitService = unitService;
|
||||
this.calendarService = calendarService;
|
||||
}
|
||||
|
||||
@@ -103,8 +110,8 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
|
||||
var response = new StatHostTemplateResponse
|
||||
{
|
||||
AllHosts = await hostService.Get().CountAsync(),
|
||||
HostsInTemplates = await hostService.Get().Include(t => t.Templates).CountAsync(t => t.Templates.Any())
|
||||
AllUnits = await unitService.Get().CountAsync(),
|
||||
HostsInTemplates = await unitService.Get().Include(t => t.Templates).CountAsync(t => t.Templates.Any())
|
||||
};
|
||||
|
||||
return Ok(new Response<StatHostTemplateResponse>(response, true));
|
||||
|
||||
@@ -40,88 +40,88 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Статистика загрузки РР по всем ЗО
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.StatResponseAreaWorkLoad.GetAll)]
|
||||
public async Task<IActionResult> GetAll([FromQuery] WorkloadBaseQuery requestQuery)
|
||||
{
|
||||
var response = await GetStatisticsAsync(requestQuery);
|
||||
///// <summary>
|
||||
///// Статистика загрузки РР по всем ЗО
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet(ApiRoutes.StatResponseAreaWorkLoad.GetAll)]
|
||||
//public async Task<IActionResult> GetAll([FromQuery] WorkloadBaseQuery requestQuery)
|
||||
//{
|
||||
// var response = await GetStatisticsAsync(requestQuery);
|
||||
|
||||
return Ok(new Response<List<StatResponseAreaWorkLoadResponse>>(response, true));
|
||||
}
|
||||
// return Ok(new Response<List<StatResponseAreaWorkLoadResponse>>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Статистика загрузки РР по списку ЗО
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost(ApiRoutes.StatResponseAreaWorkLoad.GetByResponseAreas)]
|
||||
public async Task<IActionResult> GetByResponseAreas([FromBody] StatResponseAreaWorkloadRequest request)
|
||||
{
|
||||
var response = await GetStatisticsAsync(request.Filter, request.ResponseAreas);
|
||||
///// <summary>
|
||||
///// Статистика загрузки РР по списку ЗО
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpPost(ApiRoutes.StatResponseAreaWorkLoad.GetByResponseAreas)]
|
||||
//public async Task<IActionResult> GetByResponseAreas([FromBody] StatResponseAreaWorkloadRequest request)
|
||||
//{
|
||||
// var response = await GetStatisticsAsync(request.Filter, request.ResponseAreas);
|
||||
|
||||
return Ok(new Response<List<StatResponseAreaWorkLoadResponse>>(response, true));
|
||||
}
|
||||
// return Ok(new Response<List<StatResponseAreaWorkLoadResponse>>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
private async Task<List<StatResponseAreaWorkLoadResponse>> GetStatisticsAsync(WorkloadBaseQuery requestQuery, List<int>? responseAreas = null)
|
||||
{
|
||||
var daysList = workLoadService.GetDatesForPeriod(requestQuery);
|
||||
//private async Task<List<StatResponseAreaWorkLoadResponse>> GetStatisticsAsync(WorkloadBaseQuery requestQuery, List<int>? responseAreas = null)
|
||||
//{
|
||||
// var daysList = workLoadService.GetDatesForPeriod(requestQuery);
|
||||
|
||||
IQueryable<DAL.Models.Template> query = templateService.Get()
|
||||
.Include(t => t.Host).ThenInclude(t => t.WorkGroup);
|
||||
// IQueryable<DAL.Models.Template> query = templateService.Get()
|
||||
// .Include(t => t.Host).ThenInclude(t => t.WorkGroup);
|
||||
|
||||
query = workLoadService.FilterTemplatesQuery(query, requestQuery);
|
||||
// query = workLoadService.FilterTemplatesQuery(query, requestQuery);
|
||||
|
||||
if (responseAreas != null && responseAreas.Count() > 0)
|
||||
query = query.Where(t => responseAreas.Any(x => x == t.Host.WorkGroup.ResponseAreaCode));
|
||||
// if (responseAreas != null && responseAreas.Count() > 0)
|
||||
// query = query.Where(t => responseAreas.Any(x => x == t.Host.WorkGroup.ResponseAreaCode));
|
||||
|
||||
//var groupedQuery = query.GroupBy(t => new { t.NextRun.DateTime.Date, t.Host!.WorkGroup!.ResponseAreaCode })
|
||||
var groupedQuery = query.GroupBy(t => new { t.NextRun.AddHours(requestQuery.TimeZoneOffsetHours).DateTime.Date, t.Host!.WorkGroup!.ResponseAreaCode })
|
||||
.Select(t => new
|
||||
{
|
||||
ResponseAreaCode = t.Key.ResponseAreaCode,
|
||||
Date = t.Key.Date,
|
||||
TemplateCount = t.Count()
|
||||
// //var groupedQuery = query.GroupBy(t => new { t.NextRun.DateTime.Date, t.Host!.WorkGroup!.ResponseAreaCode })
|
||||
// var groupedQuery = query.GroupBy(t => new { t.NextRun.AddHours(requestQuery.TimeZoneOffsetHours).DateTime.Date, t.Host!.WorkGroup!.ResponseAreaCode })
|
||||
// .Select(t => new
|
||||
// {
|
||||
// ResponseAreaCode = t.Key.ResponseAreaCode,
|
||||
// Date = t.Key.Date,
|
||||
// TemplateCount = t.Count()
|
||||
|
||||
});
|
||||
// });
|
||||
|
||||
var queryResult = await groupedQuery.ToListAsync();
|
||||
// var queryResult = await groupedQuery.ToListAsync();
|
||||
|
||||
var responseAreaQuery = responseAreaService.Get();
|
||||
// var responseAreaQuery = responseAreaService.Get();
|
||||
|
||||
if (responseAreas != null && responseAreas.Count() > 0)
|
||||
responseAreaQuery = responseAreaQuery.Where(t => responseAreas.Any(x => x == t.Code));
|
||||
// if (responseAreas != null && responseAreas.Count() > 0)
|
||||
// responseAreaQuery = responseAreaQuery.Where(t => responseAreas.Any(x => x == t.Code));
|
||||
|
||||
var allResponseArea = await responseAreaQuery.ToListAsync();
|
||||
// var allResponseArea = await responseAreaQuery.ToListAsync();
|
||||
|
||||
//if (!allResponseArea.Any())
|
||||
// return NoContent();
|
||||
// //if (!allResponseArea.Any())
|
||||
// // return NoContent();
|
||||
|
||||
var response = new List<StatResponseAreaWorkLoadResponse>();
|
||||
// var response = new List<StatResponseAreaWorkLoadResponse>();
|
||||
|
||||
allResponseArea.ForEach(respArea =>
|
||||
{
|
||||
var workLoads = daysList.Select(t => new StatWorkLoadDataResponse
|
||||
{
|
||||
Date = t,
|
||||
TemplateCount = queryResult.FirstOrDefault(x => x.ResponseAreaCode == respArea.Code && DateOnly.FromDateTime(x.Date) == t)?.TemplateCount ?? 0
|
||||
}).OrderBy(t => t.Date).ToList();
|
||||
// allResponseArea.ForEach(respArea =>
|
||||
// {
|
||||
// var workLoads = daysList.Select(t => new StatWorkLoadDataResponse
|
||||
// {
|
||||
// Date = t,
|
||||
// TemplateCount = queryResult.FirstOrDefault(x => x.ResponseAreaCode == respArea.Code && DateOnly.FromDateTime(x.Date) == t)?.TemplateCount ?? 0
|
||||
// }).OrderBy(t => t.Date).ToList();
|
||||
|
||||
response.Add(
|
||||
new StatResponseAreaWorkLoadResponse
|
||||
{
|
||||
ResponseArea = mapper.Map<ResponseAreaResponse>(respArea),
|
||||
WorkLoad = workLoads
|
||||
});
|
||||
});
|
||||
// response.Add(
|
||||
// new StatResponseAreaWorkLoadResponse
|
||||
// {
|
||||
// ResponseArea = mapper.Map<ResponseAreaResponse>(respArea),
|
||||
// WorkLoad = workLoads
|
||||
// });
|
||||
// });
|
||||
|
||||
response = response.OrderBy(t => t.ResponseArea.Code).ToList();
|
||||
// response = response.OrderBy(t => t.ResponseArea.Code).ToList();
|
||||
|
||||
return response;
|
||||
}
|
||||
// return response;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,66 +32,66 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
this.calendarService = calendarService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Статистика по шаблонам
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.StatTemplate.Get)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
var response = new StatTemplateResponse
|
||||
{
|
||||
ActivateScheduleCount = await templateService.Get().CountAsync(t => t.IsActiveSchedule),
|
||||
ActivateTemplateCount = await templateService.Get().CountAsync(t => t.IsActiveTemplate),
|
||||
TemplateAgentCount = await templateService.Get().Include(t => t.ApplicationsInWork).CountAsync(t => t.ApplicationsInWork!.IsAgent),
|
||||
TemplateCount = await templateService.Get().CountAsync(),
|
||||
SyncEsppScheduleCount = await templateService.Get().Include(t => t.RobotConfigurations).CountAsync(t => t.RobotConfigurations.Any(c => c.RobotCode == (int)RobotsEnum.ScheduleOrder && c.TaskStatusCode == (int)TaskStatusEnum.Ok)),
|
||||
SyncEsppTemplatesCount = await templateService.Get().Include(t => t.RobotConfigurations).CountAsync(t => t.RobotConfigurations.Any(c => c.RobotCode == (int)RobotsEnum.TemplateOrder && c.TaskStatusCode == (int)TaskStatusEnum.Ok))
|
||||
};
|
||||
///// <summary>
|
||||
///// Статистика по шаблонам
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet(ApiRoutes.StatTemplate.Get)]
|
||||
//public async Task<IActionResult> Get()
|
||||
//{
|
||||
// var response = new StatTemplateResponse
|
||||
// {
|
||||
// ActivateScheduleCount = await templateService.Get().CountAsync(t => t.IsActiveSchedule),
|
||||
// ActivateTemplateCount = await templateService.Get().CountAsync(t => t.IsActiveTemplate),
|
||||
// TemplateAgentCount = await templateService.Get().Include(t => t.ApplicationsInWork).CountAsync(t => t.ApplicationsInWork!.IsAgent),
|
||||
// TemplateCount = await templateService.Get().CountAsync(),
|
||||
// SyncEsppScheduleCount = await templateService.Get().Include(t => t.RobotConfigurations).CountAsync(t => t.RobotConfigurations.Any(c => c.RobotCode == (int)RobotsEnum.ScheduleOrder && c.TaskStatusCode == (int)TaskStatusEnum.Ok)),
|
||||
// SyncEsppTemplatesCount = await templateService.Get().Include(t => t.RobotConfigurations).CountAsync(t => t.RobotConfigurations.Any(c => c.RobotCode == (int)RobotsEnum.TemplateOrder && c.TaskStatusCode == (int)TaskStatusEnum.Ok))
|
||||
// };
|
||||
|
||||
return Ok(new Response<StatTemplateResponse>(response, true));
|
||||
}
|
||||
// return Ok(new Response<StatTemplateResponse>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику созданных шаблонов (расписаний) в БД ПАРР
|
||||
/// </summary>
|
||||
/// <param name="timeZoneQuery"></param>
|
||||
/// <param name="startPeriodDays"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.StatTemplate.GetForPeriod)]
|
||||
public async Task<IActionResult> GetForPeriod([FromQuery] TimeZoneOffsetClient timeZoneQuery, [FromQuery] int startPeriodDays = 3)
|
||||
{
|
||||
var endPeriod = calendarService.GetDateWithTimeZoneOffset(DateTimeOffset.UtcNow, timeZoneQuery.TimeZoneOffsetHours);
|
||||
var startPeriod = endPeriod.AddDays(-startPeriodDays);
|
||||
///// <summary>
|
||||
///// Получить статистику созданных шаблонов (расписаний) в БД ПАРР
|
||||
///// </summary>
|
||||
///// <param name="timeZoneQuery"></param>
|
||||
///// <param name="startPeriodDays"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet(ApiRoutes.StatTemplate.GetForPeriod)]
|
||||
//public async Task<IActionResult> GetForPeriod([FromQuery] TimeZoneOffsetClient timeZoneQuery, [FromQuery] int startPeriodDays = 3)
|
||||
//{
|
||||
// var endPeriod = calendarService.GetDateWithTimeZoneOffset(DateTimeOffset.UtcNow, timeZoneQuery.TimeZoneOffsetHours);
|
||||
// var startPeriod = endPeriod.AddDays(-startPeriodDays);
|
||||
|
||||
var query = templateService.Get()
|
||||
.Where(t =>
|
||||
t.DateCreated.DateTime.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date >= startPeriod.Date
|
||||
&& t.DateCreated.DateTime.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date <= endPeriod.Date
|
||||
).GroupBy(t => t.DateCreated.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date)
|
||||
.Select(t => new
|
||||
{
|
||||
Date = t.Key,
|
||||
CreatedObjs = t.Count()
|
||||
});
|
||||
// var query = templateService.Get()
|
||||
// .Where(t =>
|
||||
// t.DateCreated.DateTime.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date >= startPeriod.Date
|
||||
// && t.DateCreated.DateTime.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date <= endPeriod.Date
|
||||
// ).GroupBy(t => t.DateCreated.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date)
|
||||
// .Select(t => new
|
||||
// {
|
||||
// Date = t.Key,
|
||||
// CreatedObjs = t.Count()
|
||||
// });
|
||||
|
||||
var result = await query.ToListAsync();
|
||||
// var result = await query.ToListAsync();
|
||||
|
||||
var daysList = calendarService.GetDatesForPeriod(startPeriod, endPeriod);
|
||||
// var daysList = calendarService.GetDatesForPeriod(startPeriod, endPeriod);
|
||||
|
||||
var response = new List<StatTemplatePeriodResponse>();
|
||||
// var response = new List<StatTemplatePeriodResponse>();
|
||||
|
||||
daysList.ForEach(date => response.Add(new StatTemplatePeriodResponse
|
||||
{
|
||||
Date = date,
|
||||
CreatedTemplatesCount = result.FirstOrDefault(t => DateOnly.FromDateTime(t.Date) == date)?.CreatedObjs ?? 0
|
||||
}));
|
||||
// daysList.ForEach(date => response.Add(new StatTemplatePeriodResponse
|
||||
// {
|
||||
// Date = date,
|
||||
// CreatedTemplatesCount = result.FirstOrDefault(t => DateOnly.FromDateTime(t.Date) == date)?.CreatedObjs ?? 0
|
||||
// }));
|
||||
|
||||
response = response.OrderBy(t => t.Date).ToList();
|
||||
// response = response.OrderBy(t => t.Date).ToList();
|
||||
|
||||
return Ok(new Response<List<StatTemplatePeriodResponse>>(response, true));
|
||||
}
|
||||
// return Ok(new Response<List<StatTemplatePeriodResponse>>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,20 +37,20 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
/// <summary>
|
||||
/// Статистика распределения шаблонов по JobId (ApplicationInWorkId)
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorkId"></param>
|
||||
/// <param name="JobId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.StatTemplateDistribution.Get)]
|
||||
public async Task<IActionResult> Get([FromRoute] Guid applicationInWorkId)
|
||||
public async Task<IActionResult> Get([FromRoute] Guid jobId)
|
||||
{
|
||||
// f87dbe9f-cabf-4108-9c93-12068d4b48a5
|
||||
|
||||
var query = templateService.Get()
|
||||
.Include(t => t.Host)
|
||||
.Where(t => t.ApplicationInWorkId == applicationInWorkId)
|
||||
.GroupBy(t => t.Host!.WorkGroupId)
|
||||
.Include(t => t.Unit)
|
||||
.Where(t => t.JobId == jobId)
|
||||
.GroupBy(t => t.Unit!.BaseFields!.WorkGroup)
|
||||
.Select(x => new
|
||||
{
|
||||
WorkGroupId = x.Key,
|
||||
WorkGroup = x.Key,
|
||||
CountTemplates = x.Count(),
|
||||
IsActivatedAllCount = x.Count(t => t.IsActiveTemplate && t.IsActiveSchedule),
|
||||
IsDeactivatedAllCount = x.Count(t => !t.IsActiveTemplate || !t.IsActiveSchedule || (!t.IsActiveTemplate && !t.IsActiveSchedule)),
|
||||
@@ -73,13 +73,13 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
|
||||
var workGroups = await workGroupService.Get()
|
||||
.Include(t => t.ResponseArea)
|
||||
.Where(t => statResult.Select(x => x.WorkGroupId).Any(w => w == t.Id))
|
||||
.Where(t => statResult.Select(x => x.WorkGroup).Any(w => w == t.Name))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var response = statResult.Select(stat => new StatTemplateDistributorResponse
|
||||
{
|
||||
WorkGroup = mapper.Map<WorkGroupResponse>(workGroups.FirstOrDefault(x => x.Id == stat.WorkGroupId)),
|
||||
WorkGroup = mapper.Map<WorkGroupResponse>(workGroups.FirstOrDefault(x => x.Name == stat.WorkGroup)),//TODO Migration to job
|
||||
AllCount = stat.CountTemplates,
|
||||
IsActivatedAllCount = stat.IsActivatedAllCount,
|
||||
IsDeactivatedAllCount = stat.IsDeactivatedAllCount,
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Статистика загрузки регламентными работами рабочих групп по ЗО
|
||||
/// </summary>
|
||||
@@ -137,6 +137,6 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,131 +41,131 @@ namespace PARR.API.Controllers.V1.Statistics
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Статистика загрузки регламентными работами по Видам работ(ApplicationInWorks)
|
||||
/// </summary>
|
||||
/// <param name="workGroupId"></param>
|
||||
/// <param name="requestQuery"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(ApiRoutes.StatWorkWorkLoad.Get)]
|
||||
public async Task<IActionResult> Get([FromRoute] Guid workGroupId, [FromQuery] WorkloadBaseQuery requestQuery)
|
||||
{
|
||||
var response = await GetStatisticsAsync(workGroupId, requestQuery);
|
||||
///// <summary>
|
||||
///// Статистика загрузки регламентными работами по Видам работ(ApplicationInWorks)
|
||||
///// </summary>
|
||||
///// <param name="workGroupId"></param>
|
||||
///// <param name="requestQuery"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet(ApiRoutes.StatWorkWorkLoad.Get)]
|
||||
//public async Task<IActionResult> Get([FromRoute] Guid workGroupId, [FromQuery] WorkloadBaseQuery requestQuery)
|
||||
//{
|
||||
// var response = await GetStatisticsAsync(workGroupId, requestQuery);
|
||||
|
||||
return Ok(new Response<List<StatWorkWorkLoadResponse>>(response, true));
|
||||
}
|
||||
// return Ok(new Response<List<StatWorkWorkLoadResponse>>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Статистика загрузки РР по списку РР
|
||||
/// </summary>
|
||||
/// <param name="requestBody"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(ApiRoutes.StatWorkWorkLoad.GetByApplicationInWork)]
|
||||
public async Task<IActionResult> GetByApplicationInWork([FromBody] StatWorkWorkLoadRequest requestBody)
|
||||
{
|
||||
var response = await GetStatisticsAsync(null, requestBody.Filter, requestBody.JobsRequests);
|
||||
///// <summary>
|
||||
///// Статистика загрузки РР по списку РР
|
||||
///// </summary>
|
||||
///// <param name="requestBody"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost(ApiRoutes.StatWorkWorkLoad.GetByApplicationInWork)]
|
||||
//public async Task<IActionResult> GetByApplicationInWork([FromBody] StatWorkWorkLoadRequest requestBody)
|
||||
//{
|
||||
// var response = await GetStatisticsAsync(null, requestBody.Filter, requestBody.JobsRequests);
|
||||
|
||||
return Ok(new Response<List<StatWorkWorkLoadResponse>>(response, true));
|
||||
}
|
||||
// return Ok(new Response<List<StatWorkWorkLoadResponse>>(response, true));
|
||||
//}
|
||||
|
||||
|
||||
private async Task<List<StatWorkWorkLoadResponse>> GetStatisticsAsync(Guid? workGroupId, WorkloadBaseQuery requestQuery, List<StatWorkWorkLoadJobRequest>? jobsRequests = null)
|
||||
{
|
||||
//защита от дурака, чтоб не выгрузить всю БД
|
||||
if (workGroupId == null && (jobsRequests == null || jobsRequests.Count() == 0))
|
||||
{
|
||||
logger.LogWarning($"Пытались выполнить запрос получения статситики с нулевыми параметрами {nameof(workGroupId)}, {nameof(jobsRequests)}. Controller {nameof(StatWorkWorkLoadController)}");
|
||||
return new List<StatWorkWorkLoadResponse>();
|
||||
}
|
||||
//private async Task<List<StatWorkWorkLoadResponse>> GetStatisticsAsync(Guid? workGroupId, WorkloadBaseQuery requestQuery, List<StatWorkWorkLoadJobRequest>? jobsRequests = null)
|
||||
//{
|
||||
// //защита от дурака, чтоб не выгрузить всю БД
|
||||
// if (workGroupId == null && (jobsRequests == null || jobsRequests.Count() == 0))
|
||||
// {
|
||||
// logger.LogWarning($"Пытались выполнить запрос получения статситики с нулевыми параметрами {nameof(workGroupId)}, {nameof(jobsRequests)}. Controller {nameof(StatWorkWorkLoadController)}");
|
||||
// return new List<StatWorkWorkLoadResponse>();
|
||||
// }
|
||||
|
||||
|
||||
var daysList = workLoadService.GetDatesForPeriod(requestQuery);
|
||||
// var daysList = workLoadService.GetDatesForPeriod(requestQuery);
|
||||
|
||||
IQueryable<DAL.Models.Template> query = templateService.Get()
|
||||
.Include(t => t.Host);
|
||||
// IQueryable<DAL.Models.Template> query = templateService.Get()
|
||||
// .Include(t => t.Host);
|
||||
|
||||
query = workLoadService.FilterTemplatesQuery(query, requestQuery);
|
||||
// query = workLoadService.FilterTemplatesQuery(query, requestQuery);
|
||||
|
||||
if (workGroupId.HasValue)
|
||||
query = query.Where(t => t.Host!.WorkGroupId == workGroupId.Value);
|
||||
// if (workGroupId.HasValue)
|
||||
// query = query.Where(t => t.Host!.WorkGroupId == workGroupId.Value);
|
||||
|
||||
if (jobsRequests != null && jobsRequests.Count() > 0)
|
||||
//query = query.Where(t => jobsRequests.Any(x => x.JobId == t.ApplicationInWorkId && x.WorkGroupId == t.Host!.WorkGroupId.Value)); /*&& x.WorkGroupId == t.Host!.WorkGroupId.Value*/
|
||||
query = query.Where(t => jobsRequests.Select(t => t.JobId).Any(x => x == t.ApplicationInWorkId) && jobsRequests.Select(t => t.WorkGroupId).Any(x => x == t.Host!.WorkGroupId.Value));
|
||||
// if (jobsRequests != null && jobsRequests.Count() > 0)
|
||||
// //query = query.Where(t => jobsRequests.Any(x => x.JobId == t.ApplicationInWorkId && x.WorkGroupId == t.Host!.WorkGroupId.Value)); /*&& x.WorkGroupId == t.Host!.WorkGroupId.Value*/
|
||||
// query = query.Where(t => jobsRequests.Select(t => t.JobId).Any(x => x == t.ApplicationInWorkId) && jobsRequests.Select(t => t.WorkGroupId).Any(x => x == t.Host!.WorkGroupId.Value));
|
||||
|
||||
//var groupedQuery = query.GroupBy(t => new { t.NextRun.DateTime.Date, t.ApplicationInWorkId, t.Host.WorkGroupId })
|
||||
var groupedQuery = query.GroupBy(t => new { t.NextRun.AddHours(requestQuery.TimeZoneOffsetHours).DateTime.Date, t.ApplicationInWorkId, t.Host.WorkGroupId })
|
||||
.Select(t => new
|
||||
{
|
||||
ApplicationInWorkId = t.Key.ApplicationInWorkId,
|
||||
WorkGroupId = t.Key.WorkGroupId,
|
||||
Date = t.Key.Date,
|
||||
TemplateCount = t.Count()
|
||||
});
|
||||
// //var groupedQuery = query.GroupBy(t => new { t.NextRun.DateTime.Date, t.ApplicationInWorkId, t.Host.WorkGroupId })
|
||||
// var groupedQuery = query.GroupBy(t => new { t.NextRun.AddHours(requestQuery.TimeZoneOffsetHours).DateTime.Date, t.ApplicationInWorkId, t.Host.WorkGroupId })
|
||||
// .Select(t => new
|
||||
// {
|
||||
// ApplicationInWorkId = t.Key.ApplicationInWorkId,
|
||||
// WorkGroupId = t.Key.WorkGroupId,
|
||||
// Date = t.Key.Date,
|
||||
// TemplateCount = t.Count()
|
||||
// });
|
||||
|
||||
var queryResult = await groupedQuery.ToListAsync();
|
||||
// var queryResult = await groupedQuery.ToListAsync();
|
||||
|
||||
|
||||
// получаем только работы по которым есть шаблоны (активированные/деакт) и за любой период
|
||||
IQueryable<DAL.Models.Template> appInWorksQuery = templateService.Get()
|
||||
.Include(t => t.Host)
|
||||
.Include(t => t.ApplicationsInWork).ThenInclude(t => t.Application).ThenInclude(t => t.ApplicationType);
|
||||
// // получаем только работы по которым есть шаблоны (активированные/деакт) и за любой период
|
||||
// IQueryable<DAL.Models.Template> appInWorksQuery = templateService.Get()
|
||||
// .Include(t => t.Host)
|
||||
// .Include(t => t.ApplicationsInWork).ThenInclude(t => t.Application).ThenInclude(t => t.ApplicationType);
|
||||
|
||||
IQueryable<WorkGroup> workGroupsQuery = workGroupService.Get()
|
||||
.Include(t => t.ResponseArea);
|
||||
// IQueryable<WorkGroup> workGroupsQuery = workGroupService.Get()
|
||||
// .Include(t => t.ResponseArea);
|
||||
|
||||
|
||||
if (workGroupId.HasValue)
|
||||
{
|
||||
appInWorksQuery = appInWorksQuery.Where(t => t.Host.WorkGroupId == workGroupId);
|
||||
workGroupsQuery = workGroupsQuery.Where(t => t.Id == workGroupId.Value);
|
||||
}
|
||||
// if (workGroupId.HasValue)
|
||||
// {
|
||||
// appInWorksQuery = appInWorksQuery.Where(t => t.Host.WorkGroupId == workGroupId);
|
||||
// workGroupsQuery = workGroupsQuery.Where(t => t.Id == workGroupId.Value);
|
||||
// }
|
||||
|
||||
if (jobsRequests != null && jobsRequests.Count() > 0)
|
||||
{
|
||||
//appInWorksQuery = appInWorksQuery.Where(t => jobsRequests.Any(x => x.JobId == t.ApplicationInWorkId));
|
||||
appInWorksQuery = appInWorksQuery.Where(t => jobsRequests.Select(j => j.JobId).Any(x => x == t.ApplicationInWorkId));
|
||||
workGroupsQuery = workGroupsQuery.Where(t => jobsRequests.Select(w => w.WorkGroupId).Any(x => x == t.Id));
|
||||
}
|
||||
// if (jobsRequests != null && jobsRequests.Count() > 0)
|
||||
// {
|
||||
// //appInWorksQuery = appInWorksQuery.Where(t => jobsRequests.Any(x => x.JobId == t.ApplicationInWorkId));
|
||||
// appInWorksQuery = appInWorksQuery.Where(t => jobsRequests.Select(j => j.JobId).Any(x => x == t.ApplicationInWorkId));
|
||||
// workGroupsQuery = workGroupsQuery.Where(t => jobsRequests.Select(w => w.WorkGroupId).Any(x => x == t.Id));
|
||||
// }
|
||||
|
||||
|
||||
var appInWorks = await appInWorksQuery.Select(t => t.ApplicationsInWork)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
// var appInWorks = await appInWorksQuery.Select(t => t.ApplicationsInWork)
|
||||
// .Distinct()
|
||||
// .ToListAsync();
|
||||
|
||||
var workGroups = await workGroupsQuery.Distinct().ToListAsync();
|
||||
// var workGroups = await workGroupsQuery.Distinct().ToListAsync();
|
||||
|
||||
|
||||
var response = new List<StatWorkWorkLoadResponse>();
|
||||
// var response = new List<StatWorkWorkLoadResponse>();
|
||||
|
||||
appInWorks.ForEach(appInWork =>
|
||||
{
|
||||
workGroups.ForEach(workGroup =>
|
||||
{
|
||||
var workLoads = daysList.Select(t => new StatWorkLoadDataResponse
|
||||
{
|
||||
Date = t,
|
||||
TemplateCount = queryResult.FirstOrDefault(x => x.ApplicationInWorkId == appInWork.Id && DateOnly.FromDateTime(x.Date) == t && x.WorkGroupId == workGroup.Id)?.TemplateCount ?? 0
|
||||
}).OrderBy(t => t.Date).ToList();
|
||||
// appInWorks.ForEach(appInWork =>
|
||||
// {
|
||||
// workGroups.ForEach(workGroup =>
|
||||
// {
|
||||
// var workLoads = daysList.Select(t => new StatWorkLoadDataResponse
|
||||
// {
|
||||
// Date = t,
|
||||
// TemplateCount = queryResult.FirstOrDefault(x => x.ApplicationInWorkId == appInWork.Id && DateOnly.FromDateTime(x.Date) == t && x.WorkGroupId == workGroup.Id)?.TemplateCount ?? 0
|
||||
// }).OrderBy(t => t.Date).ToList();
|
||||
|
||||
response.Add(new StatWorkWorkLoadResponse
|
||||
{
|
||||
Job = mapper.Map<ApplicationInWorkBaseResponse>(appInWork),
|
||||
WorkGroup = mapper.Map<WorkGroupResponse>(workGroup),
|
||||
WorkLoad = workLoads
|
||||
});
|
||||
});
|
||||
});
|
||||
// response.Add(new StatWorkWorkLoadResponse
|
||||
// {
|
||||
// Job = mapper.Map<ApplicationInWorkBaseResponse>(appInWork),
|
||||
// WorkGroup = mapper.Map<WorkGroupResponse>(workGroup),
|
||||
// WorkLoad = workLoads
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// убираем не нужные значения так как запрос в SQL (query) был с несколькими Any
|
||||
if (jobsRequests != null && jobsRequests.Count() > 0)
|
||||
response = response.Where(t => jobsRequests.Any(x => x.WorkGroupId == t.WorkGroup.Id && x.JobId == t.Job.Id)).ToList();
|
||||
// // убираем не нужные значения так как запрос в SQL (query) был с несколькими Any
|
||||
// if (jobsRequests != null && jobsRequests.Count() > 0)
|
||||
// response = response.Where(t => jobsRequests.Any(x => x.WorkGroupId == t.WorkGroup.Id && x.JobId == t.Job.Id)).ToList();
|
||||
|
||||
response = response.OrderBy(t => t.Job.ShortDescription).ThenBy(t => t.Job.Application?.Name).ThenBy(t => t.WorkGroup.Name).ToList();
|
||||
// response = response.OrderBy(t => t.Job.ShortDescription).ThenBy(t => t.Job.Application?.Name).ThenBy(t => t.WorkGroup.Name).ToList();
|
||||
|
||||
return response;
|
||||
}
|
||||
// return response;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace PARR.API.Controllers.V1
|
||||
query = query.Where(t => EF.Functions.Like(t.Name.ToLower(), SqlHelpers.RegexToLike(filter.Mask)));
|
||||
|
||||
if (filter.AppInWorkId.HasValue)
|
||||
query = query.Where(t => t.ApplicationInWorkId == filter.AppInWorkId.Value);
|
||||
query = query.Where(t => t.JobId == filter.AppInWorkId.Value);//TODO Migration to job
|
||||
|
||||
var templates = await templateService.GetPage(query, paginationFilter).ToListAsync();
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace PARR.API.Controllers.V1
|
||||
private readonly IUnitService unitService;
|
||||
private readonly IFieldFilterService fieldFilterService;
|
||||
private readonly IJobService jobService;
|
||||
private readonly IJobDetailsService jobDetailsService;
|
||||
private readonly IJobUnitFilterService jobUnitFilterService;
|
||||
|
||||
public TestController(
|
||||
IClientService clientService,
|
||||
@@ -33,7 +33,7 @@ namespace PARR.API.Controllers.V1
|
||||
IUnitService unitService,
|
||||
IFieldFilterService fieldFilterService,
|
||||
IJobService jobService,
|
||||
IJobDetailsService jobDetailsService
|
||||
IJobUnitFilterService jobUnitFilterService
|
||||
)
|
||||
{
|
||||
this.clientService = clientService;
|
||||
@@ -43,7 +43,7 @@ namespace PARR.API.Controllers.V1
|
||||
this.unitService = unitService;
|
||||
this.fieldFilterService = fieldFilterService;
|
||||
this.jobService = jobService;
|
||||
this.jobDetailsService = jobDetailsService;
|
||||
this.jobUnitFilterService = jobUnitFilterService;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using PARR.Constants.Shortcodes;
|
||||
using PARR.DAL.DomainModels;
|
||||
using PARR.DAL.Extensions;
|
||||
using PARR.DAL.Models;
|
||||
using PARR.DAL.Models.Job;
|
||||
using PARR.DAL.Models.Unit;
|
||||
|
||||
namespace PARR.API.MappingProfiles
|
||||
@@ -19,27 +20,27 @@ namespace PARR.API.MappingProfiles
|
||||
|
||||
// --- Template ---
|
||||
CreateMap<Template, TemplateResponse>()
|
||||
.ForMember(d => d.Work, o => o.MapFrom(s => s.ApplicationsInWork!.Work))
|
||||
.ForMember(d => d.Host, o => o.MapFrom(s => s.Host))
|
||||
.ForMember(d => d.Process, o => o.MapFrom(s => s.ApplicationsInWork!.Work!.Tnk!.Subprocess!.Process))
|
||||
.ForMember(d => d.Subprocess, o => o.MapFrom(s => s.ApplicationsInWork!.Work!.Tnk!.Subprocess))
|
||||
.ForMember(d => d.Tnk, o => o.MapFrom(s => s.ApplicationsInWork!.Work!.Tnk))
|
||||
.ForMember(d => d.ShortDescription, o => o.MapFrom(s => s.ApplicationsInWork!.ShortDescription))
|
||||
.ForMember(d => d.FullDescription, o => o.MapFrom(s => s.ApplicationsInWork!.FullDescription))
|
||||
.ForMember(d => d.Solution, o => o.MapFrom(s => s.ApplicationsInWork!.Solution))
|
||||
.ForMember(d => d.TemplateDuration, o => o.MapFrom(s => s.ApplicationsInWork!.TemplateDuration))
|
||||
.ForMember(d => d.Job, o => o.MapFrom(s => s.Job))
|
||||
.ForMember(d => d.Unit, o => o.MapFrom(s => s.Unit))
|
||||
.ForMember(d => d.Process, o => o.MapFrom(s => s.Job!.Tnk!.Subprocess!.Process))
|
||||
.ForMember(d => d.Subprocess, o => o.MapFrom(s => s.Job!.Tnk!.Subprocess))
|
||||
.ForMember(d => d.Tnk, o => o.MapFrom(s => s.Job!.Tnk))
|
||||
.ForMember(d => d.ShortDescription, o => o.MapFrom(s => s.Job!.Group!.ShortDescription))
|
||||
.ForMember(d => d.FullDescription, o => o.MapFrom(s => s.Job!.Group!.FullDescription))
|
||||
.ForMember(d => d.Solution, o => o.MapFrom(s => s.Job!.Group!.Solution))
|
||||
.ForMember(d => d.TemplateDuration, o => o.MapFrom(s => s.Job!.Group!.TemplateDuration))
|
||||
.ForMember(d => d.Initiator, o => o.MapFrom<TemplateInitiatorResolver>())
|
||||
.ForMember(d => d.ClosingCode, o => o.MapFrom<TemplateClosingCodeResolver>())
|
||||
.ForMember(d => d.Category, o => o.MapFrom<TemplateCategoryResolver>())
|
||||
.ForMember(d => d.SyncStatus, o => o.MapFrom(s => s.RobotConfigurations.OrderBy(t => t.RobotCode)))
|
||||
.ForMember(d => d.Schedule, o => o.MapFrom<TemplateScheduleResolver>())
|
||||
.ForMember(d => d.Agent, o => o.MapFrom(s => s.ApplicationsInWork))
|
||||
.ForMember(d => d.Agent, o => o.MapFrom(s => s.Job!.Group!))
|
||||
//.ForMember(d => d.NextRun, o => o.MapFrom(s => s.ApplicationsInWork!.NextRun))
|
||||
//.ForMember(d => d.LastRun, o => o.MapFrom(s => s.ApplicationsInWork!.LastRun))
|
||||
.ForMember(d => d.NextRun, o => o.MapFrom(s => s.NextRun))
|
||||
.ForMember(d => d.LastRun, o => o.MapFrom(s => s.LastRun))
|
||||
.ForMember(d => d.OrderCount, o => o.MapFrom(s => s.Orders.Count()))
|
||||
.ForMember(d => d.IsAutoDistributionEnabled, o => o.MapFrom(s => s.ApplicationsInWork!.IsAutoDistributionEnabled));
|
||||
.ForMember(d => d.IsAutoDistributionEnabled, o => o.MapFrom(s => s.Job!.Group!.IsAutoDistributionEnabled));
|
||||
// === Template ===
|
||||
|
||||
|
||||
@@ -156,36 +157,36 @@ namespace PARR.API.MappingProfiles
|
||||
CreateMap<RobotConfiguration, RobotTaskTemplateResponse>()
|
||||
.ForMember(d => d.IsActive, o => o.MapFrom(s => s.Template!.IsActiveTemplate))
|
||||
.ForMember(d => d.ClosingCode, o => o.MapFrom<RobotTaskTemplateClosingCodeResolver>())
|
||||
.ForMember(d => d.FullDescription, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.FullDescription))
|
||||
.ForMember(d => d.ShortDescription, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.ShortDescription.ApplyShortcode(ShortcodeEnum.EK, s.Template!.Host!.Ek)))
|
||||
.ForMember(d => d.Solution, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Solution))
|
||||
.ForMember(d => d.FullDescription, o => o.MapFrom(s => s.Template!.Job!.Group!.FullDescription))
|
||||
.ForMember(d => d.ShortDescription, o => o.MapFrom(s => s.Template!.Job!.Group!.ShortDescription.ApplyShortcode(ShortcodeEnum.EK, s.Template!.Unit!.Name)))
|
||||
.ForMember(d => d.Solution, o => o.MapFrom(s => s.Template!.Job!.Group!.Solution))
|
||||
//.ForMember(d => d.ResponseArea, o => o.MapFrom(s => s.Template!.Host!.ResponseArea!.Name))
|
||||
//ЗО берем у группы а не у хоста
|
||||
.ForMember(d => d.ResponseArea, o => o.MapFrom(s => s.Template!.Host!.WorkGroup!.ResponseArea!.Name))
|
||||
.ForMember(d => d.TemplateDuration, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.TemplateDuration))
|
||||
.ForMember(d => d.ResponseArea, o => o.MapFrom(s => s.Template!.Unit.BaseFields.ResponseArea))
|
||||
.ForMember(d => d.TemplateDuration, o => o.MapFrom(s => s.Template!.Job!.Group!.TemplateDuration))
|
||||
.ForMember(d => d.Initiator, o => o.MapFrom<RobotTaskTemplateInitiatorResolver>())
|
||||
.ForMember(d => d.Category, o => o.MapFrom<RobotTaskTemplateCategoryResolver>())
|
||||
.ForMember(d => d.WorkGroup, o => o.MapFrom(s => s.Template!.Host!.WorkGroup!.Name))
|
||||
.ForMember(d => d.Ek, o => o.MapFrom(s => s.Template!.Host!.Ek))
|
||||
.ForMember(d => d.WorkGroup, o => o.MapFrom(s => s.Template!.Unit.BaseFields.WorkGroup))
|
||||
.ForMember(d => d.Ek, o => o.MapFrom(s => s.Template!.Unit.Name))
|
||||
.ForMember(d => d.Name, o => o.MapFrom(s => s.Template!.Name))
|
||||
.ForMember(d => d.ProcessName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Subprocess!.Process!.Name))
|
||||
.ForMember(d => d.ProcessEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Subprocess!.Process!.EsppId))
|
||||
.ForMember(d => d.SubprocessName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Subprocess!.Name))
|
||||
.ForMember(d => d.SubprocessEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Subprocess!.EsppId))
|
||||
.ForMember(d => d.TnkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.Name.ApplyShortcode(ShortcodeEnum.EK, s.Template!.Host!.Ek)))
|
||||
.ForMember(d => d.TnkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Tnk!.EsppId))
|
||||
.ForMember(d => d.WorkName, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.Name.ApplyShortcode(ShortcodeEnum.EK, s.Template!.Host!.Ek)))
|
||||
.ForMember(d => d.WorkEsppId, o => o.MapFrom(s => s.Template!.ApplicationsInWork!.Work!.EsppId))
|
||||
.ForMember(d => d.ProcessName, o => o.MapFrom(s => s.Template!.Job!.Tnk!.Subprocess!.Process!.Name))
|
||||
.ForMember(d => d.ProcessEsppId, o => o.MapFrom(s => s.Template!.Job!.Tnk!.Subprocess!.Process!.EsppId))
|
||||
.ForMember(d => d.SubprocessName, o => o.MapFrom(s => s.Template!.Job!.Tnk!.Subprocess!.Name))
|
||||
.ForMember(d => d.SubprocessEsppId, o => o.MapFrom(s => s.Template!.Job!.Tnk!.Subprocess!.EsppId))
|
||||
.ForMember(d => d.TnkName, o => o.MapFrom(s => s.Template!.Job!.Tnk!.Name.ApplyShortcode(ShortcodeEnum.EK, s.Template!.Unit!.Name)))
|
||||
.ForMember(d => d.TnkEsppId, o => o.MapFrom(s => s.Template!.Job!.Tnk!.EsppId))
|
||||
.ForMember(d => d.WorkName, o => o.MapFrom(s => s.Template!.Job!.Name.ApplyShortcode(ShortcodeEnum.EK, s.Template!.Unit!.Name)))
|
||||
//.ForMember(d => d.WorkEsppId, o => o.MapFrom(s => s.Template!.Job!.EsppId))
|
||||
.ForMember(d => d.ScheduleEsppId, o => o.MapFrom(s => s.Template!.ScheduleEsppId));
|
||||
|
||||
CreateMap<RobotConfiguration, RobotTaskScheduleResponse>()
|
||||
.ForMember(d => d.EsppId, o => o.MapFrom(s => s.Template!.ScheduleEsppId))
|
||||
.ForMember(d => d.ScheduleName, o => o.MapFrom(s => s.Template!.Name))
|
||||
.ForMember(d => d.IsActive, o => o.MapFrom(s => s.Template!.IsActiveSchedule))
|
||||
.ForMember(d => d.ResponseArea, o => o.MapFrom(s => s.Template!.Host!.ResponseArea!.Name))
|
||||
.ForMember(d => d.ResponseArea, o => o.MapFrom(s => s.Template!.Unit!.BaseFields!.ResponseArea))
|
||||
.ForMember(d => d.TemplateName, o => o.MapFrom(s => s.Template!.Name))
|
||||
.ForMember(d => d.TemplateId, o => o.MapFrom(s => s.Template!.Id))
|
||||
.ForMember(d => d.WorkGroup, o => o.MapFrom(s => s.Template!.Host!.WorkGroup!.Name))
|
||||
.ForMember(d => d.WorkGroup, o => o.MapFrom(s => s.Template!.Unit!.BaseFields!.WorkGroup))
|
||||
.ForMember(d => d.Exclude, o => o.MapFrom<RobotTaskScheduleExcludeResolver>())
|
||||
.ForMember(d => d.Timezone, o => o.MapFrom<RobotTaskScheduleTimezoneResolver>())
|
||||
.ForMember(d => d.RepeatRange, o => o.MapFrom<RobotTaskScheduleRepeatRangeResolver>())
|
||||
@@ -195,9 +196,9 @@ namespace PARR.API.MappingProfiles
|
||||
//.ForMember(d => d.NextStart, o => o.MapFrom(s => EsppScheduleHelpers.GetNextRun(s.Template!.NextRun)))
|
||||
.ForMember(d => d.NextStart, o => o.MapFrom<RobotTaskScheduleNextStartResolver>())
|
||||
.ForMember(d => d.ScheduleType, o => o.MapFrom(s =>
|
||||
s.Template!.ApplicationsInWork!.EsppSchValues!.First()!.EsppSchTypeConfig!.EsppSchTypeSchedule!.Description))
|
||||
s.Template!.Job!.Group!.EsppSchValues!.First()!.EsppSchTypeConfig!.EsppSchTypeSchedule!.Description))
|
||||
.ForMember(d => d.ScheduleTypeCode, o => o.MapFrom(s =>
|
||||
s.Template!.ApplicationsInWork!.EsppSchValues!.First()!.EsppSchTypeConfig!.EsppSchTypeSchedule!.Id))
|
||||
s.Template!.Job!.Group!.EsppSchValues!.First()!.EsppSchTypeConfig!.EsppSchTypeSchedule!.Id))
|
||||
.ForMember(d => d.Schedule, o => o.MapFrom<RobotTaskScheduleSchResolver>());
|
||||
// === RobotConfiguration ===
|
||||
#endregion
|
||||
@@ -291,13 +292,20 @@ namespace PARR.API.MappingProfiles
|
||||
|
||||
CreateMap<ApplicationsInWork, ApplicationInWorkResponse>()
|
||||
.ForMember(d => d.Work, o => o.MapFrom(s => s.Work))
|
||||
.ForMember(d => d.TemplatesCount, o => o.MapFrom(s => s.Templates.Count()))
|
||||
//.ForMember(d => d.TemplatesCount, o => o.MapFrom(s => s.Templates.Count()))
|
||||
.ForMember(d => d.Schedule, o => o.MapFrom<ApplicationInWorkScheduleResolver>())
|
||||
.ForMember(d => d.WorkGroups, o => o.MapFrom(s => s.WorkGroups.OrderBy(t => t.WorkGroup.Name).Select(t => t.WorkGroup)))
|
||||
.ForMember(d => d.WorkGroups, o => o.MapFrom(s => s.WorkGroups.OrderBy(t => t.WorkGroup!.Name).Select(t => t.WorkGroup)))
|
||||
.ForMember(d => d.AutoControl, o => o.MapFrom(s => s.JobAutoControl));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Job
|
||||
CreateMap<Job, JobBaseResponse>()
|
||||
.Include<Job, JobResponse>();
|
||||
|
||||
CreateMap<Job, JobResponse>();
|
||||
#endregion
|
||||
|
||||
#region JobAutoControl
|
||||
|
||||
CreateMap<JobAutoControl, JobAutoControlBaseResponse>()
|
||||
@@ -306,7 +314,7 @@ namespace PARR.API.MappingProfiles
|
||||
CreateMap<JobAutoControl, JobAutoControlResponse>()
|
||||
.ForMember(d => d.EkMasks, o => o.MapFrom(s => s.JobEkMasks.OrderBy(t => t.Name)))
|
||||
.ForMember(d => d.EnabledEkStatuses, o => o.MapFrom(s => s.JobAutoControlInEkStatuses.Select(t => t.EkStatus).OrderBy(t => t.Name)))
|
||||
.ForMember(d => d.WorkGroups, o => o.MapFrom(s => s.ApplicationsInWork.WorkGroups.Select(t => t.WorkGroup).OrderBy(t => t.Name)));
|
||||
.ForMember(d => d.WorkGroups, o => o.MapFrom(s => s.ApplicationsInWork!.WorkGroups.Select(t => t.WorkGroup).OrderBy(t => t.Name)));
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace PARR.API.MappingProfiles.Resolvers
|
||||
|
||||
public List<RobotTaskScheduleSchResponse>? Resolve(RobotConfiguration source, RobotTaskScheduleResponse destination, List<RobotTaskScheduleSchResponse>? destMember, ResolutionContext context)
|
||||
{
|
||||
var appInWorksId = source.Template!.ApplicationInWorkId;
|
||||
var appInWorksId = source.Template!.JobId;
|
||||
|
||||
var schedule = esppConfigService.GetEsppScheduleDto(appInWorksId);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace PARR.API.MappingProfiles.Resolvers
|
||||
}).OrderBy(t => t.Order).ToList();
|
||||
|
||||
//Если задача относится к распределенной модели исполнения за период месяц устанавливаем день равный NextRun
|
||||
if (source.Template!.ApplicationsInWork!.IsAutoDistributionEnabled && schedule.TypeSchedule.Id == (int)EsppSchTypeScheduleEnum.Monthly)
|
||||
if (source.Template!.Job!.Group!.IsAutoDistributionEnabled && schedule.TypeSchedule.Id == (int)EsppSchTypeScheduleEnum.Monthly)
|
||||
{
|
||||
var nextRunForRobot = nextRunModifierService.GetNextRunByAccountRobotTimeZone(source.Template.NextRun);
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@ namespace PARR.API.MappingProfiles.Resolvers
|
||||
|
||||
public EsppScheduleResponse? Resolve(Template source, TemplateResponse destination, EsppScheduleResponse? destMember, ResolutionContext context)
|
||||
{
|
||||
var schedule = esppConfigService.GetEsppScheduleDto(source.ApplicationInWorkId);
|
||||
var schedule = esppConfigService.GetEsppScheduleDto(source.Job!.GroupId);
|
||||
|
||||
if (schedule == null)
|
||||
{
|
||||
logger.LogError($"TemplateScheduleResolver: Не смог замапить расписание для робота, так как оно null. appInWorksId: {source.ApplicationInWorkId}");
|
||||
logger.LogError($"TemplateScheduleResolver: Не смог замапить расписание для робота, так как оно null. appInWorksId: {source.Job!.GroupId}");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,11 @@ namespace PARR.DAL.Context
|
||||
|
||||
public DbSet<Job> Jobs { get; set; }
|
||||
|
||||
public DbSet<JobUnitFilter> JobDetails { get; set; }
|
||||
public DbSet<JobUnitFilter> JobUnitFilters { get; set; }
|
||||
|
||||
public DbSet<JobGroup> JobGroups { get; set; }
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
3773
PARR.DAL/Migrations/20250625035851_tblTemplatesMigrationFormApplicationInWork.Designer.cs
generated
Normal file
3773
PARR.DAL/Migrations/20250625035851_tblTemplatesMigrationFormApplicationInWork.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PARR.DAL.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class tblTemplatesMigrationFormApplicationInWork : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_EsppSchValues_ApplicationsInWorks_ApplicationsInWorkId",
|
||||
table: "EsppSchValues");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Templates_ApplicationsInWorks_ApplicationInWorkId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Templates_Hosts_HostId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Templates_ApplicationInWorkId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Templates_HostId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ApplicationInWorkId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "HostId",
|
||||
table: "Templates");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "Duration",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
newName: "TemplateDuration");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "ApplicationsInWorkId",
|
||||
table: "EsppSchValues",
|
||||
newName: "JobGroupId");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AgentName",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AgentScript",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AgentTimeOutSec",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
type: "integer",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsAgent",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsAutoDistributionEnabled",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_EsppSchValues_Groups_JobGroupId",
|
||||
table: "EsppSchValues",
|
||||
column: "JobGroupId",
|
||||
principalSchema: "job",
|
||||
principalTable: "Groups",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_EsppSchValues_Groups_JobGroupId",
|
||||
table: "EsppSchValues");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AgentName",
|
||||
schema: "job",
|
||||
table: "Groups");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AgentScript",
|
||||
schema: "job",
|
||||
table: "Groups");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AgentTimeOutSec",
|
||||
schema: "job",
|
||||
table: "Groups");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsAgent",
|
||||
schema: "job",
|
||||
table: "Groups");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsAutoDistributionEnabled",
|
||||
schema: "job",
|
||||
table: "Groups");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "TemplateDuration",
|
||||
schema: "job",
|
||||
table: "Groups",
|
||||
newName: "Duration");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "JobGroupId",
|
||||
table: "EsppSchValues",
|
||||
newName: "ApplicationsInWorkId");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "ApplicationInWorkId",
|
||||
table: "Templates",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "HostId",
|
||||
table: "Templates",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_ApplicationInWorkId",
|
||||
table: "Templates",
|
||||
column: "ApplicationInWorkId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Templates_HostId",
|
||||
table: "Templates",
|
||||
column: "HostId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_EsppSchValues_ApplicationsInWorks_ApplicationsInWorkId",
|
||||
table: "EsppSchValues",
|
||||
column: "ApplicationsInWorkId",
|
||||
principalTable: "ApplicationsInWorks",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Templates_ApplicationsInWorks_ApplicationInWorkId",
|
||||
table: "Templates",
|
||||
column: "ApplicationInWorkId",
|
||||
principalTable: "ApplicationsInWorks",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Templates_Hosts_HostId",
|
||||
table: "Templates",
|
||||
column: "HostId",
|
||||
principalTable: "Hosts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1477,7 +1477,7 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.EsppSchValue", b =>
|
||||
{
|
||||
b.Property<Guid>("ApplicationsInWorkId")
|
||||
b.Property<Guid>("JobGroupId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("TypeValueId")
|
||||
@@ -1486,7 +1486,7 @@ namespace PARR.DAL.Migrations
|
||||
b.Property<Guid>("TypeConfigId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("ApplicationsInWorkId", "TypeValueId", "TypeConfigId");
|
||||
b.HasKey("JobGroupId", "TypeValueId", "TypeConfigId");
|
||||
|
||||
b.HasIndex("TypeConfigId");
|
||||
|
||||
@@ -1629,16 +1629,21 @@ namespace PARR.DAL.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("AgentName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("AgentScript")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("AgentTimeOutSec")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTimeOffset>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTimeOffset?>("DateModified")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Duration")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FullDescription")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
@@ -1647,6 +1652,12 @@ namespace PARR.DAL.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsAgent")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAutoDistributionEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool?>("IsUmbrella")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
@@ -1661,6 +1672,10 @@ namespace PARR.DAL.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("TemplateDuration")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Groups", "job", t =>
|
||||
@@ -2559,18 +2574,12 @@ namespace PARR.DAL.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ApplicationInWorkId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTimeOffset>("DateCreated")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTimeOffset?>("DateModified")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("HostId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("InitiatorComment")
|
||||
.HasColumnType("text");
|
||||
|
||||
@@ -2607,10 +2616,6 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ApplicationInWorkId");
|
||||
|
||||
b.HasIndex("HostId");
|
||||
|
||||
b.HasIndex("JobId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
@@ -3143,9 +3148,9 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.EsppSchValue", b =>
|
||||
{
|
||||
b.HasOne("PARR.DAL.Models.ApplicationsInWork", "ApplicationsInWork")
|
||||
b.HasOne("PARR.DAL.Models.Job.JobGroup", "JobGroup")
|
||||
.WithMany("EsppSchValues")
|
||||
.HasForeignKey("ApplicationsInWorkId")
|
||||
.HasForeignKey("JobGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
@@ -3161,11 +3166,11 @@ namespace PARR.DAL.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ApplicationsInWork");
|
||||
|
||||
b.Navigation("EsppSchTypeConfig");
|
||||
|
||||
b.Navigation("EsppSchTypeValue");
|
||||
|
||||
b.Navigation("JobGroup");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.Host", b =>
|
||||
@@ -3215,7 +3220,7 @@ namespace PARR.DAL.Migrations
|
||||
modelBuilder.Entity("PARR.DAL.Models.Job.Job", b =>
|
||||
{
|
||||
b.HasOne("PARR.DAL.Models.Job.JobGroup", "Group")
|
||||
.WithMany("Job")
|
||||
.WithMany("Jobs")
|
||||
.HasForeignKey("GroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@@ -3381,18 +3386,6 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.Template", b =>
|
||||
{
|
||||
b.HasOne("PARR.DAL.Models.ApplicationsInWork", "ApplicationsInWork")
|
||||
.WithMany("Templates")
|
||||
.HasForeignKey("ApplicationInWorkId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PARR.DAL.Models.Host", "Host")
|
||||
.WithMany("Templates")
|
||||
.HasForeignKey("HostId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PARR.DAL.Models.Job.Job", "Job")
|
||||
.WithMany()
|
||||
.HasForeignKey("JobId")
|
||||
@@ -3400,15 +3393,11 @@ namespace PARR.DAL.Migrations
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PARR.DAL.Models.Unit.Unit", "Unit")
|
||||
.WithMany()
|
||||
.WithMany("Templates")
|
||||
.HasForeignKey("UnitId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ApplicationsInWork");
|
||||
|
||||
b.Navigation("Host");
|
||||
|
||||
b.Navigation("Job");
|
||||
|
||||
b.Navigation("Unit");
|
||||
@@ -3580,12 +3569,8 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.ApplicationsInWork", b =>
|
||||
{
|
||||
b.Navigation("EsppSchValues");
|
||||
|
||||
b.Navigation("JobAutoControl");
|
||||
|
||||
b.Navigation("Templates");
|
||||
|
||||
b.Navigation("WorkGroups");
|
||||
});
|
||||
|
||||
@@ -3631,8 +3616,6 @@ namespace PARR.DAL.Migrations
|
||||
modelBuilder.Entity("PARR.DAL.Models.Host", b =>
|
||||
{
|
||||
b.Navigation("ApplicationsInHosts");
|
||||
|
||||
b.Navigation("Templates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.Job.Job", b =>
|
||||
@@ -3642,7 +3625,9 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.Job.JobGroup", b =>
|
||||
{
|
||||
b.Navigation("Job");
|
||||
b.Navigation("EsppSchValues");
|
||||
|
||||
b.Navigation("Jobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PARR.DAL.Models.Job.JobUnitFilter", b =>
|
||||
@@ -3740,6 +3725,8 @@ namespace PARR.DAL.Migrations
|
||||
|
||||
b.Navigation("ParentUnits");
|
||||
|
||||
b.Navigation("Templates");
|
||||
|
||||
b.Navigation("UnitFields");
|
||||
|
||||
b.Navigation("UnitValues");
|
||||
|
||||
@@ -111,9 +111,9 @@ namespace PARR.DAL.Models
|
||||
[ForeignKey(nameof(ApplicationId))]
|
||||
public Application? Application { get; set; }
|
||||
|
||||
public ICollection<Template> Templates { get; set; } = new HashSet<Template>();
|
||||
// public ICollection<Template> Templates { get; set; } = new HashSet<Template>();
|
||||
|
||||
public ICollection<EsppSchValue> EsppSchValues { get; set; } = new HashSet<EsppSchValue>();
|
||||
//public ICollection<EsppSchValue> EsppSchValues { get; set; } = new HashSet<EsppSchValue>();
|
||||
|
||||
public ICollection<AppInWorkInWorkGroup> WorkGroups { get; set; } = new HashSet<AppInWorkInWorkGroup>();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PARR.DAL.Models.Job;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace PARR.DAL.Models
|
||||
@@ -8,22 +9,28 @@ namespace PARR.DAL.Models
|
||||
/// </summary>
|
||||
[Table("EsppSchValues")]
|
||||
//[Index(nameof(ApplicationsInWorkId), nameof(TypeValueId), nameof(TypeConfigId), IsUnique = true)]
|
||||
[PrimaryKey(nameof(ApplicationsInWorkId), nameof(TypeValueId), nameof(TypeConfigId))]
|
||||
//[PrimaryKey(nameof(ApplicationsInWorkId), nameof(TypeValueId), nameof(TypeConfigId))]
|
||||
[PrimaryKey(nameof(JobGroupId), nameof(TypeValueId), nameof(TypeConfigId))]
|
||||
public class EsppSchValue
|
||||
{
|
||||
public Guid ApplicationsInWorkId { get; set; }
|
||||
//public Guid ApplicationsInWorkId { get; set; }
|
||||
|
||||
public Guid TypeValueId { get; set; }
|
||||
|
||||
public Guid TypeConfigId { get; set; }
|
||||
|
||||
[ForeignKey(nameof(ApplicationsInWorkId))]
|
||||
public ApplicationsInWork? ApplicationsInWork { get; set; }
|
||||
public Guid JobGroupId { get; set; }
|
||||
|
||||
//[ForeignKey(nameof(ApplicationsInWorkId))]
|
||||
//public ApplicationsInWork? ApplicationsInWork { get; set; }
|
||||
|
||||
[ForeignKey(nameof(TypeValueId))]
|
||||
public EsppSchTypeValue? EsppSchTypeValue { get; set; }
|
||||
|
||||
[ForeignKey(nameof(TypeConfigId))]
|
||||
public EsppSchTypeConfig? EsppSchTypeConfig { get; set; }
|
||||
|
||||
[ForeignKey(nameof(JobGroupId))]
|
||||
public JobGroup? JobGroup { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace PARR.DAL.Models
|
||||
|
||||
public ICollection<ApplicationInHost> ApplicationsInHosts { get; set; } = new HashSet<ApplicationInHost>();
|
||||
|
||||
public ICollection<Template> Templates { get; set; } = new HashSet<Template>();
|
||||
//public ICollection<Template> Templates { get; set; } = new HashSet<Template>();
|
||||
|
||||
|
||||
[ForeignKey(nameof(EkStatusCode))]
|
||||
|
||||
@@ -45,14 +45,61 @@ namespace PARR.DAL.Models.Job
|
||||
/// <summary>
|
||||
/// Поле Длительность описания шаблона АСУ ЕСПП
|
||||
/// </summary>
|
||||
public required string Duration { get; set; }
|
||||
public required string TemplateDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TemplateDuration в формате TimeSpan
|
||||
/// </summary>
|
||||
public TimeSpan? TemplateDurationTimeSpan
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
//ЕСПП кривоногие, они почему-то таймспан пишут так "7 00:00:00", а правильно так: "7:00:00:00"
|
||||
var durationWithTimeSpanFormat = TemplateDuration.Replace(" ", ":");
|
||||
|
||||
return TimeSpan.Parse(durationWithTimeSpanFormat);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Дата начала работ или дата для отсчёта периода следующего выполнения
|
||||
/// </summary>
|
||||
public DateTimeOffset ReferenceDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Включить автораспределение
|
||||
/// </summary>
|
||||
public bool IsAutoDistributionEnabled { get; set; }
|
||||
|
||||
public ICollection<Job> Job { get; set; } = new HashSet<Job>();
|
||||
/// <summary>
|
||||
/// Выполняет агент
|
||||
/// </summary>
|
||||
public bool IsAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Какое-то имя которое мы передаем агенту, пока непонятно что это такое.
|
||||
/// </summary>
|
||||
public string? AgentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Сколько времени ожидать выполнение скрипта агентом (секунд)
|
||||
/// </summary>
|
||||
public int? AgentTimeOutSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Скрипт для автоматического выполнения
|
||||
/// </summary>
|
||||
public string? AgentScript { get; set; }
|
||||
|
||||
public ICollection<Job> Jobs { get; set; } = new HashSet<Job>();
|
||||
|
||||
public ICollection<EsppSchValue> EsppSchValues { get; set; } = new HashSet<EsppSchValue>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,13 +48,13 @@ namespace PARR.DAL.Models
|
||||
|
||||
public DateTimeOffset NextRun { get; set; }
|
||||
|
||||
public Guid ApplicationInWorkId { get; set; }
|
||||
//public Guid ApplicationInWorkId { get; set; }
|
||||
|
||||
public Guid JobId { get; set; }//TODO Вернуть не NULL!!!
|
||||
|
||||
public Guid UnitId { get; set; }//TODO Вернуть не NULL!!!
|
||||
|
||||
public Guid HostId { get; set; }
|
||||
//public Guid HostId { get; set; }
|
||||
|
||||
#region Initiator
|
||||
public string? InitiatorIp { get; set; }
|
||||
@@ -64,11 +64,11 @@ namespace PARR.DAL.Models
|
||||
public string? InitiatorComment { get; set; }
|
||||
#endregion
|
||||
|
||||
[ForeignKey(nameof(ApplicationInWorkId))]
|
||||
public ApplicationsInWork? ApplicationsInWork { get; set; }
|
||||
//[ForeignKey(nameof(ApplicationInWorkId))]
|
||||
//public ApplicationsInWork? ApplicationsInWork { get; set; }
|
||||
|
||||
[ForeignKey(nameof(HostId))]
|
||||
public Host? Host { get; set; }
|
||||
//[ForeignKey(nameof(HostId))]
|
||||
//public Host? Host { get; set; }
|
||||
|
||||
[ForeignKey(nameof(JobId))]
|
||||
public Job.Job? Job { get; set; }
|
||||
|
||||
@@ -28,6 +28,28 @@ namespace PARR.DAL.Models.Unit
|
||||
// todo: добавить еще поля??? (которые есть у всех ЭК)
|
||||
|
||||
|
||||
[NotMapped]
|
||||
public BaseFields? BaseFields
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
if (UnitValues.Any())
|
||||
{
|
||||
var result = new BaseFields();
|
||||
|
||||
result.IP = UnitValues.FirstOrDefault(t => t.Field?.AihitName == "IP_АДРЕС")?.Value?.Value;
|
||||
result.ResponseArea = UnitValues.FirstOrDefault(t => t.Field?.AihitName == "ЗО_РГ")?.Value?.Value;
|
||||
result.WorkGroup = UnitValues.FirstOrDefault(t => t.Field?.AihitName == "РАБОЧАЯ_ГР_ОТВ_ЗА_ЭК")?.Value?.Value;
|
||||
result.Status = UnitValues.FirstOrDefault(t => t.Field?.AihitName == "СТАТУС")?.Value?.Value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<UnitInField> UnitFields { get; set; } = new HashSet<UnitInField>();
|
||||
|
||||
public ICollection<UnitInValue> UnitValues { get; set; } = new HashSet<UnitInValue>();
|
||||
@@ -44,5 +66,19 @@ namespace PARR.DAL.Models.Unit
|
||||
/// </summary>
|
||||
[InverseProperty(nameof(UnitInUnit.ParentUnit))]
|
||||
public ICollection<UnitInUnit> ChildUnits { get; set; } = new HashSet<UnitInUnit>();
|
||||
|
||||
public ICollection<Template> Templates { get; set; } = new HashSet<Template>();
|
||||
}
|
||||
|
||||
|
||||
public class BaseFields
|
||||
{
|
||||
public string? IP { get; set; }
|
||||
|
||||
public string? ResponseArea { get; set; }
|
||||
|
||||
public string? WorkGroup { get; set; }
|
||||
|
||||
public string? Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,8 +105,10 @@ namespace PARR.DAL
|
||||
#region Job
|
||||
|
||||
services.AddTransient<IJobService, JobService>();
|
||||
services.AddTransient<IJobDetailsService, JobDetailsService>();
|
||||
services.AddTransient<IJobGroupService, JobGroupService>();
|
||||
services.AddTransient<IJobUnitFilterService, JobUnitFilterService>();
|
||||
services.AddTransient<IFieldFilterService, FieldFilterService>();
|
||||
services.AddTransient<IJobUnitFilterService, JobUnitFilterService>();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -31,17 +31,27 @@ namespace PARR.DAL.Services.Implementations
|
||||
.ThenInclude(t => t!.EsppSchValues);
|
||||
}
|
||||
|
||||
public async Task<EsppScheduleDto?> GetEsppScheduleDtoAsync(Guid applicationInWorksId)
|
||||
public async Task<EsppScheduleDto?> GetEsppScheduleDtoAsync(Guid jobGroupId)
|
||||
{
|
||||
//Формирует расписание в нормальном понятном виде из БД
|
||||
|
||||
var test = await dataContext.EsppSchValues
|
||||
//.Include(t => t.JobGroup)
|
||||
//.Include(t => t.EsppSchTypeConfig)
|
||||
// .ThenInclude(t => t!.EsppSchTypeSchedule)
|
||||
//.Include(t => t.EsppSchTypeConfig)
|
||||
// .ThenInclude(t => t.EsppSchType)
|
||||
//.Include(t => t.EsppSchTypeValue)
|
||||
.ToListAsync();
|
||||
|
||||
var schValues = await dataContext.EsppSchValues
|
||||
.Include(t => t.EsppSchTypeConfig)
|
||||
.ThenInclude(t => t!.EsppSchTypeSchedule)
|
||||
.Include(t => t.EsppSchTypeConfig)
|
||||
.ThenInclude(t=>t.EsppSchType)
|
||||
.ThenInclude(t => t.EsppSchType)
|
||||
.Include(t => t.EsppSchTypeValue)
|
||||
.Where(t => t.ApplicationsInWorkId == applicationInWorksId)
|
||||
.Include(t => t.JobGroup)
|
||||
.Where(t => t.JobGroup!.Id == jobGroupId)//TODO Migration to job
|
||||
.OrderBy(t => t.EsppSchTypeConfig!.Order)
|
||||
.ToListAsync();
|
||||
|
||||
@@ -94,11 +104,11 @@ namespace PARR.DAL.Services.Implementations
|
||||
return dto;
|
||||
}
|
||||
|
||||
public EsppScheduleDto? GetEsppScheduleDto(Guid applicationInWorksId)
|
||||
public EsppScheduleDto? GetEsppScheduleDto(Guid jobGroupId)
|
||||
{
|
||||
var result = Task.Run(async () =>
|
||||
{
|
||||
return await GetEsppScheduleDtoAsync(applicationInWorksId);
|
||||
return await GetEsppScheduleDtoAsync(jobGroupId);
|
||||
}).Result;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -7,15 +7,15 @@ using PARR.DAL.Services.Interfaces.Job;
|
||||
|
||||
namespace PARR.DAL.Services.Implementations.Job
|
||||
{
|
||||
internal class JobDetailsService : BaseService<Models.Job.JobUnitFilter>, IJobDetailsService
|
||||
internal class JobUnitFilterService : BaseService<JobUnitFilter>, IJobUnitFilterService
|
||||
{
|
||||
private readonly DataContext dataContext;
|
||||
|
||||
protected override DbSet<JobUnitFilter> EntitySet => dataContext.JobDetails;
|
||||
protected override DbSet<JobUnitFilter> EntitySet => dataContext.JobUnitFilters;
|
||||
|
||||
protected override DataContext EntitiContext => dataContext;
|
||||
|
||||
public JobDetailsService(DataContext dataContext, ILogger<JobDetailsService> logger) : base(logger)
|
||||
public JobUnitFilterService(DataContext dataContext, ILogger<JobUnitFilterService> logger) : base(logger)
|
||||
{
|
||||
this.dataContext = dataContext;
|
||||
}
|
||||
|
||||
22
PARR.DAL/Services/Implementations/Job/JobGroupService.cs
Normal file
22
PARR.DAL/Services/Implementations/Job/JobGroupService.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.DAL.Context;
|
||||
using PARR.DAL.Models.Job;
|
||||
using PARR.DAL.Services.Abstracts;
|
||||
using PARR.DAL.Services.Interfaces.Job;
|
||||
|
||||
namespace PARR.DAL.Services.Implementations.Job
|
||||
{
|
||||
internal class JobGroupService : BaseService<Models.Job.JobGroup>, IJobGroupService
|
||||
{
|
||||
private readonly DataContext dataContext;
|
||||
|
||||
public JobGroupService(DataContext dataContext, ILogger<JobGroupService> logger) : base(logger)
|
||||
{
|
||||
this.dataContext = dataContext;
|
||||
}
|
||||
protected override DbSet<JobGroup> EntitySet => dataContext.JobGroups;
|
||||
|
||||
protected override DataContext EntitiContext => dataContext;
|
||||
}
|
||||
}
|
||||
@@ -34,18 +34,24 @@ namespace PARR.DAL.Services.Implementations
|
||||
public IQueryable<Template> GetWithIncludes()
|
||||
{
|
||||
return Get()
|
||||
.Include(h => h.Host)
|
||||
.ThenInclude(t => t!.ResponseArea)
|
||||
.Include(h => h.Host)
|
||||
.ThenInclude(t => t!.WorkGroup)
|
||||
.ThenInclude(t => t!.ResponseArea)
|
||||
.Include(h => h.Host)
|
||||
.ThenInclude(t => t!.EkStatus)
|
||||
.Include(a => a.ApplicationsInWork)
|
||||
.ThenInclude(w => w!.Work)
|
||||
.Include(h => h.Unit)
|
||||
.Include(a => a.Job)
|
||||
.ThenInclude(t => t!.Tnk)
|
||||
.ThenInclude(s => s!.Subprocess)
|
||||
.ThenInclude(p => p!.Process);
|
||||
//return Get()
|
||||
// .Include(h => h.Host)
|
||||
// .ThenInclude(t => t!.ResponseArea)
|
||||
// .Include(h => h.Host)
|
||||
// .ThenInclude(t => t!.WorkGroup)
|
||||
// .ThenInclude(t => t!.ResponseArea)
|
||||
// .Include(h => h.Host)
|
||||
// .ThenInclude(t => t!.EkStatus)
|
||||
// .Include(a => a.ApplicationsInWork)
|
||||
// .ThenInclude(w => w!.Work)
|
||||
// .ThenInclude(t => t!.Tnk)
|
||||
// .ThenInclude(s => s!.Subprocess)
|
||||
// .ThenInclude(p => p!.Process);
|
||||
}
|
||||
|
||||
public override Task<bool> CreateAsync(Template obj)
|
||||
|
||||
@@ -18,5 +18,15 @@ namespace PARR.DAL.Services.Implementations.Unit
|
||||
{
|
||||
this.dataContext = dataContext;
|
||||
}
|
||||
|
||||
|
||||
public IQueryable<Models.Unit.Unit> GetWithIncludes()
|
||||
{
|
||||
return Get()
|
||||
.Include(t => t.UnitValues)
|
||||
.ThenInclude(t => t.Field)
|
||||
.Include(t => t.UnitValues)
|
||||
.ThenInclude(t => t.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,16 @@ namespace PARR.DAL.Services.Interfaces
|
||||
/// <summary>
|
||||
/// Формирует расписание в нормальном понятном виде из БД синхронно
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorksId"></param>
|
||||
/// <param name="jobGroupId"></param>
|
||||
/// <returns></returns>
|
||||
EsppScheduleDto? GetEsppScheduleDto(Guid applicationInWorksId);
|
||||
EsppScheduleDto? GetEsppScheduleDto(Guid jobGroupId);
|
||||
|
||||
/// <summary>
|
||||
/// Формирует расписание в нормальном понятном виде из БД асинхронно
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorksId"></param>
|
||||
/// <param name="jobGroupId"></param>
|
||||
/// <returns></returns>
|
||||
Task<EsppScheduleDto?> GetEsppScheduleDtoAsync(Guid applicationInWorksId);
|
||||
Task<EsppScheduleDto?> GetEsppScheduleDtoAsync(Guid jobGroupId);
|
||||
|
||||
IQueryable<EsppSchTypeConfig> GetWithSchIncludes();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace PARR.DAL.Services.Interfaces.Job
|
||||
{
|
||||
public interface IJobDetailsService : IBaseService<Models.Job.JobUnitFilter>
|
||||
public interface IJobUnitFilterService : IBaseService<Models.Job.JobUnitFilter>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
8
PARR.DAL/Services/Interfaces/Job/IJobGroupService.cs
Normal file
8
PARR.DAL/Services/Interfaces/Job/IJobGroupService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using PARR.DAL.Services.Interfaces.Base;
|
||||
|
||||
namespace PARR.DAL.Services.Interfaces.Job
|
||||
{
|
||||
public interface IJobGroupService : IBaseService<Models.Job.JobGroup>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,6 @@ namespace PARR.DAL.Services.Interfaces.Unit
|
||||
{
|
||||
public interface IUnitService : IBaseService<Models.Unit.Unit>
|
||||
{
|
||||
IQueryable<Models.Unit.Unit> GetWithIncludes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using PARR.DAL.Contracts;
|
||||
using PARR.DAL.DomainModels;
|
||||
using PARR.DAL.Extensions;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
using PARR.DAL.Services.Interfaces.Job;
|
||||
|
||||
namespace PARR.DAL.TransformServices
|
||||
{
|
||||
@@ -15,6 +16,7 @@ namespace PARR.DAL.TransformServices
|
||||
private readonly IApplicationsInWorkService applicationsInWorkService;
|
||||
private readonly IWeekendDayService weekendDayService;
|
||||
private readonly INextRunModifierService nextRunModifierService;
|
||||
private readonly IJobGroupService jobGroupService;
|
||||
private readonly ILogger<EsppScheduleTransformService> logger;
|
||||
|
||||
private readonly Dictionary<string, int> monthDict = new Dictionary<string, int>()
|
||||
@@ -59,13 +61,15 @@ namespace PARR.DAL.TransformServices
|
||||
IEsppSchTypeConfigService esppSchTypeConfigService,
|
||||
IApplicationsInWorkService applicationsInWorkService,
|
||||
IWeekendDayService weekendDayService,
|
||||
INextRunModifierService nextRunModifierService
|
||||
INextRunModifierService nextRunModifierService,
|
||||
IJobGroupService jobGroupService
|
||||
)
|
||||
{
|
||||
this.esppSchTypeConfigService = esppSchTypeConfigService;
|
||||
this.applicationsInWorkService = applicationsInWorkService;
|
||||
this.weekendDayService = weekendDayService;
|
||||
this.nextRunModifierService = nextRunModifierService;
|
||||
this.jobGroupService = jobGroupService;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@@ -157,23 +161,28 @@ namespace PARR.DAL.TransformServices
|
||||
}
|
||||
|
||||
|
||||
public async Task<DateTimeOffset> GetNextDateAsync(Guid applicationInWorkId, DateTimeOffset lastRun)
|
||||
public async Task<DateTimeOffset> GetNextDateAsync(Guid jobGroupId, DateTimeOffset lastRun)
|
||||
{
|
||||
//если больше текущего вернуть lastRun. Это и есть следующая дата
|
||||
if (lastRun > DateTimeOffset.UtcNow)
|
||||
return await nextRunModifierService.GetWorkDayAsync(lastRun);
|
||||
|
||||
var appInWork = await applicationsInWorkService.Get()
|
||||
.Include(aiw => aiw.EsppSchValues)
|
||||
//var appInWork = await applicationsInWorkService.Get()
|
||||
// .Include(aiw => aiw.EsppSchValues)
|
||||
// .ThenInclude(esv => esv.EsppSchTypeValue)
|
||||
// .ThenInclude(etv => etv!.DistributionPeriod)
|
||||
// .FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||
var jobGroup = await jobGroupService.Get()
|
||||
.Include(t=>t.EsppSchValues)
|
||||
.ThenInclude(esv => esv.EsppSchTypeValue)
|
||||
.ThenInclude(etv => etv!.DistributionPeriod)
|
||||
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||
.FirstOrDefaultAsync(t => t.Id == jobGroupId);
|
||||
|
||||
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||
var esppSchedule = await GetEsppScheduleAsync(jobGroupId);
|
||||
|
||||
if (appInWork!.IsAutoDistributionEnabled)
|
||||
if (jobGroup!.IsAutoDistributionEnabled)
|
||||
{
|
||||
var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||
var period = jobGroup.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||
var periodType = ParseDistributionPeriodType(period!.Type);
|
||||
|
||||
return GetNextDateForDistributionRun(lastRun, periodType, period.Duration);
|
||||
@@ -183,24 +192,24 @@ namespace PARR.DAL.TransformServices
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<DateTimeOffset>> GetNextScheduleAsync(Guid applicationInWorkId, DateTimeOffset lastRun)
|
||||
public async Task<List<DateTimeOffset>> GetNextScheduleAsync(Guid jobGroupId, DateTimeOffset lastRun)
|
||||
{
|
||||
//TODO: тут не проверен переход через выходные дни!!! Переход не используется, так как тут не рассчитываем NextRun.
|
||||
//В общем проверить, когда будем тестировать агента, что с датами все ок
|
||||
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||
var esppSchedule = await GetEsppScheduleAsync(jobGroupId);
|
||||
var nextSchedule = GetNextSchedule(esppSchedule, lastRun);
|
||||
|
||||
return nextSchedule;
|
||||
}
|
||||
|
||||
|
||||
private async Task<EsppScheduleDto> GetEsppScheduleAsync(Guid applicationInWorkId)
|
||||
private async Task<EsppScheduleDto> GetEsppScheduleAsync(Guid jobGroupId)
|
||||
{
|
||||
var esppSchedule = await esppSchTypeConfigService.GetEsppScheduleDtoAsync(applicationInWorkId);
|
||||
var esppSchedule = await esppSchTypeConfigService.GetEsppScheduleDtoAsync(jobGroupId);
|
||||
if (esppSchedule == null)
|
||||
{
|
||||
logger.LogError($"Не найдено расписание в БД, applicationInWorkId: {applicationInWorkId}");
|
||||
throw new Exception($"Не найдено расписание в БД, applicationInWorkId: {applicationInWorkId}");
|
||||
logger.LogError($"Не найдено расписание в БД, jobId: {jobGroupId}");
|
||||
throw new Exception($"Не найдено расписание в БД, jobId: {jobGroupId}");
|
||||
}
|
||||
|
||||
return esppSchedule;
|
||||
@@ -427,9 +436,9 @@ namespace PARR.DAL.TransformServices
|
||||
}
|
||||
|
||||
|
||||
public async Task<DateOnly> GetStartPeriodForDateAsync(Guid applicationInWorkId, DateTimeOffset date, DateTimeOffset referenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
||||
public async Task<DateOnly> GetStartPeriodForDateAsync(Guid jobGroupId, DateTimeOffset date, DateTimeOffset referenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod)
|
||||
{
|
||||
var esppSchedule = await GetEsppScheduleAsync(applicationInWorkId);
|
||||
var esppSchedule = await GetEsppScheduleAsync(jobGroupId);
|
||||
|
||||
var currentStartPeriod = referenceDate;
|
||||
var currentEndPeriod = GetNextDateForDistributionRun(currentStartPeriod, periodType, distributionPeriod);
|
||||
|
||||
@@ -25,20 +25,20 @@ namespace PARR.DAL.TransformServices
|
||||
//List<DateTimeOffset> GetNextSchedule(EsppScheduleDto esppSchedule, DateTimeOffset lastRun);
|
||||
|
||||
/// <summary>
|
||||
/// Получить следующую дату по applicationInWorkId
|
||||
/// Получить следующую дату по jobGroupId
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorkId"></param>
|
||||
/// <param name="jobGroupId"></param>
|
||||
/// <param name="lastRun"></param>
|
||||
/// <returns></returns>
|
||||
Task<DateTimeOffset> GetNextDateAsync(Guid applicationInWorkId, DateTimeOffset lastRun);
|
||||
Task<DateTimeOffset> GetNextDateAsync(Guid jobGroupId, DateTimeOffset lastRun);
|
||||
|
||||
/// <summary>
|
||||
/// Получить расписание по applicationInWorkId
|
||||
/// Получить расписание по jobGroupId
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorkId"></param>
|
||||
/// <param name="jobGroupId"></param>
|
||||
/// <param name="lastRun"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<DateTimeOffset>> GetNextScheduleAsync(Guid applicationInWorkId, DateTimeOffset lastRun);
|
||||
Task<List<DateTimeOffset>> GetNextScheduleAsync(Guid jobGroupId, DateTimeOffset lastRun);
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -54,9 +54,9 @@ namespace PARR.DAL.TransformServices
|
||||
/// <summary>
|
||||
/// Получить дату начала периода распределения относительно опорной даты (Reference Date)
|
||||
/// </summary>
|
||||
/// <param name="applicationInWorkId"></param>
|
||||
/// <param name="jobGroupId"></param>
|
||||
/// <param name="date"></param>
|
||||
/// <returns></returns>
|
||||
Task<DateOnly> GetStartPeriodForDateAsync(Guid applicationInWorkId, DateTimeOffset date, DateTimeOffset refrenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod);
|
||||
Task<DateOnly> GetStartPeriodForDateAsync(Guid jobGroupId, DateTimeOffset date, DateTimeOffset refrenceDate, DistributionPeriodTypeEnum periodType, string distributionPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace PARR.EsppOrderLoader.Services
|
||||
}
|
||||
|
||||
var template = await templateService.Get()
|
||||
.Include(t => t.ApplicationsInWork)
|
||||
.Include(t => t.Job)
|
||||
.FirstOrDefaultAsync(t => t.Name.ToLower() == esppOrder.TemplateName.ToLower());
|
||||
|
||||
if (template == null)
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace PARR.EsppOrderManager
|
||||
.Include(t => t.AgentHistories).ThenInclude(t => t.AgentHistoryLevel)
|
||||
.Include(t => t.OrderStatus)
|
||||
.Include(t => t.NextStatus)
|
||||
.Include(t => t.Template).ThenInclude(t => t!.ApplicationsInWork).ThenInclude(t => t!.Work).ThenInclude(t => t!.Tnk)
|
||||
.Include(t => t.Template).ThenInclude(t => t!.Job).ThenInclude(t => t!.Tnk)
|
||||
.FirstOrDefaultAsync(t => t.Id == objFromQuery.OrderId);
|
||||
|
||||
if (!IsValidOrder(ref order, ref objFromQuery))
|
||||
@@ -162,7 +162,7 @@ namespace PARR.EsppOrderManager
|
||||
var template = resultTemplateSettings.Template;
|
||||
|
||||
//Поле решение из ApplicationsInWork
|
||||
var baseMsg = order.Template!.ApplicationsInWork!.Solution;
|
||||
var baseMsg = order.Template!.Job!.Group!.Solution;
|
||||
|
||||
//Формируем сообщения от Агента
|
||||
var msgAgent = agentHistory.Any()
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace PARR.EsppOrderManager.Services
|
||||
// заполняем ТНК
|
||||
var tnk = new AddMtnkQuery
|
||||
{
|
||||
JobOperation = order!.Template!.ApplicationsInWork!.Work!.Name,
|
||||
JobOperation = order!.Template!.Job!.WorkName,
|
||||
RecordId = order.Number,
|
||||
Time = duration.ToString("hh\\:mm")
|
||||
};
|
||||
|
||||
@@ -86,9 +86,9 @@ namespace PARR.EsppScheduleSync
|
||||
Code = template.ScheduleEsppId ?? "",
|
||||
ScheduleName = template.Name,
|
||||
IsActive = template.IsActiveSchedule,
|
||||
ResponseArea = template.Host!.ResponseArea!.Name,
|
||||
//ResponseArea = template.Host!.ResponseArea!.Name,//TODO Migration to job
|
||||
//WorkGroup = template.Host!.WorkGroup!,
|
||||
WorkGroup = template.Host!.WorkGroup!.Name,
|
||||
//WorkGroup = template.Host!.WorkGroup!.Name,//TODO Migration to job
|
||||
//Мы решили, что для всех расписаний "Нет исключений", если что-то поменяется, тут нужно переделать
|
||||
TypeV60calendar = settingsFromDb.ScheduleExclude == "Нет исключений" ? "NONE" : "",
|
||||
//Scheduled = EsppScheduleHelpers.GetNextRun(template.NextRun),
|
||||
@@ -119,7 +119,7 @@ namespace PARR.EsppScheduleSync
|
||||
if (esppSchTypeConfigService == null)
|
||||
throw new Exception($"Не найден сервис: {nameof(IEsppSchTypeConfigService)}");
|
||||
|
||||
var esppSchedule = esppSchTypeConfigService.GetEsppScheduleDto(template.ApplicationInWorkId);
|
||||
var esppSchedule = esppSchTypeConfigService.GetEsppScheduleDto(template.JobId);
|
||||
if (esppSchedule == null)
|
||||
{
|
||||
logger.LogError($"Не смог получить расписание из БД для шаблона templateId: {template.Id}, {template.Name}");
|
||||
@@ -144,16 +144,16 @@ namespace PARR.EsppScheduleSync
|
||||
break;
|
||||
case EsppSchTypeScheduleEnum.Monthly:
|
||||
//если включено автораспределение, подставляем дату месяца из NextRun
|
||||
if (template.ApplicationsInWork?.IsAutoDistributionEnabled == true)
|
||||
{
|
||||
var nextRunByRobotTimeZone = nextRunModifierService.GetNextRunByAccountRobotTimeZone(template.NextRun);
|
||||
esppObject.Dayofmonth = nextRunByRobotTimeZone.Day.ToString();
|
||||
// esppObject.Dayofmonth = template.NextRun.Day.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (template.ApplicationsInWork?.IsAutoDistributionEnabled == true)//TODO Migration to job
|
||||
//{
|
||||
// var nextRunByRobotTimeZone = nextRunModifierService.GetNextRunByAccountRobotTimeZone(template.NextRun);
|
||||
// esppObject.Dayofmonth = nextRunByRobotTimeZone.Day.ToString();
|
||||
// // esppObject.Dayofmonth = template.NextRun.Day.ToString();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
esppObject.Dayofmonth = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
|
||||
}
|
||||
//}
|
||||
break;
|
||||
case EsppSchTypeScheduleEnum.Monthly2:
|
||||
esppObject.Md1 = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
|
||||
|
||||
@@ -74,19 +74,19 @@ namespace PARR.EsppTemplateSync
|
||||
TemplateName = template.Name,
|
||||
IsActive = template.IsActiveTemplate,
|
||||
//WorkGroup = template.Host!.WorkGroup!,
|
||||
WorkGroup = template.Host!.WorkGroup!.Name,
|
||||
ShortDescription = Normalize(template.ApplicationsInWork!.ShortDescription.ApplyShortcode(Constants.Shortcodes.ShortcodeEnum.EK,template.Host.Ek)),
|
||||
WorkGroup = template.Unit!.BaseFields!.WorkGroup!,
|
||||
ShortDescription = Normalize(template.Job.Group.ShortDescription.ApplyShortcode(Constants.Shortcodes.ShortcodeEnum.EK,template.Unit.Name)),
|
||||
//ResponseArea = template.Host!.ResponseArea!.Name,
|
||||
//ЗО берем РГ а не хоста
|
||||
ResponseArea = template.Host!.WorkGroup!.ResponseArea!.Name,
|
||||
Duration = template.ApplicationsInWork.TemplateDuration,
|
||||
EK = template.Host.Ek,
|
||||
FullDescription = Normalize(template.ApplicationsInWork.FullDescription),
|
||||
Solution = Normalize(template.ApplicationsInWork.Solution),
|
||||
Process = template.ApplicationsInWork.Work!.Tnk!.Subprocess!.Process!.Name,
|
||||
SubProcess = template.ApplicationsInWork.Work.Tnk.Subprocess.Name,
|
||||
TNK = template.ApplicationsInWork.Work.Tnk.Name.ApplyShortcode(Constants.Shortcodes.ShortcodeEnum.EK, template.Host.Ek),
|
||||
Work = template.ApplicationsInWork.Work.Name.ApplyShortcode(Constants.Shortcodes.ShortcodeEnum.EK, template.Host.Ek),
|
||||
ResponseArea = template.Unit.BaseFields.ResponseArea,
|
||||
Duration = template.Job.Group.TemplateDuration,
|
||||
EK = template.Unit.Name,
|
||||
FullDescription = Normalize(template.Job.Group.FullDescription),
|
||||
Solution = Normalize(template.Job.Group.Solution),
|
||||
Process = template.Job.Tnk!.Subprocess!.Process!.Name,
|
||||
SubProcess = template.Job.Tnk.Subprocess.Name,
|
||||
TNK = template.Job.Tnk.Name.ApplyShortcode(Constants.Shortcodes.ShortcodeEnum.EK, template.Unit.Name),
|
||||
Work = template.Job.WorkName.ApplyShortcode(Constants.Shortcodes.ShortcodeEnum.EK, template.Unit.Name),
|
||||
Initiator = settingsFromDb.Initiator
|
||||
};
|
||||
|
||||
|
||||
@@ -43,93 +43,94 @@ namespace PARR.GeneratorTemplates.Services
|
||||
|
||||
public async Task CreateTemplates(GeneratorTemplateMq query)
|
||||
{
|
||||
//В таблице AppInWork находим РР, и смотрим ее рабочие группы. Затем по ним будем фильтровать хосты
|
||||
var appInWorkWg = await applicationsInWorkService.Get()
|
||||
.Include(t => t.WorkGroups)
|
||||
.FirstAsync(t => t.ApplicationId == query.ApplicationId && t.WorkId == query.WorkId);
|
||||
//TODO Migratin to Job
|
||||
////В таблице AppInWork находим РР, и смотрим ее рабочие группы. Затем по ним будем фильтровать хосты
|
||||
//var appInWorkWg = await applicationsInWorkService.Get()
|
||||
// .Include(t => t.WorkGroups)
|
||||
// .FirstAsync(t => t.ApplicationId == query.ApplicationId && t.WorkId == query.WorkId);
|
||||
|
||||
if (!appInWorkWg.WorkGroups.Any())
|
||||
{
|
||||
logger.LogWarning($"Не генерирую шаблоны. Нет рабочих групп у ApplicationInWork с id: {appInWorkWg.Id}");
|
||||
return;
|
||||
}
|
||||
//if (!appInWorkWg.WorkGroups.Any())
|
||||
//{
|
||||
// logger.LogWarning($"Не генерирую шаблоны. Нет рабочих групп у ApplicationInWork с id: {appInWorkWg.Id}");
|
||||
// return;
|
||||
//}
|
||||
|
||||
var workGroups = appInWorkWg.WorkGroups.ToList();
|
||||
//var workGroups = appInWorkWg.WorkGroups.ToList();
|
||||
|
||||
//Согласно параметрам, находит все ЭК в таблице Hosts.
|
||||
//Далее проверяет есть ли такие шаблоны в таблице Templates, если нет, то создает, активирует и ставит статус Creating.
|
||||
//Если такие шаблоны уже есть, ничего с ними не делает.
|
||||
////Согласно параметрам, находит все ЭК в таблице Hosts.
|
||||
////Далее проверяет есть ли такие шаблоны в таблице Templates, если нет, то создает, активирует и ставит статус Creating.
|
||||
////Если такие шаблоны уже есть, ничего с ними не делает.
|
||||
|
||||
string ekPattern = SqlHelpers.RegexToLike(query.Ek);
|
||||
//string ekPattern = SqlHelpers.RegexToLike(query.Ek);
|
||||
|
||||
// список хостов для создания шаблонов
|
||||
var queryHosts = hostService.Get()
|
||||
//.Include(t => t.WorkGroupItem)
|
||||
.Include(t => t.ApplicationsInHosts)
|
||||
.ThenInclude(t => t.Application).ThenInclude(t => t!.ApplicationsInWorks).ThenInclude(w => w.Work)
|
||||
.Include(t => t.Templates)
|
||||
.ThenInclude(w => w.ApplicationsInWork)
|
||||
.Include(t => t.ResponseArea)
|
||||
.Where(t =>
|
||||
t.ApplicationsInHosts.Any(h =>
|
||||
h.ApplicationId == query.ApplicationId
|
||||
&& h.Application!.ApplicationsInWorks.Any(w => w.WorkId == query.WorkId)
|
||||
)
|
||||
&& EF.Functions.Like(t.Ek.ToLower(), ekPattern)
|
||||
// смотрим что нет такого шаблона
|
||||
&& t.Templates.Any(templ => templ.ApplicationsInWork!.WorkId == query.WorkId && templ.ApplicationsInWork.ApplicationId == query.ApplicationId) == false
|
||||
// смотрим что у этих хостов есть нужные группы
|
||||
//&& workGroups.Any(x => x.WorkGroupId == t.WorkGroupId)
|
||||
);
|
||||
//// список хостов для создания шаблонов
|
||||
//var queryHosts = hostService.Get()
|
||||
// //.Include(t => t.WorkGroupItem)
|
||||
// .Include(t => t.ApplicationsInHosts)
|
||||
// .ThenInclude(t => t.Application).ThenInclude(t => t!.ApplicationsInWorks).ThenInclude(w => w.Work)
|
||||
// .Include(t => t.Templates)
|
||||
// .ThenInclude(w => w.ApplicationsInWork)
|
||||
// .Include(t => t.ResponseArea)
|
||||
// .Where(t =>
|
||||
// t.ApplicationsInHosts.Any(h =>
|
||||
// h.ApplicationId == query.ApplicationId
|
||||
// && h.Application!.ApplicationsInWorks.Any(w => w.WorkId == query.WorkId)
|
||||
// )
|
||||
// && EF.Functions.Like(t.Ek.ToLower(), ekPattern)
|
||||
// // смотрим что нет такого шаблона
|
||||
// && t.Templates.Any(templ => templ.ApplicationsInWork!.WorkId == query.WorkId && templ.ApplicationsInWork.ApplicationId == query.ApplicationId) == false
|
||||
// // смотрим что у этих хостов есть нужные группы
|
||||
// //&& workGroups.Any(x => x.WorkGroupId == t.WorkGroupId)
|
||||
// );
|
||||
|
||||
// статус ЭК
|
||||
if (query.StatusEk > 0)
|
||||
queryHosts = queryHosts.Where(t => t.EkStatusCode == query.StatusEk);
|
||||
//// статус ЭК
|
||||
//if (query.StatusEk > 0)
|
||||
// queryHosts = queryHosts.Where(t => t.EkStatusCode == query.StatusEk);
|
||||
|
||||
var hosts = await queryHosts
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
//var hosts = await queryHosts
|
||||
// .AsSplitQuery()
|
||||
// .ToListAsync();
|
||||
|
||||
// Исключаем хосты у которых нет нужных групп
|
||||
hosts = hosts.Where(t => workGroups.Any(x => x.WorkGroupId == t.WorkGroupId)).ToList();
|
||||
if (!hosts.Any())
|
||||
{
|
||||
logger.LogInformation($"Не найдено ЭК попадающих под условие: ${JsonSerializer.Serialize(query)}");
|
||||
return;
|
||||
}
|
||||
//// Исключаем хосты у которых нет нужных групп
|
||||
//hosts = hosts.Where(t => workGroups.Any(x => x.WorkGroupId == t.WorkGroupId)).ToList();
|
||||
//if (!hosts.Any())
|
||||
//{
|
||||
// logger.LogInformation($"Не найдено ЭК попадающих под условие: ${JsonSerializer.Serialize(query)}");
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
// хосты группируем по РГ, чтоб потом распределить/рассчитать NextRun
|
||||
var groupingHostByWg = hosts.GroupBy(t => t.WorkGroupId);
|
||||
//// хосты группируем по РГ, чтоб потом распределить/рассчитать NextRun
|
||||
//var groupingHostByWg = hosts.GroupBy(t => t.WorkGroupId);
|
||||
|
||||
foreach (var group in groupingHostByWg)
|
||||
{
|
||||
var groupingHosts = group.ToList();
|
||||
//foreach (var group in groupingHostByWg)
|
||||
//{
|
||||
// var groupingHosts = group.ToList();
|
||||
|
||||
var templates = CreateQueryTemplates(groupingHosts, query);
|
||||
// var templates = CreateQueryTemplates(groupingHosts, query);
|
||||
|
||||
//проверяем, что нет шаблонов с такими именами, исключаем их
|
||||
templates = await ExcludeExistTemplatesAsync(templates);
|
||||
if (!templates.Any())
|
||||
continue;
|
||||
// //проверяем, что нет шаблонов с такими именами, исключаем их
|
||||
// templates = await ExcludeExistTemplatesAsync(templates);
|
||||
// if (!templates.Any())
|
||||
// continue;
|
||||
|
||||
//заполняем NextRun
|
||||
templates = await templateDistributor.DistributeTemplateAsync(templates, appInWorkWg.Id, (Guid)group.Key!);
|
||||
// //заполняем NextRun
|
||||
// templates = await templateDistributor.DistributeTemplateAsync(templates, appInWorkWg.Id, (Guid)group.Key!);
|
||||
|
||||
// сохраняем
|
||||
foreach (var template in templates)
|
||||
{
|
||||
if (!await templateService.CreateAsync(template) || !await templateService.CommitAsync(query.HistoryInitiator))
|
||||
{
|
||||
logger.LogError($"Ошибка при создании шаблона: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, HostId: {template.HostId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation($"Создан шаблон: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, " +
|
||||
$"HostId: {template.HostId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
// // сохраняем
|
||||
// foreach (var template in templates)
|
||||
// {
|
||||
// if (!await templateService.CreateAsync(template) || !await templateService.CommitAsync(query.HistoryInitiator))
|
||||
// {
|
||||
// logger.LogError($"Ошибка при создании шаблона: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, HostId: {template.HostId}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// logger.LogInformation($"Создан шаблон: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, " +
|
||||
// $"HostId: {template.HostId}");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#region создавали шаблоны до того, как стали группировать по РГ
|
||||
////Создаем шаблоны
|
||||
@@ -231,8 +232,8 @@ namespace PARR.GeneratorTemplates.Services
|
||||
),
|
||||
IsActiveTemplate = query.IsActiveTemplate ?? false,
|
||||
IsActiveSchedule = query.IsActiveSchedule ?? false,
|
||||
ApplicationInWorkId = appInWork.Id,
|
||||
HostId = host.Id,
|
||||
JobId = appInWork.Id,//TODO Migratin to Job
|
||||
UnitId = host.Id,//TODO Migratin to Job
|
||||
// NextRun не задаем значение, его рассчитаем позже
|
||||
//NextRun = ???,
|
||||
LastRun = null
|
||||
@@ -270,26 +271,26 @@ namespace PARR.GeneratorTemplates.Services
|
||||
string ekPattern = SqlHelpers.RegexToLike(query.Ek);
|
||||
|
||||
var queryTemplates = templateService.Get()
|
||||
.Include(t => t.Host)
|
||||
.Include(t => t.ApplicationsInWork)
|
||||
.Include(t => t.Unit)//TODO Migratin to Job
|
||||
.Include(t => t.Job)//TODO Migratin to Job
|
||||
.Include(t => t.RobotConfigurations)
|
||||
.Where(t =>
|
||||
(t.IsActiveTemplate == true || t.IsActiveSchedule == true)
|
||||
&& t.ApplicationsInWork!.ApplicationId == query.ApplicationId
|
||||
&& t.ApplicationsInWork!.WorkId == query.WorkId
|
||||
&& EF.Functions.Like(t.Host!.Ek.ToLower(), ekPattern)
|
||||
//&& t.ApplicationsInWork!.ApplicationId == query.ApplicationId//TODO Migratin to Job
|
||||
//&& t.ApplicationsInWork!.WorkId == query.WorkId//TODO Migratin to Job
|
||||
&& EF.Functions.Like(t.Unit!.Name.ToLower(), ekPattern)
|
||||
);
|
||||
|
||||
// статус ЭК
|
||||
if (query.StatusEk > 0)
|
||||
queryTemplates = queryTemplates.Where(t => t.Host!.EkStatusCode == query.StatusEk);
|
||||
queryTemplates = queryTemplates;//.Where(t => t.Unit!.BaseFields.Status == query.StatusEk);//TODO Migratin to Job
|
||||
|
||||
var existTemplates = await queryTemplates
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
|
||||
// Исключаем хосты у которых нет нужных групп
|
||||
existTemplates = existTemplates.Where(t => workGroups.Any(x => x.WorkGroupId == t.Host.WorkGroupId)).ToList();
|
||||
existTemplates = existTemplates.Where(t => workGroups.Any(x => x.WorkGroup.Name == t.Unit.BaseFields.WorkGroup)).ToList();
|
||||
|
||||
if (!existTemplates.Any())
|
||||
{
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace PARR.Master.Services
|
||||
if (isAgentStarted == true && isAgentEnded == false)
|
||||
{
|
||||
var lastStrartDate = allHistory.Last(t => t.HistoryLevelId == (int)AgentHistoryLevelEnum.Start).DateCreated;
|
||||
var timeout = (double)order.Template!.ApplicationsInWork!.AgentTimeOutSec!;
|
||||
var timeout = (double)order.Template!.Job!.Group!.AgentTimeOutSec!;
|
||||
|
||||
if (lastStrartDate.AddSeconds(timeout) <= DateTimeOffset.UtcNow)
|
||||
{
|
||||
@@ -182,7 +182,7 @@ namespace PARR.Master.Services
|
||||
t.TemplateId == order.TemplateId
|
||||
&& t.DateCreated > order.GenerateDate!.Value.Add(-orderManageSettings.FindAgentHistoryStartOffset)
|
||||
//&& t.DateCreated <= order.GenerateDate!.Value.AddSeconds(order.Template!.ApplicationsInWork!.AgentTimeOutSec!.Value)
|
||||
&& t.DateCreated <= order.GenerateDate!.Value.Add(order.Template!.ApplicationsInWork!.TemplateDurationTimeSpan!.Value)
|
||||
&& t.DateCreated <= order.GenerateDate!.Value.Add(order.Template!.Job!.Group!.TemplateDurationTimeSpan!.Value)
|
||||
&& t.OrderId == null
|
||||
)
|
||||
.OrderBy(t => t.DateCreated)
|
||||
@@ -244,14 +244,14 @@ namespace PARR.Master.Services
|
||||
private IQueryable<Order> GetOrdres()
|
||||
{
|
||||
return orderService.Get()
|
||||
.Include(t => t.Template).ThenInclude(t => t!.ApplicationsInWork)
|
||||
.Include(t => t.Template).ThenInclude(t => t!.Job)
|
||||
.Include(t => t.AgentHistories)
|
||||
.Where(t =>
|
||||
t.TemplateId.HasValue
|
||||
&& t.Template!.ApplicationsInWork!.IsAgent == true
|
||||
&& t.Template!.Job!.Group!.IsAgent == true
|
||||
&& t.GenerateDate.HasValue
|
||||
&& t.Template!.ApplicationsInWork!.AgentTimeOutSec.HasValue
|
||||
&& string.IsNullOrEmpty(t.Template!.ApplicationsInWork!.TemplateDuration) == false
|
||||
&& t.Template!.Job!.Group!.AgentTimeOutSec.HasValue
|
||||
&& string.IsNullOrEmpty(t.Template!.Job!.Group!.TemplateDuration) == false
|
||||
&& t.ExpirationDate > DateTimeOffset.UtcNow
|
||||
).OrderBy(t => t.DateCreated);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace PARR.NextRun
|
||||
|
||||
foreach (var template in templates)
|
||||
{
|
||||
var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.ApplicationInWorkId, template.NextRun);
|
||||
var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.JobId, template.NextRun);
|
||||
template.LastRun = template.NextRun;
|
||||
template.NextRun = nextRun;
|
||||
|
||||
|
||||
@@ -35,11 +35,11 @@ internal class TemplateActivator : ITemplateActivator
|
||||
}
|
||||
|
||||
|
||||
public async Task ChangeStateAsync(Guid applicationInWorkId, TemplateActivatorActionsEnum action, IHistoryInitiator? historyInitiator)
|
||||
public async Task ChangeStateAsync(Guid applicationInWorkId, TemplateActivatorActionsEnum action, IHistoryInitiator? historyInitiator)//TODO Migratin to Job
|
||||
{
|
||||
var query = templateService.Get()
|
||||
.Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot)
|
||||
.Where(t => t.ApplicationInWorkId == applicationInWorkId);
|
||||
.Where(t => t.JobId == applicationInWorkId);//TODO Migratin to Job
|
||||
var changes = 0;
|
||||
switch (action)
|
||||
{
|
||||
@@ -121,7 +121,7 @@ internal class TemplateActivator : ITemplateActivator
|
||||
var changes = 0;
|
||||
|
||||
//Добавляем информацию о рабочих группах для возможности их фильтрации
|
||||
query = query.Include(t => t.Host).ThenInclude(h => h!.WorkGroup);
|
||||
query = query.Include(t => t.Unit);//TODO Migratin to Job
|
||||
|
||||
//Получаем настройки авто-контроля
|
||||
var jobAutoControlSettings = await GetJobAutoControlSettingsAsync(applicationInWorkId);
|
||||
@@ -149,7 +149,7 @@ internal class TemplateActivator : ITemplateActivator
|
||||
//Фильтруем по рабочим группам
|
||||
var appInWorkWorkGroups = GetApplicationInWorkWorkGroups(applicationInWorkId);
|
||||
if (appInWorkWorkGroups.Any())
|
||||
templates = templates.Where(t => appInWorkWorkGroups.Any(awg => t.Host!.WorkGroupId == awg.WorkGroupId)).ToList();
|
||||
templates = templates.Where(t => appInWorkWorkGroups.Any(awg => t.Unit!.BaseFields!.WorkGroup == awg.WorkGroup!.Name)).ToList();//TODO Migratin to Job
|
||||
|
||||
//Фильтруем соответствие статусов ЭК условиям автоконтроля
|
||||
var checkEkStatus = FilterTemplatesByWrongEkStatus(templates, trueEkStatuses, isActivate);
|
||||
@@ -177,9 +177,9 @@ internal class TemplateActivator : ITemplateActivator
|
||||
private List<Template> FilterTemplatesByWrongEkStatus(List<Template> templates, ICollection<JobAutoControlInEkStatus> trueEkStatuses, bool isActivate)
|
||||
{
|
||||
if (isActivate)
|
||||
return templates.Where(t => trueEkStatuses.Any(tes => tes.EkStatusCode == t.Host!.EkStatusCode)).ToList();
|
||||
return templates.Where(t => trueEkStatuses.Any(tes => tes.EkStatus!.Name == t.Unit!.BaseFields!.Status)).ToList();//TODO Migratin to Job
|
||||
|
||||
return templates.Where(t => !trueEkStatuses.Any(tes => tes.EkStatusCode == t.Host!.EkStatusCode)).ToList();
|
||||
return templates.Where(t => !trueEkStatuses.Any(tes => tes.EkStatus!.Name == t.Unit!.BaseFields!.Status)).ToList();//TODO Migratin to Job
|
||||
}
|
||||
|
||||
private List<Template> FilterTemplatesByNameNotMatchToMasks(IQueryable<Template> query, ICollection<JobEkMask> trueMasks)
|
||||
@@ -187,7 +187,7 @@ internal class TemplateActivator : ITemplateActivator
|
||||
var result = new List<Template>();
|
||||
foreach (var mask in trueMasks)
|
||||
{
|
||||
var templates = query.Where(t => EF.Functions.Like(t.Host!.Ek.ToLower(), SqlHelpers.RegexToLike(mask.Name))).ToList();
|
||||
var templates = query.Where(t => EF.Functions.Like(t.Unit!.Name.ToLower(), SqlHelpers.RegexToLike(mask.Name))).ToList();
|
||||
result.AddRange(templates);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,27 +21,28 @@ namespace PARR.TemplateDistributor.Services
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var service = scope.ServiceProvider.GetService<IApplicationsInWorkService>();
|
||||
//TODO Migratin to Job
|
||||
//var service = scope.ServiceProvider.GetService<IApplicationsInWorkService>();
|
||||
|
||||
if (service == null)
|
||||
throw new Exception($"Не найден сервис: {nameof(IApplicationsInWorkService)}");
|
||||
//if (service == null)
|
||||
// throw new Exception($"Не найден сервис: {nameof(IApplicationsInWorkService)}");
|
||||
|
||||
var appInWork = await service.Get()
|
||||
.Include(aiw => aiw.EsppSchValues)
|
||||
.FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||
//var appInWork = await service.Get()//TODO Migratin to Job
|
||||
// //.Include(aiw => aiw.EsppSchValues)
|
||||
// .FirstOrDefaultAsync(t => t.Id == applicationInWorkId);
|
||||
|
||||
if (appInWork == null)
|
||||
{
|
||||
logger.LogError($"Не найдена регалментная работа {nameof(applicationInWorkId)}: {applicationInWorkId}");
|
||||
return false;
|
||||
}
|
||||
//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;
|
||||
}
|
||||
//if (appInWork.IsAutoDistributionEnabled && appInWork.EsppSchValues.Count !=1)
|
||||
//{
|
||||
// logger.LogError($"Регалментная работа {nameof(applicationInWorkId)}: {applicationInWorkId} должна иметь только одно значение EsppSchTypeValue" +
|
||||
// $", соответствующее режиму равномерного распределения по периоду");
|
||||
// return false;
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using PARR.Constants;
|
||||
using PARR.DAL.Models;
|
||||
using PARR.DAL.Services.Interfaces;
|
||||
using PARR.DAL.TransformServices;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace PARR.TemplateDistributor
|
||||
{
|
||||
@@ -38,20 +39,20 @@ namespace PARR.TemplateDistributor
|
||||
}
|
||||
|
||||
|
||||
public async Task UpdateScheduleAsync(Guid applicationInWorkId)
|
||||
public async Task UpdateScheduleAsync(Guid applicationInWorkId)//TODO Migratin to Job
|
||||
{
|
||||
var appInWork = await applicationsInWorkService.GetAsync(applicationInWorkId);
|
||||
|
||||
var templates = await templateService.Get()
|
||||
.Include(t => t.Host)
|
||||
.ThenInclude(h => h!.WorkGroup)
|
||||
.Where(t => t.ApplicationInWorkId == applicationInWorkId && t.Host!.WorkGroupId != null)
|
||||
.Include(t => t.Unit)//TODO Migratin to Job
|
||||
//.ThenInclude(h => h!.WorkGroup)
|
||||
.Where(t => t.JobId == applicationInWorkId && t.Unit!.BaseFields!.WorkGroup != null)//TODO Migratin to Job
|
||||
.ToListAsync();
|
||||
|
||||
//Группируем шаблоны по рабочим группам
|
||||
var workGroupsWithTemplates = templates.GroupBy(t => t.Host!.WorkGroupId);
|
||||
var workGroupsWithTemplates = templates.GroupBy(t => t.Unit!.BaseFields!.WorkGroup);
|
||||
|
||||
foreach (var workGroupWithTemplates in workGroupsWithTemplates)
|
||||
/*foreach (var workGroupWithTemplates in workGroupsWithTemplates)
|
||||
{
|
||||
var wgId = (Guid)workGroupWithTemplates.Key!;
|
||||
var values = workGroupWithTemplates.ToList();
|
||||
@@ -79,163 +80,167 @@ namespace PARR.TemplateDistributor
|
||||
if (distrTemplates.Any())
|
||||
if (!await templateService.CommitAsync())
|
||||
logger.LogError($"Ошибка записи изменений в БД при перераспределении NextRun шаблонов РР({applicationInWorkId})");
|
||||
}
|
||||
}*/
|
||||
// TODO Migratin to Job
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<Template>> DistributeTemplateAsync(List<Template> templates, Guid applicationInWorkId, Guid workGroupId)
|
||||
{
|
||||
var appInWork = await applicationsInWorkService.Get()
|
||||
.Include(aiw => aiw.EsppSchValues)
|
||||
.ThenInclude(esv => esv.EsppSchTypeValue)
|
||||
.ThenInclude(etv => etv!.DistributionPeriod)
|
||||
.FirstAsync(t => t.Id == applicationInWorkId);
|
||||
// var appInWork = await applicationsInWorkService.Get()
|
||||
// .Include(aiw => aiw.EsppSchValues)
|
||||
// .ThenInclude(esv => esv.EsppSchTypeValue)
|
||||
// .ThenInclude(etv => etv!.DistributionPeriod)
|
||||
// .FirstAsync(t => t.Id == applicationInWorkId);
|
||||
|
||||
var refDate = appInWork.ReferenceDate;
|
||||
// var refDate = appInWork.ReferenceDate;
|
||||
|
||||
//Проверяем наличие распределения РР на период
|
||||
if (appInWork.IsAutoDistributionEnabled)
|
||||
{
|
||||
var existingTemplates = await templateService.Get()
|
||||
.Include(t => t.Host)
|
||||
.Where(t => t.ApplicationInWorkId == applicationInWorkId && t.Host!.WorkGroupId == workGroupId)
|
||||
.ToListAsync();
|
||||
|
||||
//Удалим из входных шаблонов уже существующие в БД (по идее, такого никогда не должно случиться)
|
||||
var duplicates = templates.Select(t => t.Id).Where(t => existingTemplates.Any(et => et.Id == t)).ToList();
|
||||
if (duplicates.Count > 0)
|
||||
{
|
||||
duplicates.ForEach(t =>
|
||||
{
|
||||
logger.LogWarning($"Для распределения AiW({applicationInWorkId}),workGroupId({workGroupId}) передан существующий в базе данных шаблон {t}");
|
||||
});
|
||||
templates.RemoveAll(t => duplicates.Any(dt => dt == t.Id));
|
||||
}
|
||||
|
||||
|
||||
existingTemplates.AddRange(templates);
|
||||
|
||||
//Если распределенная РР получаем начало
|
||||
var period = appInWork.EsppSchValues.First()!.EsppSchTypeValue!.DistributionPeriod;
|
||||
var periodType = ParseDistributionPeriodType(period!.Type);
|
||||
|
||||
var workDays = await GetWorkDaysAsync(appInWork);
|
||||
|
||||
var result = new List<Template>();
|
||||
|
||||
//распределяем РР отдельно активированные
|
||||
var activatedTemplates = existingTemplates.Where(t => t.IsActiveTemplate && t.IsActiveSchedule).ToList();
|
||||
if (activatedTemplates.Count > 0)
|
||||
{
|
||||
Distribute(ref activatedTemplates, refDate, period, periodType, workDays);
|
||||
// result.AddRange(activatedTemplates);
|
||||
}
|
||||
|
||||
//распределяем РР отдельно деактивированные
|
||||
var deactivatedTemplates = existingTemplates.Where(t =>
|
||||
!t.IsActiveTemplate || !t.IsActiveSchedule || (
|
||||
!t.IsActiveTemplate && !t.IsActiveSchedule
|
||||
)).ToList();
|
||||
if (deactivatedTemplates.Count > 0)
|
||||
{
|
||||
Distribute(ref deactivatedTemplates, refDate, period, periodType, workDays);
|
||||
// result.AddRange(deactivatedTemplates);
|
||||
}
|
||||
|
||||
|
||||
if (templates.Any())
|
||||
{
|
||||
// это была генерация шаблонов, не нужны все шаблоны, нужны только те которые передал для получения NextRun
|
||||
result.AddRange(templates);
|
||||
}
|
||||
else
|
||||
{
|
||||
// это было распределение шаблонов, добавляем активированные и деактивированные
|
||||
result.AddRange(activatedTemplates);
|
||||
result.AddRange(deactivatedTemplates);
|
||||
}
|
||||
|
||||
return result;
|
||||
#region comments
|
||||
|
||||
//var d = new Dictionary<DateOnly, List<Template>>();
|
||||
//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));
|
||||
// if (wrokDateTimeOffset < DateTimeOffset.UtcNow)
|
||||
// wrokDateTimeOffset = esppScheduleTransformService.GetNextDateForDistributionRun(wrokDateTimeOffset, periodType, period.Duration);
|
||||
|
||||
// var assignedTemplates = existingTemplates.Where(t => t.NextRun == wrokDateTimeOffset).ToList();
|
||||
// d.Add(wd, assignedTemplates);
|
||||
//}
|
||||
|
||||
//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())
|
||||
// //Проверяем наличие распределения РР на период
|
||||
// if (appInWork.IsAutoDistributionEnabled)
|
||||
// {
|
||||
// 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));
|
||||
// var existingTemplates = await templateService.Get()
|
||||
// .Include(t => t.Unit)
|
||||
// .Where(t => t.JobId == applicationInWorkId
|
||||
// //&& t.Host!.WorkGroupId == workGroupId//TODO Migratin to Job
|
||||
// )
|
||||
// .ToListAsync();
|
||||
|
||||
// templates.Skip(templateDistributed).Take(addingTemplatesCount).ToList().ForEach(t =>
|
||||
// //Удалим из входных шаблонов уже существующие в БД (по идее, такого никогда не должно случиться)
|
||||
// var duplicates = templates.Select(t => t.Id).Where(t => existingTemplates.Any(et => et.Id == t)).ToList();
|
||||
// if (duplicates.Count > 0)
|
||||
// {
|
||||
// t.NextRun = currentDay;
|
||||
// d[wd.Key].Add(t);
|
||||
// duplicates.ForEach(t =>
|
||||
// {
|
||||
// logger.LogWarning($"Для распределения AiW({applicationInWorkId}),workGroupId({workGroupId}) передан существующий в базе данных шаблон {t}");
|
||||
// });
|
||||
// templateDistributed += addingTemplatesCount;
|
||||
|
||||
// templates.RemoveAll(t => duplicates.Any(dt => dt == t.Id));
|
||||
// }
|
||||
|
||||
|
||||
// existingTemplates.AddRange(templates);
|
||||
|
||||
// //Если распределенная РР получаем начало
|
||||
// var period = appInWork.EsppSchValues.First()!.EsppSchTypeValue!.DistributionPeriod;
|
||||
// var periodType = ParseDistributionPeriodType(period!.Type);
|
||||
|
||||
// var workDays = await GetWorkDaysAsync(appInWork);
|
||||
|
||||
// var result = new List<Template>();
|
||||
|
||||
// //распределяем РР отдельно активированные
|
||||
// var activatedTemplates = existingTemplates.Where(t => t.IsActiveTemplate && t.IsActiveSchedule).ToList();
|
||||
// if (activatedTemplates.Count > 0)
|
||||
// {
|
||||
// Distribute(ref activatedTemplates, refDate, period, periodType, workDays);
|
||||
// // result.AddRange(activatedTemplates);
|
||||
// }
|
||||
|
||||
// //распределяем РР отдельно деактивированные
|
||||
// var deactivatedTemplates = existingTemplates.Where(t =>
|
||||
// !t.IsActiveTemplate || !t.IsActiveSchedule || (
|
||||
// !t.IsActiveTemplate && !t.IsActiveSchedule
|
||||
// )).ToList();
|
||||
// if (deactivatedTemplates.Count > 0)
|
||||
// {
|
||||
// Distribute(ref deactivatedTemplates, refDate, period, periodType, workDays);
|
||||
// // result.AddRange(deactivatedTemplates);
|
||||
// }
|
||||
|
||||
|
||||
// if (templates.Any())
|
||||
// {
|
||||
// // это была генерация шаблонов, не нужны все шаблоны, нужны только те которые передал для получения NextRun
|
||||
// result.AddRange(templates);
|
||||
// }
|
||||
// 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;
|
||||
// // это было распределение шаблонов, добавляем активированные и деактивированные
|
||||
// result.AddRange(activatedTemplates);
|
||||
// result.AddRange(deactivatedTemplates);
|
||||
// }
|
||||
|
||||
// return result;
|
||||
// #region comments
|
||||
|
||||
// //var d = new Dictionary<DateOnly, List<Template>>();
|
||||
// //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));
|
||||
// // if (wrokDateTimeOffset < DateTimeOffset.UtcNow)
|
||||
// // wrokDateTimeOffset = esppScheduleTransformService.GetNextDateForDistributionRun(wrokDateTimeOffset, periodType, period.Duration);
|
||||
|
||||
// // var assignedTemplates = existingTemplates.Where(t => t.NextRun == wrokDateTimeOffset).ToList();
|
||||
// // d.Add(wd, assignedTemplates);
|
||||
// //}
|
||||
|
||||
// //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;
|
||||
// // }
|
||||
// // }
|
||||
// //}
|
||||
|
||||
// #endregion
|
||||
// }
|
||||
//}
|
||||
// else
|
||||
// // templates.ForEach(t => t.NextRun = appInWork!.ReferenceDate);
|
||||
// // это не автораспределение, по ReferenceDate получаем ближайший рабочий день
|
||||
// templates.ForEach(async t => t.NextRun = await nextRunModifierService.GetWorkDayAsync(appInWork!.ReferenceDate));
|
||||
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
// templates.ForEach(t => t.NextRun = appInWork!.ReferenceDate);
|
||||
// это не автораспределение, по ReferenceDate получаем ближайший рабочий день
|
||||
templates.ForEach(async t => t.NextRun = await nextRunModifierService.GetWorkDayAsync(appInWork!.ReferenceDate));
|
||||
|
||||
return templates;
|
||||
// return templates;
|
||||
return new List<Template>();
|
||||
}
|
||||
|
||||
private void Distribute(ref List<Template> templates, DateTimeOffset refDate, DistributionPeriod period, DistributionPeriodTypeEnum periodType, List<DateOnly> workDays)
|
||||
@@ -246,9 +251,9 @@ namespace PARR.TemplateDistributor
|
||||
//Проверяем шаблоны уже распределённые, чтобы не перемещать лишний раз
|
||||
var templateToDistrib = GetTemplatesToDistribute(ref distrPlan, templates);
|
||||
|
||||
//logger.LogInformation($"{GetType().Name}(AppInWId:{templates.Select(t => t.ApplicationInWorkId).First()}, WorkGroup:{templates.Select(t => t.Host!.WorkGroup!.Name).First()}) запланировал изменение даты следующего срабатывания у {templateToDistrib.Count()} существующих шаблона(ов), {templates.Count() - templateToDistrib.Count()} остались без изменений");
|
||||
string? loggerWorkGroup = templates.FirstOrDefault()?.Host?.WorkGroup != null ? templates.FirstOrDefault()?.Host?.WorkGroup?.Name : templates.FirstOrDefault()?.Host?.WorkGroupId?.ToString();
|
||||
logger.LogInformation($"{GetType().Name}(AppInWId:{templates.Select(t => t.ApplicationInWorkId).First()}, " +
|
||||
|
||||
string? loggerWorkGroup = templates.FirstOrDefault()?.Unit?.BaseFields?.WorkGroup != null ? templates.FirstOrDefault()?.Unit.BaseFields.WorkGroup : templates.FirstOrDefault()?.Unit?.BaseFields?.WorkGroup?.ToString();
|
||||
logger.LogInformation($"{GetType().Name}(AppInWId:{templates.Select(t => t.JobId).First()}, " +
|
||||
$"WorkGroup:{loggerWorkGroup}) " +
|
||||
$"запланировал изменение даты следующего срабатывания у {templateToDistrib.Count()} существующих шаблона(ов), {templates.Count() - templateToDistrib.Count()} остались без изменений");
|
||||
|
||||
@@ -288,47 +293,49 @@ namespace PARR.TemplateDistributor
|
||||
/// <returns></returns>
|
||||
private async Task<List<DateOnly>> GetWorkDaysAsync(ApplicationsInWork appInWork)
|
||||
{
|
||||
var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||
var periodType = ParseDistributionPeriodType(period!.Type);
|
||||
//var period = appInWork.EsppSchValues.FirstOrDefault()?.EsppSchTypeValue?.DistributionPeriod;
|
||||
//var periodType = ParseDistributionPeriodType(period!.Type);
|
||||
|
||||
//старт период, берем сейчас, будем получать рабочие дни с вычетом выходных на весь период сразу.
|
||||
var startPeriod = DateOnly.FromDateTime(DateTimeOffset.UtcNow.Date);
|
||||
// старт период считаем относительно refDate
|
||||
//var startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(appInWork.Id, appInWork.ReferenceDate, appInWork.ReferenceDate, periodType, period.Duration);
|
||||
////старт период, берем сейчас, будем получать рабочие дни с вычетом выходных на весь период сразу.
|
||||
//var startPeriod = DateOnly.FromDateTime(DateTimeOffset.UtcNow.Date);
|
||||
//// старт период считаем относительно refDate
|
||||
////var startPeriod = await esppScheduleTransformService.GetStartPeriodForDateAsync(appInWork.Id, appInWork.ReferenceDate, appInWork.ReferenceDate, periodType, period.Duration);
|
||||
|
||||
var workDays = calendarService.GetWorkDatesForPeriod(startPeriod, TimeOnly.FromDateTime(appInWork.ReferenceDate.DateTime), periodType, period.Duration, weekendDayService.GetWeekends);
|
||||
//var workDays = calendarService.GetWorkDatesForPeriod(startPeriod, TimeOnly.FromDateTime(appInWork.ReferenceDate.DateTime), periodType, period.Duration, weekendDayService.GetWeekends);
|
||||
|
||||
#region старая логика
|
||||
//var resultWorkDays = new List<DateOnly>();
|
||||
//#region старая логика
|
||||
////var resultWorkDays = new List<DateOnly>();
|
||||
|
||||
//workDays.ForEach(wd =>
|
||||
//{
|
||||
// var wrokDateTimeOffset = new DateTimeOffset(
|
||||
// wd.Year, wd.Month, wd.Day,
|
||||
// appInWork.ReferenceDate.Hour, appInWork.ReferenceDate.Minute, appInWork.ReferenceDate.Second,
|
||||
// new TimeSpan(0, 0, 0));
|
||||
////workDays.ForEach(wd =>
|
||||
////{
|
||||
//// var wrokDateTimeOffset = new DateTimeOffset(
|
||||
//// wd.Year, wd.Month, wd.Day,
|
||||
//// appInWork.ReferenceDate.Hour, appInWork.ReferenceDate.Minute, appInWork.ReferenceDate.Second,
|
||||
//// new TimeSpan(0, 0, 0));
|
||||
|
||||
// if (wrokDateTimeOffset < DateTimeOffset.UtcNow)
|
||||
// {
|
||||
// wrokDateTimeOffset = esppScheduleTransformService.GetNextDateForDistributionRun(wrokDateTimeOffset, periodType, period.Duration);
|
||||
// //wd = DateOnly.FromDateTime(wrokDateTimeOffset.DateTime);
|
||||
// resultWorkDays.Add(DateOnly.FromDateTime(wrokDateTimeOffset.DateTime));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// resultWorkDays.Add(wd);
|
||||
// }
|
||||
//});
|
||||
//// if (wrokDateTimeOffset < DateTimeOffset.UtcNow)
|
||||
//// {
|
||||
//// wrokDateTimeOffset = esppScheduleTransformService.GetNextDateForDistributionRun(wrokDateTimeOffset, periodType, period.Duration);
|
||||
//// //wd = DateOnly.FromDateTime(wrokDateTimeOffset.DateTime);
|
||||
//// resultWorkDays.Add(DateOnly.FromDateTime(wrokDateTimeOffset.DateTime));
|
||||
//// }
|
||||
//// else
|
||||
//// {
|
||||
//// resultWorkDays.Add(wd);
|
||||
//// }
|
||||
////});
|
||||
|
||||
////----- убираем даты, которые могли выйти за конец периода (из-за сдвига NextRun по рабочим дням)
|
||||
//var endPeriod = calendarService.GetEndPeriodDate(DateOnly.FromDateTime(DateTimeOffset.UtcNow.Date), periodType, period.Duration);
|
||||
//resultWorkDays = resultWorkDays.Where(t => t <= endPeriod).Distinct().OrderBy(t => t).ToList();
|
||||
////-----
|
||||
//////----- убираем даты, которые могли выйти за конец периода (из-за сдвига NextRun по рабочим дням)
|
||||
////var endPeriod = calendarService.GetEndPeriodDate(DateOnly.FromDateTime(DateTimeOffset.UtcNow.Date), periodType, period.Duration);
|
||||
////resultWorkDays = resultWorkDays.Where(t => t <= endPeriod).Distinct().OrderBy(t => t).ToList();
|
||||
//////-----
|
||||
|
||||
//return resultWorkDays;
|
||||
#endregion
|
||||
////return resultWorkDays;
|
||||
//#endregion
|
||||
|
||||
return workDays;
|
||||
//return workDays;
|
||||
|
||||
return new List<DateOnly>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -41,6 +41,28 @@ namespace PARR.Test
|
||||
#region test
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var unitService = scope.ServiceProvider.GetService<IUnitService>();
|
||||
|
||||
var unitsQuery = unitService!.Get()
|
||||
.Include(t => t.UnitValues)
|
||||
.ThenInclude(t => t.Field)
|
||||
.Include(t => t.UnitValues)
|
||||
.ThenInclude(t => t.Value)
|
||||
.Include(t => t.ParentUnits)
|
||||
.Include(t => t.ChildUnits)
|
||||
.Where(t => EF.Functions.Like(t.Name, "%-ГВЦ") &&
|
||||
t.UnitValues.Any(v =>
|
||||
v.Field!.AihitName == "ПОДКАТЕГОРИЯ_ЭК" && v.Value!.Value == "система хранения данных (схд)")
|
||||
&& t.UnitValues.Any(v =>
|
||||
v.Field!.AihitName == "ТИП_ЭК" && v.Value!.Value == "коммутатор")
|
||||
//&& t.UnitValues.Any(v =>
|
||||
// v.Field!.AihitName == "АКТИВЕН" && v.Value!.Value == "1")
|
||||
// && t.UnitValues.Any(v =>
|
||||
// v.Field!.AihitName == "НЕУНИКАЛЬНЫЙ_ЭК" && v.Value!.Value == "0")
|
||||
);
|
||||
|
||||
var v1 = await unitsQuery.Where(t => t.UnitValues.Any(v =>
|
||||
v.Field!.AihitName == "НЕУНИКАЛЬНЫЙ_ЭК" && v.Value!.Value == "0")).ToListAsync();
|
||||
/*var service = scope.ServiceProvider.GetService<ITemplateNameGeneratorService>();
|
||||
|
||||
var ttt = await service.GetTemplateNameAsync(Guid.Parse("ba05948b-b040-48cc-ab77-0accc9c223a0"), Guid.Parse("d4a86f24-6975-4614-98ab-431f26e3eb69"));*/
|
||||
|
||||
Reference in New Issue
Block a user