DD.WellWorkover.Cloud/AsbCloudWebApi/Controllers/WellOperationController.cs

379 lines
15 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;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Requests.ExportOptions;
using AsbCloudApp.Requests.ParserOptions;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.WellOperations.Factories;
using System.Linq;
namespace AsbCloudWebApi.Controllers;
/// <summary>
/// Буровые операции (вводимые вручную)
/// </summary>
[Route("api/well/{idWell}/wellOperations")]
[ApiController]
[Authorize]
public class WellOperationController : ControllerBase
{
private readonly IDictionary<int, string> templateNames = new Dictionary<int, string>
{
{ WellOperation.IdOperationTypeFact, "ЕЦП_шаблон_файлаактические_операции.xlsx" },
{ WellOperation.IdOperationTypePlan, "ЕЦП_шаблон_файла_плановые_операции.xlsx" }
};
private readonly IUserRepository userRepository;
private readonly IWellOperationRepository wellOperationRepository;
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
private readonly IWellService wellService;
private readonly WellOperationParserFactory wellOperationParserFactory;
private readonly WellOperationExportServiceFactory wellOperationExportServiceFactory;
public WellOperationController(IWellOperationRepository wellOperationRepository,
IWellOperationCategoryRepository wellOperationCategoryRepository,
IWellService wellService,
IUserRepository userRepository,
WellOperationParserFactory wellOperationParserFactory,
WellOperationExportServiceFactory wellOperationExportServiceFactory)
{
this.wellOperationRepository = wellOperationRepository;
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
this.wellService = wellService;
this.userRepository = userRepository;
this.wellOperationParserFactory = wellOperationParserFactory;
this.wellOperationExportServiceFactory = wellOperationExportServiceFactory;
}
/// <summary>
/// Добавляет новые операции на скважине
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="dtos">Добавляемые операции</param>
/// <param name="deleteBeforeInsert">Удалить операции перед сохранением</param>
/// <param name="cancellationToken"></param>
/// <returns>Количество добавленных в БД записей</returns>
[HttpPost("{deleteBeforeInsert:bool}")]
[Permission]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> InsertRangeAsync(
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")]
int idWell,
bool deleteBeforeInsert,
[FromBody] IEnumerable<WellOperationDto> dtos,
CancellationToken cancellationToken)
{
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
return Forbid();
foreach (var dto in dtos)
{
dto.IdWell = idWell;
dto.LastUpdateDate = null;
dto.IdUser = User.GetUserId();
}
var result = await wellOperationRepository.InsertRangeAsync(dtos, deleteBeforeInsert, cancellationToken);
return Ok(result);
}
/// <summary>
/// Обновляет выбранную операцию на скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="dtos"></param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Количество обновленных в БД строк</returns>
[HttpPut]
[Permission]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
public async Task<IActionResult> UpdateRangeAsync(int idWell,
[FromBody] IEnumerable<WellOperationDto> dtos,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
foreach (var dto in dtos)
{
dto.IdWell = idWell;
dto.IdUser = User.GetUserId();
dto.LastUpdateDate = DateTimeOffset.UtcNow;
}
var result = await wellOperationRepository.UpdateRangeAsync(dtos, token);
return Ok(result);
}
/// <summary>
/// Возвращает словарь типов секций
/// </summary>
/// <returns></returns>
[HttpGet("sectionTypes")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellSectionTypeDto>), StatusCodes.Status200OK)]
public IActionResult GetSectionTypes()
{
var result = wellOperationRepository.GetSectionTypes();
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, new[] { idWell });
var result = await wellOperationRepository.GetGroupOperationsStatAsync(requestToservice, token);
return Ok(result);
}
/// <summary>
/// Возвращает список имен типов операций на скважине
/// </summary>
/// <param name="includeParents">флаг, нужно ли включать родителей в список</param>
/// <returns></returns>
[HttpGet("categories")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<WellOperationCategoryDto>), StatusCodes.Status200OK)]
public IActionResult GetCategories(bool includeParents = true)
{
var result = wellOperationCategoryRepository.Get(includeParents, false);
return Ok(result);
}
/// <summary>
/// Постраничный список операций на скважине.
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns>Список операций на скважине</returns>
[HttpGet]
[Permission]
[ProducesResponseType(typeof(PaginationContainer<WellOperationDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetPageOperationsAsync(
[FromRoute] int idWell,
[FromQuery] WellOperationRequestBase request,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
var requestToService = new WellOperationRequest(request, new[] { idWell });
var result = await wellOperationRepository.GetPageAsync(requestToService, token);
return Ok(result);
}
/// <summary>
/// Создает excel файл с "сетевым графиком"
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="scheduleReportService"></param>
/// <param name="token"></param>
/// <returns>Запрашиваемый файл</returns>
[HttpGet("scheduleReport")]
[Permission]
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)]
public async Task<IActionResult> ScheduleReportAsync([FromRoute] int idWell,
[FromServices] IScheduleReportService scheduleReportService,
CancellationToken token)
{
var idCompany = User.GetCompanyId();
if (idCompany is null)
return Forbid();
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token))
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>
/// <param name="idWell">id скважины</param>
/// <param name="idOperation">id выбранной операции</param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Количество удаленных из БД строк</returns>
[HttpDelete("{idOperation}")]
[Permission]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
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 wellOperationRepository.DeleteRangeAsync(new[] { idOperation }, token);
return Ok(result);
}
/// <summary>
/// Удаляет выбранные операции по скважине
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="ids">ids выбранных операций</param>
/// <param name="token">Токен отмены задачи</param>
/// <returns>Количество удаленных из БД строк</returns>
[HttpDelete]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> DeleteRangeAsync([FromRoute] int idWell, IEnumerable<int> ids, CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
if (!ids.Any())
return this.ValidationBadRequest(nameof(ids), "Пустой список операций");
var result = await wellOperationRepository.DeleteRangeAsync(ids, token);
if(result == ICrudRepository<WellOperationDto>.ErrorIdNotFound)
return this.ValidationBadRequest(nameof(ids), "Минимум одна из операций не найдена в базе");
return Ok(result);
}
/// <summary>
/// Формирование excel файла с операциями на скважине
/// </summary>
/// <param name="idWell"></param>
/// <param name="idType"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("export")]
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
public async Task<IActionResult> ExportAsync(int idWell,
int idType,
CancellationToken token)
{
var options = new WellOperationExportRequest(idWell, idType);
var exportService = wellOperationExportServiceFactory.CreateExportService<WellOperationExportRequest>(idType);
var (fileName, file) = await exportService.ExportAsync(options, token);
return File(file, "application/octet-stream", fileName);
}
/// <summary>
/// Парсинг ГГД из excel (xlsx) файла
/// </summary>
/// <param name="idWell"></param>
/// <param name="idType"></param>
/// <param name="file"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPost("parse/{idType}")]
[Permission]
[ProducesResponseType(typeof(ParserResultDto<WellOperationDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> ParseAsync(int idWell,
int idType,
[Required] IFormFile file,
CancellationToken token)
{
if (!await CanUserAccessToWellAsync(idWell, token))
return Forbid();
if (!await CanUserEditWellOperationsAsync(idWell, token))
return Forbid();
var stream = file.GetExcelFile();
try
{
var timezone = wellService.GetTimezone(idWell);
var options = new WellOperationParserRequest(idWell, idType, timezone);
var parser = wellOperationParserFactory.CreateParser<WellOperationParserRequest>(idType);
var result = parser.Parse(stream, options);
return Ok(result);
}
catch (FileFormatException ex)
{
return this.ValidationBadRequest(nameof(file), ex.Message);
}
}
/// <summary>
/// Получение шаблона для заполнения ГГД
/// </summary>
/// <returns></returns>
[HttpGet("template")]
[AllowAnonymous]
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
public IActionResult GetTemplate(int idType)
{
var parser = wellOperationParserFactory.CreateParser<WellOperationParserRequest>(idType);
var stream = parser.GetTemplateFile();
return File(stream, "application/octet-stream", templateNames[idType]);
}
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
{
var idCompany = User.GetCompanyId();
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, token).ConfigureAwait(false);
}
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");
}
}