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.DomainModels; using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; namespace PARR.API.Controllers.V1 { [Authorize(Roles = ParrRoles.Administrator.Role)] public class ApplicationInWorkController : BaseApiController { private readonly ILogger logger; private readonly IMapper mapper; private readonly IApplicationsInWorkService applicationsInWorkService; private readonly IValidator validator; private readonly IUriService uriService; public ApplicationInWorkController( ILogger logger, IMapper mapper, IApplicationsInWorkService applicationsInWorkService, IValidator validator, IUriService uriService ) { this.logger = logger; this.mapper = mapper; this.applicationsInWorkService = applicationsInWorkService; this.validator = validator; this.uriService = uriService; } /// /// Получить список заданий на выполнение работ(ApplicationInWork) постранично /// /// [HttpGet(ApiRoutes.Job.GetAll)] public async Task GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] ApplicationInWorkQuery filter) { var paginationFilter = mapper.Map(paginationQuery); IQueryable query = applicationsInWorkService.Get() .Include(t => t.Application).ThenInclude(t => t!.ApplicationType) .Include(t => t.Work) .Include(t => t.Templates) .OrderBy(t => t.ShortDescription); if (!string.IsNullOrEmpty(filter.ShortDescription)) query = query.Where(t => t.ShortDescription.ToLower().Contains(filter.ShortDescription.ToLower())); var appInWorks = await applicationsInWorkService.GetPage(query, paginationFilter).ToListAsync(); if (!appInWorks.Any()) return NoContent(); var response = mapper.Map>(appInWorks); var paginationResponse = new PagedResponse(response, true).GetPaginatedProps(paginationFilter, query); return Ok(paginationResponse); } /// /// Получить задание на выполнение работ по id /// /// /// [HttpGet(ApiRoutes.Job.Get)] public async Task 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) .FirstOrDefaultAsync(t => t.Id == id); if (applicationInWork == null) return NotFound(); var response = mapper.Map(applicationInWork); return Ok(new Response(response, true)); } /// /// Создать задание на выполнение работ (ApplicationInWork) /// /// /// [HttpPost(ApiRoutes.Job.Create)] public async Task Create([FromBody] ApplicationInWorkRequest request) { var resultValidate = await validator.ValidateAsync(request); 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 { 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, 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 }); }); if (!await applicationsInWorkService.CreateAsync(applicationInWork) || !await applicationsInWorkService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при созании задания на выполнение работ" } })); logger.LogInformation($"Пользователь {User.Identity?.Name} добавил задание на выполнение работ: {applicationInWork.Id}, {applicationInWork.ShortDescription}, {applicationInWork.Solution}, {applicationInWork.NextRun}"); var createdApplicationInWork = await applicationsInWorkService.Get() .Include(t => t.Application).ThenInclude(t => t!.ApplicationType) .Include(t => t.Work) .Include(t => t.Templates) .FirstAsync(t => t.Id == applicationInWork.Id); var locationUri = uriService.GetUri(ApiRoutes.Job.Get, ApiRoutes.Job.getParam, createdApplicationInWork.Id); return Created(locationUri, new Response(mapper.Map(createdApplicationInWork), true)); } /// /// Обновить задание на выполнение работ (ApplicationInWork) /// /// /// /// [HttpPut(ApiRoutes.Job.Update)] public async Task 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 { new ErrorModel { Message = "Задание на выполнение работ с такими ПО и работой уже существует" } })); var orig = await applicationsInWorkService.GetAsync(id); if (orig == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при изменении задания на выполнение работ. Не найдено задание с Id: {id}" } })); 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.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 }); }); if (!await applicationsInWorkService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при изменении задания на выполнение работ." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} обновил задание на выполнение работ: {orig.Id}," + $" {orig.WorkId}, {orig.ApplicationId}, {orig.TemplateDuration}, {orig.ShortDescription}," + $" {orig.FullDescription}, {orig.Solution}, {orig.NextRun}, {orig.IsAgent}, {orig.AgentName}, {orig.AgentTimeOutSec}, {orig.AgentScript}"); var updatedApplicationInWork = await applicationsInWorkService.Get() .Include(t => t.Application).ThenInclude(t => t!.ApplicationType) .Include(t => t.Work) .Include(t => t.Templates) .FirstAsync(t => t.Id == orig.Id); return Ok(new Response(mapper.Map(updatedApplicationInWork), true)); } /// /// Удалить задание на выполнение работ (только если нет связанных шаблонов) /// /// /// [HttpDelete(ApiRoutes.Job.Delete)] public async Task 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 { new ErrorModel { Message = $"Ошибка при удалении задания на выполнение работ. Не найдено задание на выполнение работ Id: {id}" } })); if (applicationsInWork.Templates.Any()) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении задания на выполнение работ. С данным заданием связаны шаблоны: {applicationsInWork.Templates.Count()} шт." } })); if (!applicationsInWorkService.Delete(applicationsInWork) || !await applicationsInWorkService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении задания на выполнение работ" } })); logger.LogInformation($"Пользователь {User.Identity?.Name} удалил задание на выполнение работ: {applicationsInWork.Id},{applicationsInWork.WorkId}," + $" {applicationsInWork.ApplicationId}, {applicationsInWork.TemplateDuration}, {applicationsInWork.ShortDescription}," + $" {applicationsInWork.FullDescription}, {applicationsInWork.Solution}, {applicationsInWork.NextRun}, {applicationsInWork.IsAgent}," + $" {applicationsInWork.AgentName}, {applicationsInWork.AgentTimeOutSec}, {applicationsInWork.AgentScript}"); return NoContent(); } } }