Files
parr_api/PARR.API/Controllers/V1/JobGroupController.cs

368 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AutoMapper;
using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Requests;
using PARR.API.Contracts.V1.Requests.Queries;
using PARR.API.Contracts.V1.Responses;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.API.Extensions;
using PARR.API.Services.Interfaces;
using PARR.Constants;
using PARR.DAL.Contracts;
using PARR.DAL.DomainModels;
using PARR.DAL.Models;
using PARR.DAL.Models.Job;
using PARR.DAL.Services.Interfaces;
using PARR.DAL.Services.Interfaces.Job;
namespace PARR.API.Controllers.V1
{
/// <summary>
/// Управление группами работам
/// </summary>
[Authorize(Roles = ParrRoles.Administrator.Role)]
public class JobGroupController : BaseApiController
{
private readonly ILogger<JobController> logger;
private readonly IMapper mapper;
private readonly IUriService uriService;
private readonly IJobGroupService groupService;
private readonly IJobService jobService;
private readonly IEsppSchTypeConfigService esppConfigService;
private readonly IValidator<JobGroupRequest> validator;
private readonly SettingsFromDb settingsFromDb;
public JobGroupController(
ILogger<JobController> logger,
IMapper mapper,
IUriService uriService,
IJobGroupService groupService,
IJobService jobService,
IEsppSchTypeConfigService esppConfigService,
IValidator<JobGroupRequest> validator,
SettingsFromDb settingsFromDb
)
{
this.logger = logger;
this.mapper = mapper;
this.uriService = uriService;
this.groupService = groupService;
this.jobService = jobService;
this.esppConfigService = esppConfigService;
this.validator = validator;
this.settingsFromDb = settingsFromDb;
}
/// <summary>
/// Получить список групп заданий на выполнение работ постранично
/// </summary>
/// <returns></returns>
[HttpGet(ApiRoutes.JobGroup.GetAll)]
public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] JobGroupQuery filter)
{
var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
IQueryable<JobGroup> query = groupService.Get().Include(t => t.GroupType);
query = query.OrderBy(t => t.GroupName);
if (!string.IsNullOrEmpty(filter.Name))
query = query.Where(t => t.GroupName.ToLower().Contains(filter.Name.ToLower()));
if (filter.IsFull)
query = query.Include(t => t.Jobs).ThenInclude(t => t.Tnk);
var jobGroups = await groupService.GetPage(query, paginationFilter).ToListAsync();
if (!jobGroups.Any())
return NoContent();
var response = mapper.Map<List<JobGroupResponse>>(jobGroups);
if (filter.IsFull)
foreach (var jobGroupResponse in response)
await AppendMissingDataAsync(jobGroupResponse);
var paginationResponse = new PagedResponse<JobGroupResponse>(response, true).GetPaginatedProps(paginationFilter, query);
return Ok(paginationResponse);
}
/// <summary>
/// Получить группу заданий на выполнение работ по id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet(ApiRoutes.JobGroup.Get)]
public async Task<IActionResult> GetById([FromRoute] Guid id)
{
var jobGroup = await groupService.Get()
.Include(t => t.Jobs).ThenInclude(t => t.Tnk)
.Include(t => t.GroupType)
.FirstOrDefaultAsync(t => t.Id == id);
if (jobGroup == null)
return NotFound();
var response = mapper.Map<JobGroupResponse>(jobGroup);
await AppendMissingDataAsync(response);
return Ok(new Response<JobGroupResponse>(response, true));
}
/// <summary>
/// Создать группу заданий на выполнение работ (JobGroup)
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost(ApiRoutes.JobGroup.Create)]
public async Task<IActionResult> Create([FromBody] JobGroupRequest request)
{
var resultValidate = await validator.ValidateAsync(request);
if (!resultValidate.IsValid)
return BadRequest(new Response(resultValidate.Errors));
var jobGroup = new JobGroup
{
Id = Guid.NewGuid(),
GroupName = request.Name.Trim(),
//IsUmbrella = request.IsUmbrella,
GroupTypeId = request.GroupTypeId,
ShortDescription = request.ShortDescription.Trim(),
FullDescription = request.FullDescription.Trim(),
Solution = request.Solution.Trim(),
TemplateDuration = request.TemplateDuration.Trim(),
ReferenceDate = request.ReferenceDate,
//IsAutoDistributionEnabled = request.IsAutoDistributionEnabled,
//IsAgent = request.IsAgent,
//AgentName = request.AgentName,
//AgentTimeOutSec = request.AgentTimeOutSec,
//AgentScript = request.AgentScript
};
//Добавляем настройки планировщика
request.Schedule.ForEach(item =>
{
jobGroup.EsppSchValues.Add(new EsppSchValue
{
JobGroupId = jobGroup.Id,
TypeConfigId = item.TypeConfigId,
TypeValueId = item.TypeValueId
});
});
if (!await groupService.CreateAsync(jobGroup) || !await groupService.CommitAsync())
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при создании группы заданий на выполнение работ" } }));
logger.LogInformation($"Пользователь {User.Identity?.Name} добавил группу заданий на выполнение работ: {jobGroup.Id}, {jobGroup.GroupName}, {jobGroup.ShortDescription}");
var createdJobGroup = await groupService.Get().Include(t => t.Jobs).ThenInclude(t => t.Tnk)
.Include(t => t.GroupType)
.FirstAsync(t => t.Id == jobGroup.Id);
var locationUri = uriService.GetUri(ApiRoutes.JobGroup.Get, ApiRoutes.JobGroup.getParam, createdJobGroup.Id);
var response = mapper.Map<JobGroupResponse>(createdJobGroup);
return Created(locationUri, new Response<JobGroupResponse>(response, true));
}
/// <summary>
/// Обновить группу заданий на выполнение работ (JobGroup)
/// </summary>
/// <param name="id"></param>
/// <param name="request"></param>
/// <returns></returns>
[HttpPut(ApiRoutes.JobGroup.Update)]
public async Task<IActionResult> Update([FromRoute] Guid id, [FromBody] JobGroupRequest request)
{
var resultValidate = await validator.ValidateAsync(request);
if (!resultValidate.IsValid)
return BadRequest(new Response(resultValidate.Errors));
var orig = await groupService.Get()
.Include(t => t.Jobs)
.ThenInclude(t => t.Tnk)
.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}" } }));
// //Расписание было изменено, ниже добавим задание в очередь на обновление расписаний у связанных шаблонов
var isScheduleChanged = IsScheduleChanged(orig, request);
orig.GroupName = request.Name.Trim();
//orig.IsUmbrella = request.IsUmbrella;
orig.GroupTypeId = request.GroupTypeId;
orig.ShortDescription = request.ShortDescription.Trim();
orig.FullDescription = request.FullDescription.Trim();
orig.Solution = request.Solution.Trim();
orig.TemplateDuration = request.TemplateDuration.Trim();
orig.ReferenceDate = request.ReferenceDate;
//orig.IsAutoDistributionEnabled = request.IsAutoDistributionEnabled;
//orig.IsAgent = request.IsAgent;
//orig.AgentName = request.AgentName;
//orig.AgentTimeOutSec = request.AgentTimeOutSec;
//orig.AgentScript = request.AgentScript;
orig.DateModified = DateTimeOffset.UtcNow;
//обновляем планировщик
orig.EsppSchValues.Clear();
request.Schedule.ForEach(item =>
{
orig.EsppSchValues.Add(new EsppSchValue
{
JobGroupId = orig.Id,
TypeConfigId = item.TypeConfigId,
TypeValueId = item.TypeValueId
});
});
if (!await groupService.CommitAsync())
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Ошибка при изменении группы заданий на выполнение работ." } }));
logger.LogInformation($"Пользователь {User.Identity?.Name} обновил группу заданий на выполнение работ: {orig.Id}," +
$" {orig.GroupName}, {orig.IsUmbrella}, {orig.ShortDescription}, {orig.FullDescription}," +
$" {orig.Solution}, {orig.TemplateDuration}, {orig.ReferenceDate}, {orig.IsAutoDistributionEnabled}" +
$", {orig.IsAgent}, {orig.AgentName}, {orig.AgentTimeOutSec}, {orig.AgentScript}");
//TODO: Восстановить после перехода на JobGroup
//if (isScheduleChanged)
//{
// //расписание было обновлено, отправим задание в очередь на перерасчет NextRun
// var requestToMq = new TemplateDistributorMq
// {
// ApplicationInWorkId = id
// };
// var msg = JsonSerializer.Serialize(requestToMq);
// logger.LogDebug($"Расписание в РР applicationInWorkId: {id} было изменено. Отправляем задание в очередь на перерасчет NextRun");
// 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}");
//}
var updatedJobGroup = await groupService.Get()
.Include(t => t.Jobs)
.ThenInclude(t => t.Tnk)
.Include(t => t.GroupType)
.FirstAsync(t => t.Id == orig.Id);
var response = mapper.Map<JobGroupResponse>(updatedJobGroup);
return Ok(new Response<JobGroupResponse>(response, true));
}
/// <summary>
/// Удалить группу заданий на выполнение работ (только если нет связанных заданий)
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete(ApiRoutes.JobGroup.Delete)]
public async Task<IActionResult> Delete([FromRoute] Guid id)
{
var jobGroup = await groupService.Get()
.FirstOrDefaultAsync(t => t.Id == id);
if (jobGroup == null)
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
Message = $"Ошибка при удалении группы заданий на выполнение работ. Не найдена группа заданий на выполнение работ Id: {id}"
} }));
var jobCount = await jobService.Get().CountAsync(t => t.GroupId == id);
if (jobCount > 0)
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
Message = $"Ошибка при удалении группы заданий на выполнение работ. С данным группой связаны задания: {jobCount} шт."
} }));
if (!groupService.Delete(jobGroup) || !await groupService.CommitAsync())
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel {
Message = $"Ошибка при удалении группы заданий на выполнение работ"
} }));
logger.LogInformation($"Пользователь {User.Identity?.Name} удалил группу заданий на выполнение работ: {jobGroup.Id},{jobGroup.GroupName}," +
$" {jobGroup.IsUmbrella}, {jobGroup.ShortDescription}, {jobGroup.FullDescription}," +
$" {jobGroup.Solution}, {jobGroup.TemplateDuration}, {jobGroup.ReferenceDate}" +
$"{jobGroup.IsAutoDistributionEnabled}, {jobGroup.IsAgent}, {jobGroup.AgentName}" +
$"{jobGroup.AgentTimeOutSec}, {jobGroup.AgentScript}");
return NoContent();
}
/// <summary>
/// Проверка, были ли изменения в расписании
/// </summary>
/// <param name="orig"></param>
/// <param name="request"></param>
/// <returns></returns>
private bool IsScheduleChanged(JobGroup orig, JobGroupRequest request)
{
var isScheduleChanged = false;
if (orig.ReferenceDate != request.ReferenceDate)
isScheduleChanged = true;
if (request.Schedule.Count() != orig.EsppSchValues.Count())
isScheduleChanged = true;
//if (request.IsAutoDistributionEnabled != orig.IsAutoDistributionEnabled)
// isScheduleChanged = true;
request.Schedule.ForEach(requestSchedule =>
{
var schExist = orig.EsppSchValues.FirstOrDefault(t => t.JobGroupId == orig.Id
&& t.TypeValueId == requestSchedule.TypeValueId
&& t.TypeConfigId == requestSchedule.TypeConfigId);
if (schExist == null)
isScheduleChanged = true;
});
return isScheduleChanged;
}
private async Task AppendMissingDataAsync(JobGroupResponse jobGroupResponse)
{
var schedule = await esppConfigService.GetEsppScheduleDtoAsync(jobGroupResponse.Id);
if (schedule == null)
{
logger.LogError($"Не смог замапить расписание, так как оно null. JobGroupId: {jobGroupResponse.Id}");
return;
}
var scheduleResponse = new JobGroupScheduleResponse
{
Timezone = settingsFromDb.ScheduleTimezone,
TypeSchedule = mapper.Map<EsppScheduleTypeScheduleResponse>(schedule.TypeSchedule),
Values = mapper.Map<List<EsppScheduleValResponse>>(schedule.Values).OrderBy(t => t.Order).ToList()
};
jobGroupResponse.Schedule = scheduleResponse;
jobGroupResponse.JobsCount = await jobService.Get().CountAsync(t => t.GroupId == jobGroupResponse.Id);
}
}
}