diff --git a/PARR.API/Contracts/V1/Requests/ProcessRequest.cs b/PARR.API/Contracts/V1/Requests/ProcessRequest.cs new file mode 100644 index 00000000..b94972d6 --- /dev/null +++ b/PARR.API/Contracts/V1/Requests/ProcessRequest.cs @@ -0,0 +1,8 @@ +namespace PARR.API.Contracts.V1.Requests +{ + public class ProcessRequest + { + public required string Name { get; set; } + public int EsppId { get; set; } + } +} diff --git a/PARR.API/Controllers/V1/ProcessController.cs b/PARR.API/Controllers/V1/ProcessController.cs new file mode 100644 index 00000000..020f503d --- /dev/null +++ b/PARR.API/Controllers/V1/ProcessController.cs @@ -0,0 +1,201 @@ +using AutoMapper; +using FluentValidation; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using PARR.API.Contracts.V1; +using PARR.API.Contracts.V1.Requests; +using PARR.API.Contracts.V1.Responses.Base; +using PARR.API.Contracts.V1.Responses; +using PARR.API.Controllers.V1.Base; +using PARR.API.Services.Interfaces; +using PARR.Constants; +using PARR.DAL.Services.Interfaces; +using Microsoft.EntityFrameworkCore; +using PARR.DAL.Models; +using PARR.API.Contracts.V1.Requests.Queries; +using PARR.API.Extensions; +using PARR.DAL.DomainModels; + +namespace PARR.API.Controllers.V1 +{ + /// + /// Управление процессами + /// + [Authorize(Roles = ParrRoles.Administrator.Role)] + public class ProcessController : BaseApiController + { + private readonly ILogger logger; + private readonly IMapper mapper; + private readonly IProcessService processService; + private readonly IValidator validator; + private readonly IUriService uriService; + + public ProcessController( + ILogger logger, + IMapper mapper, + IProcessService processService, + IValidator validator, + IUriService uriService + ) + { + this.logger = logger; + this.mapper = mapper; + this.processService = processService; + this.validator = validator; + this.uriService = uriService; + } + + + /// + /// Создать процесс + /// + /// + /// + [HttpPost(ApiRoutes.Process.Create)] + public async Task Create([FromBody] ProcessRequest request) + { + var resultValidate = await validator.ValidateAsync(request); + if (!resultValidate.IsValid) + return BadRequest(new Response(resultValidate.Errors)); + + var existName = await processService.Get().FirstOrDefaultAsync(t => t.Name == request.Name); + if (existName != null) + return BadRequest(new Response(false, new List { new ErrorModel { FieldName = nameof(request.Name), Message = $"Процесс с именем \"{request.Name}\" уже существует." } })); + + var process = new Process + { + Id = Guid.NewGuid(), + Name = request.Name, + EsppId = request.EsppId + }; + + if (!await processService.CreateAsync(process) || !await processService.CommitAsync()) + return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при записи нового процесса в базу данных" } })); + + logger.LogInformation($"Пользователь {User.Identity?.Name} добавил процесс: {process.Name}, {process.EsppId}"); + + var locationUri = uriService.GetUri(ApiRoutes.Process.Get, ApiRoutes.Process.getParam, process.Id); + + return Created(locationUri, new Response(mapper.Map(process), true)); + } + + + /// + /// Список процессов постранично + /// + /// + /// + [HttpGet(ApiRoutes.Process.GetAll)] + public async Task GetAll([FromQuery] PaginationQuery paginationQuery) + { + var paginationFilter = mapper.Map(paginationQuery); + + IQueryable query = processService.Get() + .OrderBy(t => t.Name); + + var processes = await processService.GetPage(query, paginationFilter).ToListAsync(); + + if (!processes.Any()) + return NoContent(); + + var processesResponse = mapper.Map>(processes); + var paginationResponse = new PagedResponse(processesResponse, true).GetPaginatedProps(paginationFilter, query); + + return Ok(paginationResponse); + } + + + /// + /// Получить процесс по id + /// + /// + /// + [HttpGet(ApiRoutes.Process.Get)] + public async Task GetById([FromRoute] Guid id) + { + var process = await processService.Get() + .FirstOrDefaultAsync(t => t.Id == id); + + if (process == null) + return NotFound(); + + var response = mapper.Map(process); + + return Ok(new Response(response, true)); + } + + + /// + /// Получить связанные с процессом подпроцессы + /// + /// + /// + [HttpGet(ApiRoutes.Process.GetSubprcesses)] + public async Task Get([FromRoute] Guid id) + { + var process = await processService.Get() + .Include(t => t.Subprocesses) + .FirstOrDefaultAsync(t => t.Id == id); + + if (process == null) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найден процесс с id: {id}" } })); + + var response = mapper.Map>(process.Subprocesses.OrderBy(t => t.Name).ToList()); + + return Ok(new Response>(response, true)); + } + + + /// + /// Обновить процесс + /// + /// + /// + /// + [HttpPut(ApiRoutes.Process.Update)] + public async Task Update([FromRoute] Guid id, [FromBody] ProcessRequest request) + { + var resultValidate = await validator.ValidateAsync(request); + if (!resultValidate.IsValid) + return BadRequest(new Response(resultValidate.Errors)); + + var orig = await processService.Get() + .FirstOrDefaultAsync(t => t.Id == id); + + if (orig == null) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при изменении процесса. Не найден процесс Id: {id}" } })); + + orig.Name = request.Name; + orig.EsppId = request.EsppId; + + if (!await processService.CommitAsync()) + return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка записи в базу данных изменений процесса." } })); + + logger.LogInformation($"Пользователь {User.Identity?.Name} обновил процесс: {orig.Id}, {orig.Name}, {orig.EsppId}"); + + return Ok(new Response(mapper.Map(orig), true)); + } + + + /// + /// Удалить подпроцесс + /// + /// + /// + [HttpDelete(ApiRoutes.Process.Delete)] + public async Task Delete([FromRoute] Guid id) + { + var process = await processService.GetAsync(id); + + if (process == null) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении процесса. Не найден процесс Id: {id}" } })); + + if (!processService.Delete(process) || !await processService.CommitAsync()) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении процесса из базы данных" } })); + + logger.LogInformation($"Пользователь {User.Identity?.Name} удалил процесс: {process.Id}, {process.Name}, {process.EsppId}"); + + return NoContent(); + } + } +} diff --git a/PARR.API/Controllers/V1/SubprocessController.cs b/PARR.API/Controllers/V1/SubprocessController.cs index af6df569..1da2c3a7 100644 --- a/PARR.API/Controllers/V1/SubprocessController.cs +++ b/PARR.API/Controllers/V1/SubprocessController.cs @@ -19,7 +19,7 @@ using PARR.DAL.Services.Interfaces; namespace PARR.API.Controllers.V1 { /// - /// Управление Подпроцессами + /// Управление подпроцессами /// [Authorize(Roles = ParrRoles.Administrator.Role)] public class SubprocessController : BaseApiController @@ -141,9 +141,9 @@ namespace PARR.API.Controllers.V1 if (subprocess == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найден подпроцесс с id: {id}" } })); - var response = mapper.Map>(subprocess.Tnks.OrderBy(t => t.Name).ToList()); + var response = mapper.Map>(subprocess.Tnks.OrderBy(t => t.Name).ToList()); - return Ok(new Response>(response, true)); + return Ok(new Response>(response, true)); } @@ -164,7 +164,7 @@ namespace PARR.API.Controllers.V1 .FirstOrDefaultAsync(t => t.Id == id); if (orig == null) - return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при изменении подпроцесса. Не найдена подпроцесс Id: {id}" } })); + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при изменении подпроцесса. Не найден подпроцесс Id: {id}" } })); orig.Name = request.Name; orig.EsppId = request.EsppId; diff --git a/PARR.API/Validators/ProcessValidator.cs b/PARR.API/Validators/ProcessValidator.cs new file mode 100644 index 00000000..c5612e19 --- /dev/null +++ b/PARR.API/Validators/ProcessValidator.cs @@ -0,0 +1,17 @@ +using FluentValidation; +using PARR.API.Contracts.V1.Requests; + +namespace PARR.API.Validators +{ + public class ProcessValidator : AbstractValidator + { + private bool? isValid = null; + + public ProcessValidator() + { + RuleFor(t => t.Name).NotEmpty().NotNull().WithMessage("Имя процесса не может быть пустым"); + + RuleFor(t => t.EsppId).NotEmpty().NotNull().WithMessage("EsppId не может быть пустым"); + } + } +}