using AsbCloudApp.Data.ProcessMapPlan; using AsbCloudApp.Repositories; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; using Microsoft.AspNetCore.Http; using AsbCloudApp.Exceptions; using AsbCloudApp.Requests; using System; using AsbCloudApp.Services; using System.Linq; namespace AsbCloudWebApi.Controllers.ProcessMapPlan; /// /// РТК план /// [ApiController] [Route("api/well/{idWell}/[controller]")] [Authorize] public abstract class ProcessMapPlanBaseController : ControllerBase where TDto : ProcessMapPlanBaseDto { private readonly IProcessMapPlanBaseRepository repository; private readonly IWellService wellService; public ProcessMapPlanBaseController(IProcessMapPlanBaseRepository repository, IWellService wellService) { this.repository = repository; this.wellService = wellService; } /// /// Добавление /// /// /// /// /// [HttpPost] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task InsertRange([FromRoute] int idWell, IEnumerable dtos, CancellationToken token) { if (idWell == 0 || dtos.Any(d => d.IdWell != idWell)) return this.ValidationBadRequest(nameof(dtos), "all dtos should contain same idWell"); var idUser = await AssertUserHasAccessToWell(idWell, token); var result = await repository.InsertRange(idUser, dtos, token); return Ok(result); } /// /// Удалить все по скважине и добавить новые /// /// /// /// /// [HttpPost("replace")] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task ClearAndInsertRange([FromRoute] int idWell, IEnumerable dtos, CancellationToken token) { if (idWell == 0 || dtos.Any(d => d.IdWell != idWell)) return this.ValidationBadRequest(nameof(dtos), "all dtos should contain same idWell"); var idUser = await AssertUserHasAccessToWell(idWell, token); var result = await repository.ClearAndInsertRange(idUser, idWell, dtos, token); return Ok(result); } /// /// Удаление /// /// /// /// /// [HttpDelete] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task DeleteRange([FromRoute]int idWell, IEnumerable ids, CancellationToken token) { var idUser = await AssertUserHasAccessToWell(idWell, token); var result = await repository.DeleteRange(idUser, ids, token); return Ok(result); } /// /// Получение /// /// /// /// /// [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task>> Get([FromRoute] int idWell, [FromQuery]ProcessMapPlanBaseRequest request, CancellationToken token) { await AssertUserHasAccessToWell(idWell, token); var result = await repository.Get(idWell, request, token); return Ok(result); } /// /// Изменения за определенную дату /// /// /// /// /// [HttpGet("changeLog")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task>> GetChangeLog([FromRoute] int idWell, [FromQuery] DateOnly? date, CancellationToken token) { await AssertUserHasAccessToWell(idWell, token); var result = await repository.GetChangeLog(idWell, date, token); return Ok(result); } /// /// Даты за которые есть изменения /// /// /// /// [HttpGet("dates")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task>> GetDatesChange([FromRoute] int idWell, CancellationToken token) { await AssertUserHasAccessToWell(idWell, token); var result = await repository.GetDatesChange(idWell, token); return Ok(result); } /// /// Редактирование /// /// /// /// /// [HttpPut] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task UpdateRange([FromRoute] int idWell, IEnumerable dtos, CancellationToken token) { var first = dtos.FirstOrDefault(); if(first is null) return NoContent(); if (idWell == 0 || dtos.Any(d => d.IdWell != idWell)) return this.ValidationBadRequest(nameof(dtos), "all dtos should contain same idWell"); var idUser = await AssertUserHasAccessToWell(idWell, token); var result = await repository.UpdateRange(idUser, dtos, token); return Ok(result); } /// /// returns user id, if he has access to well /// /// /// /// /// private async Task AssertUserHasAccessToWell(int idWell, CancellationToken token) { var idUser = GetUserId(); var idCompany = User.GetCompanyId(); if (!idCompany.HasValue) throw new ForbidException("Нет доступа к скважине"); if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token)) throw new ForbidException("Нет доступа к скважине"); return idUser; } /// /// returns user id or throw /// /// /// private int GetUserId() { var idUser = User.GetUserId() ?? throw new ForbidException("Неизвестный пользователь"); return idUser; } }