forked from ddrilling/AsbCloudServer
Новая реализация экпорта/импорта ГГД
1. Изменено апи 2. Добавлен парсер для ГГД 3. Добавлен ссервис экспорта ГГД
This commit is contained in:
parent
39a1c874c0
commit
16645d053a
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AsbCloudApp.Data;
|
||||
|
||||
@ -9,4 +10,8 @@ namespace AsbCloudApp.Data;
|
||||
public class ParserResultDto<TDto> : ValidationResultDto<IEnumerable<ValidationResultDto<TDto>>>
|
||||
where TDto : class, IId
|
||||
{
|
||||
/// <summary>
|
||||
/// Объекты полученные из файла
|
||||
/// </summary>
|
||||
public override IEnumerable<ValidationResultDto<TDto>> Item { get; set; } = Enumerable.Empty<ValidationResultDto<TDto>>();
|
||||
}
|
@ -18,7 +18,7 @@ public class ValidationResultDto<T>
|
||||
/// <summary>
|
||||
/// Объект валидации
|
||||
/// </summary>
|
||||
public T Item { get; set; } = null!;
|
||||
public virtual T Item { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Предупреждения
|
||||
|
@ -0,0 +1,20 @@
|
||||
namespace AsbCloudApp.Requests.ExportOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Параметры экспорта ГГД
|
||||
/// </summary>
|
||||
public class WellOperationExportRequest : WellRelatedExportRequest
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public WellOperationExportRequest(int idWell,
|
||||
int idType)
|
||||
: base(idWell)
|
||||
{
|
||||
IdType = idType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Тип операций
|
||||
/// </summary>
|
||||
public int IdType { get; }
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using AsbCloudApp.Data;
|
||||
|
||||
namespace AsbCloudApp.Requests.ParserOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Параметры парсинга ГГД
|
||||
/// </summary>
|
||||
public class WellOperationParserRequest : WellRelatedParserRequest
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public WellOperationParserRequest(int idWell,
|
||||
int idType,
|
||||
SimpleTimezoneDto wellTimezone)
|
||||
: base(idWell)
|
||||
{
|
||||
IdType = idType;
|
||||
WellTimezone = wellTimezone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Тип операции
|
||||
/// </summary>
|
||||
public int IdType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Часовой пояс в котором находится скважина
|
||||
/// </summary>
|
||||
public SimpleTimezoneDto WellTimezone { get; }
|
||||
}
|
@ -45,11 +45,9 @@
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
|
||||
<EmbeddedResource Include="Services\ProcessMaps\Report\ProcessMapReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperations\Templates\WellOperationFactTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperations\Templates\WellOperationPlanTemplate.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -77,4 +75,10 @@
|
||||
<HintPath>CommonLibs\AsbWitsInfo.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Services\ProcessMapPlan\Parser\ProcessMapPlanExcelReamParser.cs" />
|
||||
<Compile Remove="Services\ProcessMapPlan\Parser\ProcessMapPlanExcelParser.cs" />
|
||||
<Compile Remove="Services\ProcessMapPlan\Parser\ProcessMapPlanExcelDrillingParser.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -14,7 +14,6 @@ using AsbCloudApp.Services.DailyReport;
|
||||
using AsbCloudApp.Services.Notifications;
|
||||
using AsbCloudApp.Services.ProcessMaps;
|
||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
@ -36,8 +35,6 @@ using AsbCloudInfrastructure.Services.Subsystems;
|
||||
using AsbCloudInfrastructure.Services.Trajectory;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||
using AsbCloudInfrastructure.Services.WellOperationService;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -46,6 +43,7 @@ using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using AsbCloudInfrastructure.Services.ProcessMapPlan.Export;
|
||||
using AsbCloudInfrastructure.Services.WellOperations.Factories;
|
||||
|
||||
namespace AsbCloudInfrastructure
|
||||
{
|
||||
@ -160,7 +158,6 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||
services.AddTransient<ITimezoneService, TimezoneService>();
|
||||
services.AddScoped<IWellService, WellService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IProcessMapReportDrillingExportService, ProcessMapReportDataSaubStatExportService>();
|
||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
@ -270,13 +267,6 @@ namespace AsbCloudInfrastructure
|
||||
|
||||
services.AddTransient<IWellboreService, WellboreService>();
|
||||
|
||||
services.AddTransient<IWellOperationExportService, WellOperationExportService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IWellOperationImportTemplateService, WellOperationImportTemplateService>();
|
||||
|
||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
|
||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
|
||||
|
||||
services.AddTransient<DetectedOperationExportService>();
|
||||
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
@ -301,6 +291,9 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<ProcessMapPlanDrillingExportService>();
|
||||
services.AddTransient<ProcessMapPlanReamExportService>();
|
||||
|
||||
services.AddTransient<WellOperationParserFactory>();
|
||||
services.AddTransient<WellOperationExportServiceFactory>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ExcelServices.Templates.WellOperations;
|
||||
|
||||
public class WellOperationPlanTemplate : ITemplateParameters
|
||||
{
|
||||
public string SheetName => "План";
|
||||
|
||||
public int HeaderRowsCount => 1;
|
||||
|
||||
public string FileName => "WellOperationPlanTemplate.xlsx";
|
||||
|
||||
public IDictionary<string, Cell> Cells => new Dictionary<string, Cell>()
|
||||
{
|
||||
{ nameof(WellOperationDto.WellSectionTypeCaption), new Cell(1, typeof(string)) },
|
||||
{ nameof(WellOperationDto.OperationCategoryName), new Cell(2, typeof(string)) },
|
||||
{ nameof(WellOperationDto.CategoryInfo), new Cell(3, typeof(string)) },
|
||||
{ nameof(WellOperationDto.DepthStart), new Cell(4, typeof(double)) },
|
||||
{ nameof(WellOperationDto.DepthEnd), new Cell(5, typeof(double)) },
|
||||
{ nameof(WellOperationDto.DateStart), new Cell(6, typeof(DateTime)) },
|
||||
{ nameof(WellOperationDto.DurationHours), new Cell(7, typeof(double)) },
|
||||
{ nameof(WellOperationDto.Comment), new Cell(8, typeof(string)) }
|
||||
};
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests.ExportOptions;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.Export;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.ExcelServices.Templates.WellOperations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.WellOperations.Factories;
|
||||
|
||||
public class WellOperationExportServiceFactory : IExportServiceFactory<int>
|
||||
{
|
||||
private readonly IDictionary<int, Func<IExportService>> exportServices;
|
||||
|
||||
public WellOperationExportServiceFactory(IServiceProvider serviceProvider)
|
||||
{
|
||||
var wellOperationRepository = serviceProvider.GetRequiredService<IWellOperationRepository>();
|
||||
var wellService = serviceProvider.GetRequiredService<IWellService>();
|
||||
|
||||
exportServices = new Dictionary<int, Func<IExportService>>
|
||||
{
|
||||
{
|
||||
WellOperation.IdOperationTypeFact,
|
||||
() => new WellOperationExport<WellOperationFactTemplate>(wellOperationRepository, wellService)
|
||||
},
|
||||
{
|
||||
WellOperation.IdOperationTypePlan,
|
||||
() => new WellOperationExport<WellOperationPlanTemplate>(wellOperationRepository, wellService)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IExportService<TOptions> CreateExportService<TOptions>(int id)
|
||||
where TOptions : IExportOptionsRequest
|
||||
{
|
||||
var parser = exportServices[id].Invoke();
|
||||
|
||||
return parser as IExportService<TOptions>
|
||||
?? throw new ArgumentNullException(nameof(id), "Не удалось экспортировать файл");
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests.ParserOptions;
|
||||
using AsbCloudApp.Services.Parsers;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.ExcelServices.Templates.WellOperations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.WellOperations.Factories;
|
||||
|
||||
public class WellOperationParserFactory : IParserFactory<int, WellOperationDto>
|
||||
{
|
||||
private readonly IDictionary<int, Func<IParserService>> parsers;
|
||||
|
||||
public WellOperationParserFactory(IServiceProvider serviceProvider)
|
||||
{
|
||||
var wellOperationRepository = serviceProvider.GetRequiredService<IWellOperationRepository>();
|
||||
var categoryRepository = serviceProvider.GetRequiredService<IWellOperationCategoryRepository>();
|
||||
|
||||
parsers = new Dictionary<int, Func<IParserService>>
|
||||
{
|
||||
{
|
||||
WellOperation.IdOperationTypeFact,
|
||||
() => new WellOperationParser<WellOperationFactTemplate>(wellOperationRepository, categoryRepository)
|
||||
},
|
||||
{
|
||||
WellOperation.IdOperationTypePlan,
|
||||
() => new WellOperationParser<WellOperationPlanTemplate>(wellOperationRepository, categoryRepository)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IParserService<WellOperationDto, TOptions> CreateParser<TOptions>(int id)
|
||||
where TOptions : IParserOptionsRequest
|
||||
{
|
||||
var parser = parsers[id].Invoke();
|
||||
|
||||
return parser as IParserService<WellOperationDto, TOptions>
|
||||
?? throw new ArgumentNullException(nameof(id), "Не удалось распознать файл");
|
||||
}
|
||||
}
|
Binary file not shown.
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Requests.ExportOptions;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.ExcelServices;
|
||||
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.WellOperations;
|
||||
|
||||
public class WellOperationExport<TTemplate> : ExcelExportService<WellOperationDto, WellOperationExportRequest, TTemplate>
|
||||
where TTemplate : class, ITemplateParameters, new()
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
|
||||
public WellOperationExport(IWellOperationRepository wellOperationRepository,
|
||||
IWellService wellService)
|
||||
{
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
this.wellService = wellService;
|
||||
}
|
||||
|
||||
protected override async Task<string> BuildFileNameAsync(WellOperationExportRequest options, CancellationToken token)
|
||||
{
|
||||
var caption = await wellService.GetWellCaptionByIdAsync(options.IdWell, token);
|
||||
|
||||
return options.IdType switch
|
||||
{
|
||||
WellOperation.IdOperationTypeFact => $"{caption}_Фактические_операции.xlsx",
|
||||
WellOperation.IdOperationTypePlan => $"{caption}_Плановые_операции.xlsx",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(options.IdType))
|
||||
};
|
||||
}
|
||||
|
||||
protected override Task<IEnumerable<WellOperationDto>> GetDtosAsync(WellOperationExportRequest options, CancellationToken token)
|
||||
{
|
||||
var request = new WellOperationRequest
|
||||
{
|
||||
IdsWell = new[] { options.IdWell },
|
||||
OperationType = options.IdType
|
||||
};
|
||||
|
||||
return wellOperationRepository.GetAsync(request, token);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests.ParserOptions;
|
||||
using AsbCloudInfrastructure.Services.ExcelServices;
|
||||
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.WellOperations;
|
||||
|
||||
public class WellOperationParser<TTemplateParameters> : ExcelWellRelatedParser<WellOperationDto, WellOperationParserRequest, TTemplateParameters>
|
||||
where TTemplateParameters : class, ITemplateParameters, new()
|
||||
{
|
||||
private readonly IEnumerable<WellSectionTypeDto> sectionTypes;
|
||||
private readonly IEnumerable<WellOperationCategoryDto> categories;
|
||||
|
||||
public WellOperationParser(IWellOperationRepository wellOperationRepository,
|
||||
IWellOperationCategoryRepository categoryRepository)
|
||||
{
|
||||
categories = categoryRepository.Get(false);
|
||||
sectionTypes = wellOperationRepository.GetSectionTypes();
|
||||
}
|
||||
|
||||
public override ParserResultDto<WellOperationDto> Parse(Stream file, WellOperationParserRequest options)
|
||||
{
|
||||
var result = base.Parse(file, options);
|
||||
|
||||
foreach (var dto in result.Item)
|
||||
{
|
||||
dto.Item.IdWell = options.IdWell;
|
||||
dto.Item.IdType = options.IdType;
|
||||
dto.Item.DateStart = new DateTimeOffset(dto.Item.DateStart.DateTime, options.WellTimezone.Offset);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override WellOperationDto BuildDto(IDictionary<string, object?> row, int rowNumber)
|
||||
{
|
||||
var dto = base.BuildDto(row, rowNumber);
|
||||
|
||||
var sectionType = sectionTypes.FirstOrDefault(s =>
|
||||
string.Equals(s.Caption.Trim(), dto.WellSectionTypeCaption?.Trim(), StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
if (sectionType is null)
|
||||
{
|
||||
var message = string.Format(XLExtentions.ProblemDetailsTemplate,
|
||||
TemplateParameters.SheetName,
|
||||
rowNumber,
|
||||
TemplateParameters.Cells[nameof(WellOperationDto.WellSectionTypeCaption)],
|
||||
"Указана некорректная секция");
|
||||
throw new FileFormatException(message);
|
||||
}
|
||||
|
||||
var category = categories.FirstOrDefault(c =>
|
||||
string.Equals(c.Name.Trim(), dto.OperationCategoryName?.Trim(), StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
if (category is null)
|
||||
{
|
||||
var message = string.Format(XLExtentions.ProblemDetailsTemplate,
|
||||
TemplateParameters.SheetName,
|
||||
rowNumber,
|
||||
TemplateParameters.Cells[nameof(WellOperationDto.OperationCategoryName)],
|
||||
"Указана некорректная операция");
|
||||
throw new FileFormatException(message);
|
||||
}
|
||||
|
||||
dto.IdWellSectionType = sectionType.Id;
|
||||
dto.IdCategory = category.Id;
|
||||
dto.IdParentCategory = category.IdParent;
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Controllers\WellOperations\Files\PlanWellOperations.xlsx" />
|
||||
<EmbeddedResource Include="Controllers\WellOperations\Files\FactWellOperations.xlsx" />
|
||||
<EmbeddedResource Include="WellOperationsPlan.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Requests;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Refit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||
@ -8,20 +10,23 @@ public interface IWellOperationClient
|
||||
{
|
||||
private const string BaseRoute = "/api/well/{idWell}/wellOperations";
|
||||
|
||||
[Post(BaseRoute + "/{idType}/{deleteBeforeInsert}")]
|
||||
Task<IApiResponse<int>> InsertRangeAsync(int idWell, int idType, bool deleteBeforeInsert, [Body] IEnumerable<WellOperationDto> dtos);
|
||||
[Post(BaseRoute + "/{deleteBeforeInsert}")]
|
||||
Task<IApiResponse<int>> InsertRangeAsync(int idWell,
|
||||
bool deleteBeforeInsert,
|
||||
[Body] IEnumerable<WellOperationDto> dtos);
|
||||
|
||||
[Put(BaseRoute + "/{idOperation}")]
|
||||
Task<IApiResponse<int>> UpdateAsync(int idWell, int idOperation, [Body] WellOperationDto value, CancellationToken token);
|
||||
[Put(BaseRoute)]
|
||||
Task<IApiResponse<int>> UpdateRangeAsync(int idWell, [Body] IEnumerable<WellOperationDto> dtos);
|
||||
|
||||
[Get(BaseRoute + "/plan")]
|
||||
Task<IApiResponse<PaginationContainer<WellOperationDto>>> GetPageOperationsPlanAsync(int idWell,
|
||||
[Query] WellOperationRequestBase request,
|
||||
CancellationToken token);
|
||||
[Get(BaseRoute)]
|
||||
Task<IApiResponse<PaginationContainer<WellOperationDto>>> GetPageOperationsPlanAsync(int idWell, [Query] WellOperationRequest request);
|
||||
|
||||
[Multipart]
|
||||
[Post(BaseRoute + "/import/plan/default")]
|
||||
Task<IApiResponse<IEnumerable<WellOperationDto>>> ImportPlanDefaultExcelFileAsync(int idWell,
|
||||
[AliasAs("files")] IEnumerable<StreamPart> streams,
|
||||
CancellationToken token);
|
||||
[Post(BaseRoute + "/parse/{idType}")]
|
||||
Task<IApiResponse<ParserResultDto<WellOperationDto>>> ParseAsync(int idWell,
|
||||
int idType,
|
||||
[AliasAs("file")] StreamPart file);
|
||||
|
||||
[Get(BaseRoute + "/export")]
|
||||
Task<IApiResponse<PhysicalFileResult>> ExportAsync(int idWell, int idType);
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -1,16 +1,16 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using AsbCloudWebApi.IntegrationTests.Data;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Refit;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers.WellOperations;
|
||||
|
||||
public class WellOperationControllerTest : BaseIntegrationTest
|
||||
{
|
||||
@ -37,7 +37,7 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
||||
var dtos = new[] { entity.Adapt<WellOperationDto>() };
|
||||
|
||||
//act
|
||||
var response = await client.InsertRangeAsync(well.Id, 1, false, dtos);
|
||||
var response = await client.InsertRangeAsync(well.Id, false, dtos);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
@ -56,18 +56,18 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
||||
var dtos = new[] { entity.Adapt<WellOperationDto>() };
|
||||
|
||||
//act
|
||||
var response = await client.InsertRangeAsync(well.Id, 1, true, dtos);
|
||||
var response = await client.InsertRangeAsync(well.Id, true, dtos);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Успешное обновление операции
|
||||
/// Успешное обновление операций
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task UpdateAsync_returns_success()
|
||||
public async Task UpdateRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var well = await dbContext.Wells.FirstAsync();
|
||||
@ -75,10 +75,10 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
||||
dbContext.WellOperations.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var dto = entity.Adapt<WellOperationDto>();
|
||||
var dtos = new[] { entity.Adapt<WellOperationDto>() };
|
||||
|
||||
//act
|
||||
var response = await client.UpdateAsync(well.Id, entity.Id, dto, CancellationToken.None);
|
||||
var response = await client.UpdateRangeAsync(well.Id, dtos);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
@ -100,66 +100,101 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
||||
var dto = entity.Adapt<WellOperationDto>();
|
||||
var timezoneOffset = TimeSpan.FromHours(well.Timezone.Hours);
|
||||
dto.DateStart = dto.DateStart.ToOffset(timezoneOffset);
|
||||
dto.LastUpdateDate = dto.LastUpdateDate?.ToOffset(timezoneOffset);
|
||||
|
||||
var request = new WellOperationRequestBase
|
||||
var request = new WellOperationRequest
|
||||
{
|
||||
OperationType = WellOperation.IdOperationTypePlan
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await client.GetPageOperationsPlanAsync(well.Id, request, CancellationToken.None);
|
||||
var response = await client.GetPageOperationsPlanAsync(well.Id, request);
|
||||
|
||||
//assert
|
||||
Assert.Equal(response.StatusCode, HttpStatusCode.OK);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Single(response.Content.Items);
|
||||
|
||||
var actualDto = response.Content.Items.First();
|
||||
|
||||
var excludeProps = new[]
|
||||
{
|
||||
nameof(WellOperationDto.LastUpdateDate)
|
||||
};
|
||||
MatchHelper.Match(dto, actualDto, excludeProps);
|
||||
MatchHelper.Match(dto, actualDto);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ImportPlanDefaultExcelFileAsync_returns_success()
|
||||
[Theory]
|
||||
[InlineData(WellOperation.IdOperationTypePlan, "PlanWellOperations.xlsx")]
|
||||
[InlineData(WellOperation.IdOperationTypeFact, "FactWellOperations.xlsx")]
|
||||
public async Task ParseAsync_returns_success(int idType, string fileName)
|
||||
{
|
||||
//arrange
|
||||
var stream = Assembly.GetExecutingAssembly().GetFileCopyStream("WellOperationsPlan.xlsx");
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await stream.CopyToAsync(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
var well = await dbContext.Wells.FirstAsync();
|
||||
|
||||
//act
|
||||
var streamPart = new StreamPart(memoryStream, "WellOperations.xlsx", "application/octet-stream");
|
||||
var expectedDto = new WellOperationDto
|
||||
{
|
||||
IdWell = well.Id,
|
||||
IdWellSectionType = 2,
|
||||
IdCategory = WellOperationCategory.IdSlide,
|
||||
IdPlan = null,
|
||||
CategoryInfo = "Доп.инфо",
|
||||
IdType = idType,
|
||||
DepthStart = 10.0,
|
||||
DepthEnd = 20.0,
|
||||
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(well.Timezone.Hours)),
|
||||
DurationHours = 1.0,
|
||||
Comment = "123",
|
||||
};
|
||||
|
||||
var response = await client.ImportPlanDefaultExcelFileAsync(well.Id, new[] { streamPart }, CancellationToken.None);
|
||||
var stream = Assembly.GetExecutingAssembly().GetFileCopyStream(fileName);
|
||||
|
||||
var streamPart = new StreamPart(stream, fileName, "application/octet-stream");
|
||||
|
||||
//act
|
||||
var response = await client.ParseAsync(well.Id, idType, streamPart);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(4, response.Content.Count());
|
||||
Assert.True(response.Content.All(w => Math.Abs(w.DateStart.Offset.Hours - Defaults.Timezone.Hours) < 0.1));
|
||||
|
||||
var actualDto = response.Content.Item.First().Item;
|
||||
|
||||
MatchHelper.Match(expectedDto, actualDto);
|
||||
}
|
||||
|
||||
private static WellOperation CreateWellOperation(int idWell) =>
|
||||
[Theory]
|
||||
[InlineData(WellOperation.IdOperationTypePlan)]
|
||||
[InlineData(WellOperation.IdOperationTypeFact)]
|
||||
public async Task ExportAsync_returns_success(int idType)
|
||||
{
|
||||
//arrange
|
||||
var well = await dbContext.Wells.FirstAsync();
|
||||
|
||||
var entity = CreateWellOperation(well.Id, idType);
|
||||
dbContext.WellOperations.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
//act
|
||||
var response = await client.ExportAsync(well.Id, idType);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("application/octet-stream", response.ContentHeaders?.ContentType?.MediaType);
|
||||
Assert.True(response.ContentHeaders?.ContentLength > 0);
|
||||
}
|
||||
|
||||
private static WellOperation CreateWellOperation(int idWell, int idType = WellOperation.IdOperationTypePlan) =>
|
||||
new()
|
||||
{
|
||||
IdWell = idWell,
|
||||
IdWellSectionType = 2,
|
||||
LastUpdateDate = DateTimeOffset.UtcNow,
|
||||
IdCategory = 5000,
|
||||
IdCategory = WellOperationCategory.IdSlide,
|
||||
IdPlan = null,
|
||||
CategoryInfo = "1",
|
||||
IdType = 0,
|
||||
CategoryInfo = "Доп.инфо",
|
||||
LastUpdateDate = new DateTimeOffset(new DateTime(2023, 1, 10)).ToUniversalTime(),
|
||||
IdType = idType,
|
||||
DepthStart = 10.0,
|
||||
DepthEnd = 20.0,
|
||||
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(Defaults.Timezone.Hours)).ToUniversalTime(),
|
||||
DurationHours = 1.0,
|
||||
Comment = "1",
|
||||
IdUser = 1
|
||||
IdUser = 1,
|
||||
};
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||
using NSubstitute;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
||||
{
|
||||
public class WellOperationExportServiceTest
|
||||
{
|
||||
private const int idWell = 4;
|
||||
|
||||
private IWellService wellService;
|
||||
private IWellOperationRepository wellOperationRepository;
|
||||
private IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||
private IWellOperationImportTemplateService wellOperationImportTemplateService;
|
||||
private WellOperationExportService wellOperationExportService;
|
||||
private WellOperationImportService wellOperationImportService;
|
||||
private IWellOperationExcelParser<WellOperationImportDefaultOptionsDto> wellOperationDefaultExcelParser;
|
||||
|
||||
private readonly WellSectionTypeDto[] sectionTypes = new WellSectionTypeDto[2]
|
||||
{
|
||||
new WellSectionTypeDto()
|
||||
{
|
||||
Caption = "1",
|
||||
Id = 1,
|
||||
Order = 0
|
||||
},
|
||||
new WellSectionTypeDto()
|
||||
{
|
||||
Caption = "2",
|
||||
Id = 2,
|
||||
Order = 1
|
||||
}
|
||||
};
|
||||
|
||||
private readonly WellOperationCategoryDto[] categories = new WellOperationCategoryDto[2]
|
||||
{
|
||||
new WellOperationCategoryDto()
|
||||
{
|
||||
Id = 1,
|
||||
IdParent = 1,
|
||||
KeyValueName = "1",
|
||||
KeyValueUnits = "1",
|
||||
Name = "1"
|
||||
},
|
||||
new WellOperationCategoryDto()
|
||||
{
|
||||
Id = 2,
|
||||
IdParent = 2,
|
||||
KeyValueName = "2",
|
||||
KeyValueUnits = "2",
|
||||
Name = "2"
|
||||
}
|
||||
};
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public WellOperationExportServiceTest(ITestOutputHelper output)
|
||||
{
|
||||
wellService = Substitute.For<IWellService>();
|
||||
wellOperationRepository = Substitute.For<IWellOperationRepository>();
|
||||
wellOperationCategoryRepository = Substitute.For<IWellOperationCategoryRepository>();
|
||||
wellOperationImportTemplateService = new WellOperationImportTemplateService();
|
||||
wellOperationExportService = new WellOperationExportService(wellOperationRepository, wellOperationImportTemplateService, wellOperationCategoryRepository);
|
||||
|
||||
wellOperationImportService = new WellOperationImportService(wellService, wellOperationRepository, wellOperationCategoryRepository);
|
||||
wellOperationDefaultExcelParser = new WellOperationDefaultExcelParser();
|
||||
this.output = output;
|
||||
|
||||
wellService.GetTimezone(idWell).Returns(new SimpleTimezoneDto()
|
||||
{
|
||||
Hours = 5
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Check_Exported_WellOperations_With_Operations_In_Db()
|
||||
{
|
||||
var operations = getOperations();
|
||||
|
||||
var localOperations = operations.ToArray();
|
||||
|
||||
foreach (var operation in localOperations)
|
||||
operation.Id = 0;
|
||||
|
||||
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(localOperations);
|
||||
wellOperationRepository.GetSectionTypes().Returns(sectionTypes);
|
||||
wellOperationCategoryRepository.Get(false).Returns(categories);
|
||||
|
||||
var stream = await wellOperationExportService.ExportAsync(idWell, CancellationToken.None);
|
||||
|
||||
var options = new WellOperationImportDefaultOptionsDto
|
||||
{
|
||||
IdType = WellOperation.IdOperationTypePlan
|
||||
};
|
||||
var sheet = wellOperationDefaultExcelParser.Parse(stream, options);
|
||||
var result = wellOperationImportService.Import(idWell, 1, options.IdType, sheet);
|
||||
|
||||
var expected = JsonSerializer.Serialize(localOperations);
|
||||
var actual = JsonSerializer.Serialize(result);
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDataContainsNotDefaultProps()
|
||||
{
|
||||
var initOk = true;
|
||||
var operations = getOperations();
|
||||
for (int i = 0; i < operations.Length; i++)
|
||||
{
|
||||
var operation = operations[i];
|
||||
var propsWithDefault = GetPropsWithDefaultValue(operation,
|
||||
nameof(WellOperationDto.Id),
|
||||
nameof(WellOperationDto.IdType),
|
||||
nameof(WellOperationDto.IdPlan),
|
||||
nameof(WellOperationDto.IdParentCategory),
|
||||
nameof(WellOperationDto.Day),
|
||||
nameof(WellOperationDto.NptHours),
|
||||
nameof(WellOperationDto.UserName),
|
||||
nameof(WellOperationDto.LastUpdateDate)
|
||||
)
|
||||
.ToArray();
|
||||
|
||||
if (propsWithDefault.Any())
|
||||
{
|
||||
initOk = false;
|
||||
foreach (var propertyName in propsWithDefault)
|
||||
output.WriteLine($"{nameof(operations)}[{i}].{propertyName} is default");
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(initOk);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPropsWithDefaultValue<T>(T dto, params string[] excludeProps)
|
||||
{
|
||||
IEnumerable<PropertyInfo> props = typeof(T).GetProperties(
|
||||
BindingFlags.Public
|
||||
| BindingFlags.Instance);
|
||||
|
||||
props = props
|
||||
.Where(prop => prop.CanWrite)
|
||||
.Where(prop => !excludeProps.Contains(prop.Name));
|
||||
|
||||
foreach (var prop in props)
|
||||
{
|
||||
var value = prop.GetValue(dto);
|
||||
if (prop.PropertyType.IsDefaultValue(value))
|
||||
yield return prop.Name;
|
||||
}
|
||||
}
|
||||
|
||||
private WellOperationDto[] getOperations()
|
||||
{
|
||||
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
|
||||
DateTimeOffset GetDate(int days)
|
||||
{
|
||||
var date = DateTimeOffset.UtcNow.AddDays(days);
|
||||
return new DateTimeOffset(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, TimeSpan.FromHours(timezone.Hours));
|
||||
}
|
||||
|
||||
return new WellOperationDto[2] {
|
||||
new WellOperationDto() {
|
||||
Id = 5,
|
||||
IdWell = idWell,
|
||||
IdUser = 1,
|
||||
IdType = 0,
|
||||
IdWellSectionType = 1,
|
||||
WellSectionTypeName = "1",
|
||||
IdCategory = 1,
|
||||
CategoryName = "1",
|
||||
CategoryInfo = "CategoryInfo 1",
|
||||
DepthStart = 10,
|
||||
DepthEnd = 20,
|
||||
DateStart = GetDate(days: 0),
|
||||
DurationHours = 10,
|
||||
Comment = "Комментарий 1",
|
||||
},
|
||||
new WellOperationDto() {
|
||||
Id = 6,
|
||||
IdWell = idWell,
|
||||
IdUser = 1,
|
||||
IdType = 0,
|
||||
IdWellSectionType = 2,
|
||||
WellSectionTypeName = "2",
|
||||
IdCategory = 2,
|
||||
CategoryName = "2",
|
||||
CategoryInfo = "CategoryInfo 2",
|
||||
DepthStart = 20,
|
||||
DepthEnd = 30,
|
||||
DateStart = GetDate(days: 1),
|
||||
DurationHours = 20,
|
||||
Comment = "Комментарий 2",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,7 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperationImport;
|
||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -15,12 +9,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
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;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Буровые операции (вводимые вручную)
|
||||
@ -30,35 +27,102 @@ namespace AsbCloudWebApi.Controllers
|
||||
[Authorize]
|
||||
public class WellOperationController : ControllerBase
|
||||
{
|
||||
private readonly IWellOperationRepository operationRepository;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationExportService wellOperationExportService;
|
||||
private readonly IWellOperationImportTemplateService wellOperationImportTemplateService;
|
||||
private readonly IWellOperationImportService wellOperationImportService;
|
||||
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||
private readonly IWellOperationExcelParser<WellOperationImportDefaultOptionsDto> wellOperationDefaultExcelParser;
|
||||
private readonly IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto> wellOperationGazpromKhantosExcelParser;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
public WellOperationController(IWellOperationRepository operationRepository,
|
||||
IWellService wellService,
|
||||
IWellOperationImportTemplateService wellOperationImportTemplateService,
|
||||
IWellOperationExportService wellOperationExportService,
|
||||
IWellOperationImportService wellOperationImportService,
|
||||
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
||||
IWellOperationExcelParser<WellOperationImportDefaultOptionsDto> wellOperationDefaultExcelParser,
|
||||
IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto> wellOperationGazpromKhantosExcelParser,
|
||||
IUserRepository userRepository)
|
||||
private readonly IDictionary<int, string> templateNames = new Dictionary<int, string>
|
||||
{
|
||||
this.operationRepository = operationRepository;
|
||||
this.wellService = wellService;
|
||||
this.wellOperationImportTemplateService = wellOperationImportTemplateService;
|
||||
this.wellOperationExportService = wellOperationExportService;
|
||||
this.wellOperationImportService = wellOperationImportService;
|
||||
{ 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.wellOperationDefaultExcelParser = wellOperationDefaultExcelParser;
|
||||
this.wellOperationGazpromKhantosExcelParser = wellOperationGazpromKhantosExcelParser;
|
||||
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>
|
||||
@ -67,101 +131,10 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <returns></returns>
|
||||
[HttpGet("sectionTypes")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellSectionTypeDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellSectionTypeDto>), StatusCodes.Status200OK)]
|
||||
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 = wellOperationCategoryRepository.Get(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);
|
||||
var result = wellOperationRepository.GetSectionTypes();
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@ -177,149 +150,79 @@ namespace AsbCloudWebApi.Controllers
|
||||
[ProducesResponseType(typeof(IEnumerable<WellGroupOpertionDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetGroupOperationsAsync(
|
||||
[FromRoute] int idWell,
|
||||
[FromQuery] WellOperationRequestBase request,
|
||||
[FromQuery] WellOperationRequest 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);
|
||||
request.IdsWell = new[] { idWell };
|
||||
var result = await wellOperationRepository.GetGroupOperationsStatAsync(request, 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);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Постраничный список операций на скважине.
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="idOperation">id нужной операции</param>
|
||||
/// <param name="token">Токен отмены задачи</param>
|
||||
/// <returns>Нужную операцию на скважине</returns>
|
||||
[HttpGet("{idOperation}")]
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Список операций на скважине</returns>
|
||||
[HttpGet]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetOrDefaultAsync(int idWell, int idOperation,
|
||||
[ProducesResponseType(typeof(PaginationContainer<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetPageOperationsAsync(
|
||||
[FromRoute] int idWell,
|
||||
[FromQuery] WellOperationRequest request,
|
||||
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="idType">Тип добавляемой операции</param>
|
||||
/// <param name="wellOperation">Добавляемая операция</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>Количество добавленных в БД записей</returns>
|
||||
[HttpPost("{idType:int}")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> InsertAsync(
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")] int idWell,
|
||||
[Range(0, 1, ErrorMessage = "Тип операции недопустим. Допустимые: 0, 1")] int idType,
|
||||
WellOperationDto wellOperation,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
wellOperation.IdWell = idWell;
|
||||
wellOperation.IdUser = User.GetUserId();
|
||||
wellOperation.IdType = idType;
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет новые операции на скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="wellOperations">Добавляемые операции</param>
|
||||
/// <param name="idType">Тип добавляемых операций</param>
|
||||
/// <param name="deleteBeforeInsert">Удалить операции перед сохранением</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>Количество добавленных в БД записей</returns>
|
||||
[HttpPost("{idType:int}/{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,
|
||||
[Range(0, 1, ErrorMessage = "Тип операции недопустим. Допустимые: 0, 1")] int idType,
|
||||
bool deleteBeforeInsert,
|
||||
[FromBody] IEnumerable<WellOperationDto> wellOperations,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (deleteBeforeInsert)
|
||||
{
|
||||
var existingOperations = await operationRepository.GetAsync(new WellOperationRequest
|
||||
{
|
||||
IdWell = idWell,
|
||||
OperationType = idType
|
||||
}, cancellationToken);
|
||||
|
||||
await operationRepository.DeleteAsync(existingOperations.Select(o => o.Id), cancellationToken);
|
||||
}
|
||||
|
||||
foreach (var wellOperation in wellOperations)
|
||||
{
|
||||
wellOperation.IdWell = idWell;
|
||||
wellOperation.IdUser = User.GetUserId();
|
||||
wellOperation.IdType = idType;
|
||||
}
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
||||
|
||||
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))
|
||||
request.IdsWell = new[] { idWell };
|
||||
var result = await wellOperationRepository.GetPageAsync(request, 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();
|
||||
|
||||
value.IdWell = idWell;
|
||||
value.Id = idOperation;
|
||||
value.IdUser = User.GetUserId();
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token))
|
||||
return Forbid();
|
||||
|
||||
var result = await operationRepository.UpdateAsync(value, token)
|
||||
.ConfigureAwait(false);
|
||||
return Ok(result);
|
||||
var stream = await scheduleReportService.MakeReportAsync(idWell, token);
|
||||
var fileName = await wellService.GetWellCaptionByIdAsync(idWell, token) + "_ScheduleReport.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -331,7 +234,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <returns>Количество удаленных из БД строк</returns>
|
||||
[HttpDelete("{idOperation}")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> DeleteAsync(int idWell, int idOperation, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
@ -340,256 +243,90 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
var result = await operationRepository.DeleteAsync(new int[] { idOperation }, token)
|
||||
.ConfigureAwait(false);
|
||||
var result = await wellOperationRepository.DeleteRangeAsync(new[] { idOperation }, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Импорт фактических операций из excel (xlsx) файла. Стандартный заполненный шаблон
|
||||
/// Формирование excel файла с операциями на скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="files">Коллекция из одного файла xlsx</param>
|
||||
/// <param name="deleteBeforeInsert">Удалить операции перед сохранением</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idType"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("import/fact/default/{deleteBeforeInsert:bool}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[Permission]
|
||||
public Task<IActionResult> ImportFactDefaultExcelFileAsync(int idWell,
|
||||
[FromForm] IFormFileCollection files,
|
||||
bool deleteBeforeInsert,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var options = new WellOperationImportDefaultOptionsDto
|
||||
{
|
||||
IdType = WellOperation.IdOperationTypeFact
|
||||
};
|
||||
|
||||
return ImportExcelFileAsync(idWell, files, options,
|
||||
(stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
|
||||
deleteBeforeInsert,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Импорт плановых операций из excel (xlsx) файла. Стандартный заполненный шаблон
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="files">Коллекция из одного файла xlsx</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("import/plan/default")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[Permission]
|
||||
public Task<IActionResult> ImportPlanDefaultExcelFileAsync(int idWell,
|
||||
[FromForm] IFormFileCollection files,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var options = new WellOperationImportDefaultOptionsDto
|
||||
{
|
||||
IdType = WellOperation.IdOperationTypePlan
|
||||
};
|
||||
|
||||
return ImportExcelFileAsync(idWell, files, options,
|
||||
(stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
|
||||
null,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Импорт операций из excel (xlsx) файла. ГПНХ (Хантос)
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="options">Параметры парсинга</param>
|
||||
/// <param name="files">Коллекция из одного файла xlsx</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("import/plan/gazpromKhantos")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[Permission]
|
||||
public Task<IActionResult> ImportPlanGazpromKhantosExcelFileAsync(int idWell,
|
||||
[FromQuery] WellOperationImportGazpromKhantosOptionsDto options,
|
||||
[FromForm] IFormFileCollection files,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
options.IdType = WellOperation.IdOperationTypePlan;
|
||||
|
||||
return ImportExcelFileAsync(idWell, files, options,
|
||||
(stream, _) => wellOperationGazpromKhantosExcelParser.Parse(stream, options),
|
||||
null,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
|
||||
public async Task<IActionResult> ExportAsync(int idWell,
|
||||
int idType,
|
||||
CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
var options = new WellOperationExportRequest(idWell, idType);
|
||||
var exportService = wellOperationExportServiceFactory.CreateExportService<WellOperationExportRequest>(idType);
|
||||
|
||||
if (idCompany is null)
|
||||
return Forbid();
|
||||
var (fileName, file) = await exportService.ExportAsync(options, token);
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var stream = await wellOperationExportService.ExportAsync(idWell, token);
|
||||
var fileName = await wellService.GetWellCaptionByIdAsync(idWell, token) + "_operations.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
return File(file, "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>
|
||||
/// Удаляет полые дубликаты операций
|
||||
/// Импорт ГГД из excel (xlsx) файла
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idType"></param>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("/api/well/wellOperations/RemoveDuplicates")]
|
||||
[HttpPost("parse/{idType}")]
|
||||
[Permission]
|
||||
[Obsolete]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> RemoveDuplicates(CancellationToken token)
|
||||
[ProducesResponseType(typeof(ParserResultDto<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> ParseAsync(int idWell,
|
||||
int idType,
|
||||
[Required] IFormFile file,
|
||||
CancellationToken token)
|
||||
{
|
||||
var result = await operationRepository.RemoveDuplicates((_, _) => { }, token);
|
||||
return Ok(result);
|
||||
}
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
/// <summary>
|
||||
/// Удаляет полностью пересекающиеся операции или "подрезает" более поздние их по глубине и дате.
|
||||
/// </summary>
|
||||
/// <param name="geDate"></param>
|
||||
/// <param name="leDate"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("/api/well/wellOperations/TrimOverlapping")]
|
||||
[Permission]
|
||||
[Obsolete]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, CancellationToken token)
|
||||
{
|
||||
var result = await operationRepository.TrimOverlapping(geDate, leDate, (_, _) => { }, token);
|
||||
return Ok(result);
|
||||
}
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает шаблон файла импорта
|
||||
/// </summary>
|
||||
/// <returns>Запрашиваемый файл</returns>
|
||||
[HttpGet("template")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
public IActionResult GetTemplate()
|
||||
{
|
||||
var stream = wellOperationImportTemplateService.GetExcelTemplateStream();
|
||||
var fileName = "ЕЦП_шаблон_файла_операций.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
//TODO: deleteBeforeInsert тоже быстрый костыль
|
||||
private async Task<IActionResult> ImportExcelFileAsync<TOptions>(int idWell, [FromForm] IFormFileCollection files,
|
||||
TOptions options,
|
||||
Func<Stream, TOptions, SheetDto> parseMethod,
|
||||
bool? deleteBeforeInsert,
|
||||
CancellationToken cancellationToken)
|
||||
where TOptions : IWellOperationImportOptions
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idCompany.HasValue || !idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||
throw new ForbidException("Недостаточно прав для редактирования ГГД на завершенной скважине");
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||
throw new ForbidException("Скважина недоступна для компании");
|
||||
|
||||
if (files.Count < 1)
|
||||
return this.ValidationBadRequest(nameof(files), "Нет файла");
|
||||
|
||||
var file = files[0];
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
|
||||
return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл.");
|
||||
|
||||
using Stream stream = file.OpenReadStream();
|
||||
var stream = file.GetExcelFile();
|
||||
|
||||
try
|
||||
{
|
||||
var sheet = parseMethod(stream, options);
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
var options = new WellOperationParserRequest(idWell, idType, timezone);
|
||||
var parser = wellOperationParserFactory.CreateParser<WellOperationParserRequest>(idType);
|
||||
var result = parser.Parse(stream, options);
|
||||
|
||||
var wellOperations = wellOperationImportService.Import(idWell, idUser.Value, options.IdType, sheet)
|
||||
.OrderBy(w => w.DateStart);
|
||||
|
||||
var dateStart = wellOperations.MinOrDefault(w => w.DateStart);
|
||||
|
||||
foreach (var wellOperation in wellOperations)
|
||||
{
|
||||
if (dateStart.HasValue)
|
||||
wellOperation.Day = (wellOperation.DateStart - dateStart.Value).TotalDays;
|
||||
}
|
||||
|
||||
//TODO: очень быстрый костыль
|
||||
if (deleteBeforeInsert is not null && options.IdType == WellOperation.IdOperationTypeFact)
|
||||
{
|
||||
return await InsertRangeAsync(idWell, options.IdType,
|
||||
deleteBeforeInsert.Value,
|
||||
wellOperations,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
return Ok(wellOperations);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
{
|
||||
return this.ValidationBadRequest(nameof(files), ex.Message);
|
||||
return this.ValidationBadRequest(nameof(file), ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение шаблона для заполнения ГГД
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("template")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
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)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
var idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
@ -609,4 +346,3 @@ namespace AsbCloudWebApi.Controllers
|
||||
return well.IdState != 2 || userRepository.HasPermission(idUser.Value, "WellOperation.editCompletedWell");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user