diff --git a/AsbCloudWebApi/Controllers/WellSections/WellSectionPlanController.cs b/AsbCloudWebApi/Controllers/WellSections/WellSectionPlanController.cs new file mode 100644 index 00000000..68167edb --- /dev/null +++ b/AsbCloudWebApi/Controllers/WellSections/WellSectionPlanController.cs @@ -0,0 +1,168 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Data.WellSections; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Services; +using AsbCloudApp.Services.WellSections; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace AsbCloudWebApi.Controllers.WellSections; + +/// +/// Конструкция скважины - план +/// +[ApiController] +[Route("api/well/{idWell:int}/[controller]")] +[Authorize] +public class WellSectionPlanController : ControllerBase +{ + private readonly IWellSectionPlanService wellSectionPlanService; + private readonly IWellService wellService; + private readonly ICrudRepository wellSectionRepository; + private readonly IRepositoryWellRelated wellSectionPlanRepository; + + public WellSectionPlanController(IWellSectionPlanService wellSectionPlanService, + IWellService wellService, + ICrudRepository wellSectionRepository, + IRepositoryWellRelated wellSectionPlanRepository) + { + this.wellSectionPlanService = wellSectionPlanService; + this.wellService = wellService; + this.wellSectionRepository = wellSectionRepository; + this.wellSectionPlanRepository = wellSectionPlanRepository; + } + + //TODO: так же следует вынести в базовый контроллер + private int IdUser + { + get + { + var idUser = User.GetUserId(); + + if (!idUser.HasValue) + throw new ForbidException("Неизвестный пользователь"); + + return idUser.Value; + } + } + + /// + /// Добавить секцию + /// + /// Идентификатор скважины + /// Секция скважины - план + /// + /// + [HttpPost] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task InsertAsync(int idWell, WellSectionPlanDto wellSection, CancellationToken cancellationToken) + { + wellSection.IdWell = idWell; + wellSection.IdUser = IdUser; + + await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken); + + await AssertUserAccessToWell(idWell, cancellationToken); + + var wellSectionId = await wellSectionPlanService.InsertAsync(wellSection, cancellationToken); + + return Ok(wellSectionId); + } + + /// + /// Обновить секцию + /// + /// Идентификатор скважины + /// Секция скважины - план + /// + /// + [HttpPut] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task UpdateAsync(int idWell, WellSectionPlanDto wellSection, CancellationToken cancellationToken) + { + wellSection.IdWell = idWell; + wellSection.IdUser = IdUser; + + await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken); + + await AssertUserAccessToWell(idWell, cancellationToken); + + var wellSectionId = await wellSectionPlanService.UpdateAsync(wellSection, cancellationToken); + + if (wellSectionId == ICrudRepository.ErrorIdNotFound) + return this.ValidationBadRequest(nameof(wellSection.Id), $"Секции скважины с Id: {wellSection.Id} не существует"); + + return Ok(wellSectionId); + } + + /// + /// Получить типы секций + /// + /// Идентификатор скважины + /// + /// + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken) + { + await AssertUserAccessToWell(idWell, cancellationToken); + + var wellSectionTypes = await wellSectionPlanService.GetWellSectionTypesAsync(idWell, cancellationToken); + + if (!wellSectionTypes.Any()) + return NoContent(); + + return Ok(wellSectionTypes); + } + + /// + /// Удалить секцию + /// + /// Идентификатор скважины + /// Идентификатор плановой секции + /// + /// + [HttpDelete] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task DeleteAsync(int idWell, int id, CancellationToken cancellationToken) + { + await AssertUserAccessToWell(idWell, cancellationToken); + + var deletedWellSectionPlanCount = await wellSectionPlanRepository.DeleteAsync(id, cancellationToken); + + return Ok(deletedWellSectionPlanCount); + } + + //TODO: нужно создать базовый контроллер связанный со скважиной и вынести этот метод туда. Данный метод много где дублируется + private async Task AssertUserAccessToWell(int idWell, CancellationToken cancellationToken) + { + var idCompany = User.GetCompanyId(); + + if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken)) + throw new ForbidException("Нет доступа к скважине"); + } + + //TODO: тоже нужно вынести в базовый контроллер + private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken) + { + _ = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken) + ?? throw new ArgumentInvalidException(nameof(ProcessMapPlanWellDrillingDto.IdWellSectionType), + $"Тип секции с Id: {idWellSectionType} не найден"); + } +} \ No newline at end of file