using AsbCloudApp.Data; using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers.ProcessMaps; /// /// Конструкция скважины - план /// [ApiController] [Route("api/well/{idWell:int}/[controller]")] [Authorize] public class WellSectionPlanController : ControllerBase { private readonly IWellService wellService; private readonly IWellSectionPlanRepository wellSectionPlanRepository; private readonly ICrudRepository wellSectionRepository; public WellSectionPlanController(IWellService wellService, IWellSectionPlanRepository wellSectionPlanRepository, ICrudRepository wellSectionRepository) { this.wellService = wellService; this.wellSectionPlanRepository = wellSectionPlanRepository; this.wellSectionRepository = wellSectionRepository; } //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 wellSectionPlanRepository.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; wellSection.LastUpdateDate = DateTimeOffset.UtcNow; await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken); await AssertUserAccessToWell(idWell, cancellationToken); var wellSectionId = await wellSectionPlanRepository.UpdateAsync(wellSection, cancellationToken); if (wellSectionId == ICrudRepository.ErrorIdNotFound) return this.ValidationBadRequest(nameof(wellSection.Id), $"Секции скважины с Id: {wellSection.Id} не существует"); return Ok(wellSectionId); } /// /// Получить типы секций /// /// Идентификатор скважины /// /// [HttpGet("wellSectionTypes")] [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 wellSectionPlanRepository.GetWellSectionTypesAsync(idWell, cancellationToken); if (!wellSectionTypes.Any()) return NoContent(); return Ok(wellSectionTypes); } /// /// Получить список секций /// /// Идентификатор скважины /// /// [HttpGet] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task GetPlanWellSectionsAsync(int idWell, CancellationToken cancellationToken) { await AssertUserAccessToWell(idWell, cancellationToken); var planWellSections = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken); if (!planWellSections.Any()) return NoContent(); return Ok(planWellSections); } /// /// Удалить секцию /// /// Идентификатор скважины /// Идентификатор плановой секции /// /// [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(ProcessMapPlanBaseDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден"); } }