using System; using System.Threading; using System.Threading.Tasks; 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; namespace AsbCloudWebApi.Controllers.ProcessMaps; /// /// РТК /// [ApiController] [Route("api/well/{idWell}/[controller]")] [Authorize] public abstract class ProcessMapBaseController : ControllerBase where TProcessMap : ProcessMapBaseDto { protected int IdUser { get { var idUser = User.GetUserId(); if (!idUser.HasValue) throw new ForbidException("Неизвестный пользователь"); return idUser.Value; } } protected readonly IWellService wellService; protected readonly IRepositoryWellRelated repository; protected readonly IUserRepository userRepository; protected ProcessMapBaseController(IWellService wellService, IRepositoryWellRelated repository, IUserRepository userRepository) { this.wellService = wellService; this.repository = repository; this.userRepository = userRepository; } /// /// Создание РТК /// /// Тело запроса /// Id скважины /// /// [HttpPost] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public virtual async Task InsertAsync(TProcessMap processMap, int idWell, CancellationToken cancellationToken) { processMap.IdWell = idWell; processMap.IdUser = IdUser; processMap.LastUpdate = DateTime.UtcNow; await AssertUserHasAccessToEditProcessMapAsync(processMap.IdWell, cancellationToken); var result = await repository.InsertAsync(processMap, cancellationToken); return Ok(result); } /// /// Обновление РТК /// /// Тело запроса /// Id скважины /// /// [HttpPut] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public virtual async Task UpdateAsync(TProcessMap processMap, int idWell, CancellationToken cancellationToken) { processMap.IdWell = idWell; processMap.IdUser = IdUser; processMap.LastUpdate = DateTime.UtcNow; await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); var result = await repository.UpdateAsync(processMap, cancellationToken); if (result == ICrudRepository.ErrorIdNotFound) return this.ValidationBadRequest(nameof(processMap.Id), $"РТК с Id: {processMap.Id} не существует"); return Ok(result); } /// /// Удаление РТК /// /// Id скважины /// /// [HttpDelete] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public virtual async Task DeleteAsync(int idWell, CancellationToken cancellationToken) { await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); var result = await repository.DeleteAsync(idWell, cancellationToken); return Ok(result); } /// /// Получение РТК по Id скважины /// /// Id скважины /// /// [HttpGet] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task GetAsync(int idWell, CancellationToken cancellationToken) { var processMaps = await repository.GetByIdWellAsync(idWell, cancellationToken); return Ok(processMaps); } protected virtual async Task AssertUserHasAccessToEditProcessMapAsync(int idWell, CancellationToken cancellationToken) { var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) ?? throw new ArgumentInvalidException(nameof(idWell),$"Скважины с {idWell} не существует"); var idCompany = User.GetCompanyId(); if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken)) throw new ForbidException("Нет доступа к скважине"); if (well.IdState == 2 && !userRepository.HasPermission(IdUser, "WellDrillingProcessMap.editCompletedWell")) throw new ForbidException("Недостаточно прав для редактирования РТК завершенной скважины"); } }