DD.WellWorkover.Cloud/AsbCloudWebApi/Controllers/WellOperationController.cs
Степанов Дмитрий e451c0662c Правки после ревью
1. Поправил инициализацию ролей и прав
2. Поправил проверки в контроллере на редактирование РТК и ГГД
3. Пересоздал миграцию
2023-09-13 11:42:44 +05:00

421 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers
{
/// <summary>
/// Буровые операции (вводимые вручную)
/// </summary>
[Route("api/well/{idWell}/wellOperations")]
[ApiController]
[Authorize]
public class WellOperationController : ControllerBase
{
private readonly IWellOperationRepository operationRepository;
private readonly IWellService wellService;
private readonly IWellOperationImportService wellOperationImportService;
private readonly IUserRepository userRepository;
public WellOperationController(IWellOperationRepository operationService, IWellService wellService,
IWellOperationImportService wellOperationImportService,
IUserRepository userRepository)
{
this.operationRepository = operationService;
this.wellService = wellService;
this.wellOperationImportService = wellOperationImportService;
this.userRepository = userRepository;
}
/// <summary>
/// Возвращает словарь типов секций
/// </summary>
/// <returns></returns>
[HttpGet("sectionTypes")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellSectionTypeDto>), (int)System.Net.HttpStatusCode.OK)]
public IActionResult GetSectionTypes()
{
var result = operationRepository.GetSectionTypes();
return Ok(result);
}
/// <summary>
/// Возвращает список имен типов операций на скважине
/// </summary>
/// <param name="includeParents">флаг, нужно ли включать родителей в список</param>
/// <returns></returns>
[HttpGet("categories")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellOperationCategoryDto>), (int)System.Net.HttpStatusCode.OK)]
public IActionResult GetCategories(bool includeParents = true)
{
var result = operationRepository.GetCategories(includeParents);
return Ok(result);
}
/// <summary>
/// Возвращает список плановых операций для сопоставления
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="currentDate">дата для нахождения последней сопоставленной плановой операции</param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("operationsPlan")]
[ProducesResponseType(typeof(WellOperationPlanDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetOperationsPlanAsync(
[FromRoute] int idWell,
[FromQuery] DateTime currentDate,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid();
var result = await operationRepository
.GetOperationsPlanAsync(idWell, currentDate, token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Отфильтрованный список фактических операций на скважине.
/// Если не применять фильтр, то вернется весь список. Сортированный по глубине затем по дате
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns>Список операций на скважине</returns>
[HttpGet("fact")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetPageOperationsFactAsync(
[FromRoute] int idWell,
[FromQuery] WellOperationRequestBase request,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid();
var requestToService = new WellOperationRequest(request, idWell);
var result = await operationRepository.GetAsync(
requestToService,
token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Отфильтрованный список плановых операций на скважине.
/// Если не применять фильтр, то вернется весь список. Сортированный по глубине затем по дате
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns>Список операций на скважине в контейнере для постраничного просмотра</returns>
[HttpGet("plan")]
[Permission]
[ProducesResponseType(typeof(PaginationContainer<WellOperationDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetPageOperationsPlanAsync(
[FromRoute] int idWell,
[FromQuery] WellOperationRequestBase request,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid();
var requestToService = new WellOperationRequest(request, idWell);
var result = await operationRepository.GetPageAsync(
requestToService,
token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Статистика операций по скважине, группированая по категориям
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("groupStat")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellGroupOpertionDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetGroupOperationsAsync(
[FromRoute] int idWell,
[FromQuery] WellOperationRequestBase request,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid();
var requestToService = new WellOperationRequest(request, idWell);
var result = await operationRepository.GetGroupOperationsStatAsync(
requestToService,
token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Возвращает нужную операцию на скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="idOperation">id нужной операции</param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Нужную операцию на скважине</returns>
[HttpGet("{idOperation}")]
[Permission]
[ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetOrDefaultAsync(int idWell, int idOperation,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid();
var result = await operationRepository.GetOrDefaultAsync(idOperation, token).ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Добавляет новые операции на скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="values">Данные о добавляемых операциях</param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Количество добавленных в БД строк</returns>
[HttpPost]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> InsertRangeAsync(
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")] int idWell,
[FromBody] IEnumerable<WellOperationDto> values,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
foreach (var value in values)
{
value.IdWell = idWell;
value.LastUpdateDate = DateTimeOffset.UtcNow;
value.IdUser = User.GetUserId();
}
var result = await operationRepository.InsertRangeAsync(values, token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Обновляет выбранную операцию на скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="idOperation">id выбранной операции</param>
/// <param name="value">Новые данные для выбранной операции</param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Количество обновленных в БД строк</returns>
[HttpPut("{idOperation}")]
[Permission]
[ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> UpdateAsync(int idWell, int idOperation,
[FromBody] WellOperationDto value, CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
value.IdWell = idWell;
value.Id = idOperation;
value.LastUpdateDate = DateTimeOffset.UtcNow;
value.IdUser = User.GetUserId();
var result = await operationRepository.UpdateAsync(value, token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Удаляет выбранную операцию на скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="idOperation">id выбранной операции</param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Количество удаленных из БД строк</returns>
[HttpDelete("{idOperation}")]
[Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> DeleteAsync(int idWell, int idOperation, CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
var result = await operationRepository.DeleteAsync(new int[] { idOperation }, token)
.ConfigureAwait(false);
return Ok(result);
}
/// <summary>
/// Импортирует операции из excel (xlsx) файла
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="files">Коллекция из одного файла xlsx</param>
/// <param name="options">Удалить операции перед импортом = 1, если фал валидный</param>
/// <param name="token"> Токен отмены задачи </param>
/// <returns></returns>
[HttpPost("import/{options}")]
[Permission]
public async Task<IActionResult> ImportAsync(int idWell,
[FromForm] IFormFileCollection files,
int options,
CancellationToken token)
{
int? idCompany = User.GetCompanyId();
int? idUser = User.GetUserId();
if (idCompany is null || idUser is null)
return Forbid();
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false))
return Forbid();
if (files.Count < 1)
return BadRequest("нет файла");
var file = files[0];
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
return BadRequest("Требуется xlsx файл.");
using Stream stream = file.OpenReadStream();
try
{
wellOperationImportService.Import(idWell, stream, idUser.Value, (options & 1) > 0);
}
catch (FileFormatException ex)
{
return BadRequest(ex.Message);
}
return Ok();
}
/// <summary>
/// Создает excel файл с операциями по скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="token">Токен отмены задачи </param>
/// <returns>Запрашиваемый файл</returns>
[HttpGet("export")]
[Permission]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> ExportAsync([FromRoute] int idWell, CancellationToken token)
{
int? idCompany = User.GetCompanyId();
if (idCompany is null)
return Forbid();
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false))
return Forbid();
var stream = wellOperationImportService.Export(idWell);
var fileName = await wellService.GetWellCaptionByIdAsync(idWell, token) + "_operations.xlsx";
return File(stream, "application/octet-stream", fileName);
}
/// <summary>
/// Создает excel файл с "сетевым графиком"
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="scheduleReportService"></param>
/// <param name="token"> Токен отмены задачи</param>
/// <returns>Запрашиваемый файл</returns>
[HttpGet("scheduleReport")]
[Permission]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> ScheduleReportAsync([FromRoute] int idWell, [FromServices] IScheduleReportService scheduleReportService, CancellationToken token)
{
int? idCompany = User.GetCompanyId();
if (idCompany is null)
return Forbid();
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false))
return Forbid();
var stream = await scheduleReportService.MakeReportAsync(idWell, token);
var fileName = await wellService.GetWellCaptionByIdAsync(idWell, token) + "_ScheduleReport.xlsx";
return File(stream, "application/octet-stream", fileName);
}
/// <summary>
/// Возвращает шаблон файла импорта
/// </summary>
/// <returns>Запрашиваемый файл</returns>
[HttpGet("template")]
[AllowAnonymous]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
public IActionResult GetTemplate()
{
var stream = wellOperationImportService.GetExcelTemplateStream();
var fileName = "ЕЦП_шаблон_файла_операций.xlsx";
return File(stream, "application/octet-stream", fileName);
}
private async Task<bool> CanUserEditWellOperationsAsync(int idWell, CancellationToken token)
{
var idUser = User.GetUserId();
if (!idUser.HasValue)
return false;
var well = await wellService.GetOrDefaultAsync(idWell, token);
if (well is null)
return false;
return well.IdState != 2 || userRepository.HasPermission(idUser.Value, "WellOperation.editCompletedWell");
}
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
{
int? idCompany = User.GetCompanyId();
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false);
}
}
}