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 SubprocessController : BaseApiController { private readonly ILogger logger; private readonly IMapper mapper; private readonly ISubprocessService subprocessService; private readonly IValidator validator; private readonly IUriService uriService; public SubprocessController( ILogger logger, IMapper mapper, ISubprocessService subprocessService, IValidator validator, IUriService uriService ) { this.logger = logger; this.mapper = mapper; this.subprocessService = subprocessService; this.validator = validator; this.uriService = uriService; } /// /// Список подпроцессов постранично /// /// /// [HttpGet(ApiRoutes.Subprocess.GetAll)] public async Task GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] SubprocessQuery filter) { var paginationFilter = mapper.Map(paginationQuery); IQueryable query = subprocessService.Get() .OrderBy(t => t.Name); if (filter.ProcessId.HasValue) query = query.Where(t => t.ProcessId == filter.ProcessId.Value); var subprocesses = await subprocessService.GetPage(query, paginationFilter).ToListAsync(); if (!subprocesses.Any()) return NoContent(); var subprocessesResponse = mapper.Map>(subprocesses); var paginationResponse = new PagedResponse(subprocessesResponse, true).GetPaginatedProps(paginationFilter, query); return Ok(paginationResponse); } /// /// Получить подпроцесс по id /// /// /// [HttpGet(ApiRoutes.Subprocess.Get)] public async Task GetById([FromRoute] Guid id) { var subprocess = await subprocessService.Get() .FirstOrDefaultAsync(t => t.Id == id); if (subprocess == null) return NotFound(); var response = mapper.Map(subprocess); return Ok(new Response(response, true)); } /// /// Получить связанные с подпроцессом ТНК /// /// /// [HttpGet(ApiRoutes.Subprocess.GetTnks)] public async Task Get([FromRoute] Guid id) { var subprocess = await subprocessService.Get() .Include(t => t.Tnks) .FirstOrDefaultAsync(t => t.Id == id); 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()); return Ok(new Response>(response, true)); } /// /// Создать подпроцесс /// /// /// [HttpPost(ApiRoutes.Subprocess.Create)] public async Task Create([FromBody] SubprocessRequest request) { var resultValidate = await validator.ValidateAsync(request); if (!resultValidate.IsValid) return BadRequest(new Response(resultValidate.Errors)); var existName = await subprocessService.Get().FirstOrDefaultAsync(t => t.Name.ToLower() == request.Name.Trim().ToLower()); if (existName != null) return BadRequest(new Response(false, new List { new ErrorModel { FieldName = nameof(request.Name), Message = $"Подпроцесс с именем \"{request.Name}\" уже существует." } })); var existEsppId = await subprocessService.Get().FirstOrDefaultAsync(t => t.EsppId == request.EsppId); if (existEsppId != null) return BadRequest(new Response(false, new List { new ErrorModel { FieldName = nameof(request.EsppId), Message = $"Подпроцесс с EsppId: {request.EsppId} уже существует." } })); var subprocess = new Subprocess { Id = Guid.NewGuid(), Name = request.Name.Trim(), EsppId = request.EsppId, ProcessId = request.ProcessId, }; if (!await subprocessService.CreateAsync(subprocess) || !await subprocessService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при добавлении подпроцесса." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} добавил подпроцесс: {subprocess.Name}, {subprocess.EsppId}, {subprocess.ProcessId}"); var locationUri = uriService.GetUri(ApiRoutes.Subprocess.Get, ApiRoutes.Subprocess.getParam, subprocess.Id); return Created(locationUri, new Response(mapper.Map(subprocess), true)); } /// /// Обновить подпроцесс /// /// /// /// [HttpPut(ApiRoutes.Subprocess.Update)] public async Task Update([FromRoute] Guid id, [FromBody] SubprocessRequest request) { var resultValidate = await validator.ValidateAsync(request); if (!resultValidate.IsValid) return BadRequest(new Response(resultValidate.Errors)); //проверка на уникальность esppId var existEsppId = await subprocessService.Get().FirstOrDefaultAsync(t => t.Id != id && t.EsppId == request.EsppId); if (existEsppId != null) return BadRequest(new Response(false, new List { new ErrorModel { FieldName = nameof(request.EsppId), Message = $"Уже есть подпроцесс с EsppId: {request.EsppId}" } })); var orig = await subprocessService.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.Trim(); orig.EsppId = request.EsppId; orig.ProcessId = request.ProcessId; orig.DateModified = DateTimeOffset.UtcNow; if (!await subprocessService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка записи в базу данных изменений подпроцесса." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} обновил подпроцесс: {orig.Id}, {orig.Name}, {orig.EsppId}, {orig.ProcessId}"); return Ok(new Response(mapper.Map(orig), true)); } /// /// Удалить подпроцесс (если у него нет ТНК) /// /// /// [HttpDelete(ApiRoutes.Subprocess.Delete)] public async Task Delete([FromRoute] Guid id) { var subprocess = await subprocessService.Get().Include(t=>t.Tnks).FirstOrDefaultAsync(t=>t.Id==id); if (subprocess == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении подпроцесса." } })); if (subprocess.Tnks.Any()) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении подпроцесса. У данного подпроцесса есть ТНК ({subprocess.Tnks.Count()} шт.)" } })); if (!subprocessService.Delete(subprocess) || !await subprocessService.CommitAsync()) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при удалении подпроцесса." } })); logger.LogInformation($"Пользователь {User.Identity?.Name} удалил подпроцесс: {subprocess.Id}, {subprocess.Name}, {subprocess.EsppId}, {subprocess.ProcessId}"); return NoContent(); } } }