merge from dev to wellbores

This commit is contained in:
ngfrolov 2023-10-24 09:26:45 +05:00
commit 4a72504ee8
Signed by: ng.frolov
GPG Key ID: E99907A0357B29A7
30 changed files with 1032 additions and 520 deletions

View File

@ -5,21 +5,10 @@ namespace AsbCloudApp.Data.AutogeneratedDailyReport;
/// <summary> /// <summary>
/// Базовая информация о суточном отчёте /// Базовая информация о суточном отчёте
/// </summary> /// </summary>
public class AutoGeneratedDailyReportInfoDto public class AutoGeneratedDailyReportInfoDto : ReportInfoDto
{ {
/// <summary> /// <summary>
/// Дата формирования отчёта /// Дата формирования отчёта
/// </summary> /// </summary>
public DateOnly ReportDate { get; set; } public DateOnly ReportDate { get; set; }
/// <summary>
/// Название файла
/// </summary>
public string FileName { get; set; } = null!;
/// <summary>
/// Размер файла
/// </summary>
public int FileSize { get; set; }
} }

View File

@ -0,0 +1,26 @@
using AsbCloudApp.Data.SAUB;
using System;
namespace AsbCloudApp.Data.DrillTestReport
{
/// <summary>
/// Информация о drill test, выгружаемая в отчете
/// </summary>
public class DrillTestReportDataDto
{
/// <summary>
/// Данные для отчета
/// </summary>
public DrillTestDto Data { get; set; } = null!;
/// <summary>
/// Заголовок отчета
/// </summary>
public string Caption { get; set; } = null!;
/// <summary>
/// Дата отчета
/// </summary>
public DateTime Date { get; set; } = DateTime.Now;
}
}

View File

@ -0,0 +1,25 @@
using System;
namespace AsbCloudApp.Data.DrillTestReport
{
/// <summary>
/// Базовая информация о drill_test отчёте
/// </summary>
public class DrillTestReportInfoDto : ReportInfoDto
{
/// <summary>
/// Идентификатор отчета
/// </summary>
public int Id { get; set; }
/// <summary>
/// Проходка
/// </summary>
public float DrillDepth { get; set; }
/// <summary>
/// Дата и время
/// </summary>
public DateTime DateTime { get; set; }
}
}

View File

@ -0,0 +1,18 @@
namespace AsbCloudApp.Data
{
/// <summary>
/// Справочная информация об отчете
/// </summary>
public class ReportInfoDto
{
/// <summary>
/// Название файла
/// </summary>
public string FileName { get; set; } = null!;
/// <summary>
/// Размер файла
/// </summary>
public int FileSize { get; set; } = 0;
}
}

View File

@ -24,6 +24,11 @@ namespace AsbCloudApp.Data.SAUB
/// </summary> /// </summary>
public float DepthStart { get; set; } public float DepthStart { get; set; }
/// <summary>
/// Связанная с drill_test телеметрия
/// </summary>
public TelemetryDto? Telemetry { get; set; }
/// <summary> /// <summary>
/// Параметры теста /// Параметры теста
/// </summary> /// </summary>

View File

@ -26,7 +26,7 @@
public float? DepthSpeed { get; set; } public float? DepthSpeed { get; set; }
/// <summary> /// <summary>
/// Время бурения шага /// Время бурения шага, сек
/// </summary> /// </summary>
public float? TimeDrillStep { get; set; } public float? TimeDrillStep { get; set; }

View File

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Exceptions namespace AsbCloudApp.Exceptions
{ {
@ -8,9 +10,9 @@ namespace AsbCloudApp.Exceptions
public class ArgumentInvalidException : Exception public class ArgumentInvalidException : Exception
{ {
/// <summary> /// <summary>
/// название аргумента /// словарь с ошибками, где ключ - имя аргумента, а значение - массив из одного сообщения
/// </summary> /// </summary>
public string ParamName { get; } = string.Empty; public IDictionary<string, string[]> ErrorState { get; } = null!;
/// <summary> /// <summary>
/// конструктор /// конструктор
@ -20,7 +22,20 @@ namespace AsbCloudApp.Exceptions
public ArgumentInvalidException(string paramName, string message) public ArgumentInvalidException(string paramName, string message)
: base(message) : base(message)
{ {
ParamName = paramName; ErrorState = new Dictionary<string, string[]>() {
{ paramName, new[]{ message } }
};
}
/// <summary>
/// конструктор
/// </summary>
/// <param name="paramsNames"></param>
/// <param name="message"></param>
public ArgumentInvalidException(string[] paramsNames, string message)
: base(message)
{
ErrorState = paramsNames.ToDictionary(paramName => paramName, item => new[] { message });
} }
} }
} }

View File

@ -1,4 +1,6 @@
using AsbCloudApp.Data.SAUB; using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Requests;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,6 +11,24 @@ namespace AsbCloudApp.Repositories
/// </summary> /// </summary>
public interface IDrillTestRepository public interface IDrillTestRepository
{ {
/// <summary>
/// Получить данные drill_test в соответствии с параметрами запроса
/// </summary>
/// <param name="idTelemetry">ключ телеметрии</param>
/// <param name="request">запрос</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<DrillTestDto>> GetAllAsync(int idTelemetry, FileReportRequest request, CancellationToken cancellationToken);
/// <summary>
/// Получить запись drill_test
/// </summary>
/// <param name="idTelemetry">ключ телеметрии</param>
/// <param name="id">ключ записи drill_test</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<DrillTestDto> GetAsync(int idTelemetry, int id, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Сохранить данные drill_test /// Сохранить данные drill_test
/// </summary> /// </summary>

View File

@ -1,19 +0,0 @@
using System;
namespace AsbCloudApp.Requests;
/// <summary>
/// Параметры запроса для получения авто-генерируемых суточных отчётов
/// </summary>
public class AutoGeneratedDailyReportRequest : RequestBase
{
/// <summary>
/// Дата начала периода
/// </summary>
public DateOnly? StartDate { get; set; }
/// <summary>
/// Дата конца периода
/// </summary>
public DateOnly? FinishDate { get; set; }
}

View File

@ -0,0 +1,19 @@
using System;
namespace AsbCloudApp.Requests;
/// <summary>
/// Параметры запроса для получения отчетов (файлов)
/// </summary>
public class FileReportRequest : RequestBase
{
/// <summary>
/// Дата начала периода
/// </summary>
public DateOnly? GeDate { get; set; }
/// <summary>
/// Дата конца периода
/// </summary>
public DateOnly? LeDate { get; set; }
}

View File

@ -1,20 +0,0 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.AutogeneratedDailyReport;
namespace AsbCloudApp.Services.AutoGeneratedDailyReports;
/// <summary>
/// Сервис для генерации файлов авто-генерируемых суточный отчётов
/// </summary>
public interface IAutoGeneratedDailyReportMakerService
{
/// <summary>
/// Генерация файла
/// </summary>
/// <param name="report"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Stream> MakeReportAsync(AutoGeneratedDailyReportDto report, CancellationToken cancellationToken);
}

View File

@ -21,7 +21,7 @@ public interface IAutoGeneratedDailyReportService
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
Task<PaginationContainer<AutoGeneratedDailyReportInfoDto>> GetListAsync(int idWell, Task<PaginationContainer<AutoGeneratedDailyReportInfoDto>> GetListAsync(int idWell,
AutoGeneratedDailyReportRequest request, FileReportRequest request,
CancellationToken cancellationToken); CancellationToken cancellationToken);
/// <summary> /// <summary>

View File

@ -0,0 +1,35 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Requests;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services
{
/// <summary>
/// сервис по работе с отчетами drill test
/// </summary>
public interface IDrillTestReportService
{
/// <summary>
/// Список файлов drill test
/// </summary>
/// <param name="idWell">ключ скважины</param>
/// <param name="request">параметры запроса</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<PaginationContainer<DrillTestReportInfoDto>> GetListAsync(int idWell,
FileReportRequest request,
CancellationToken cancellationToken);
/// <summary>
/// Генерация файла с отчётом
/// </summary>
/// <param name="idWell">ключ скважины</param>
/// <param name="id">ключ drill test записи</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<(string fileName, Stream stream)> GenerateAsync(int idWell, int id, CancellationToken cancellationToken);
}
}

View File

@ -0,0 +1,19 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services;
/// <summary>
/// Сервис для генерации файлов отчётов
/// </summary>
public interface IReportMakerService<T>
{
/// <summary>
/// Генерация файла
/// </summary>
/// <param name="report">модель с данными для построения отчета</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Stream> MakeReportAsync(T report, CancellationToken cancellationToken);
}

View File

@ -161,6 +161,8 @@
new() { Id = 527, Name = "Manual.delete", Description = "Разрешение на удаление инструкций"}, new() { Id = 527, Name = "Manual.delete", Description = "Разрешение на удаление инструкций"},
new (){ Id = 528, Name="WellContact.delete", Description="Разрешение на удаление контакта"}, new (){ Id = 528, Name="WellContact.delete", Description="Разрешение на удаление контакта"},
new (){ Id = 529, Name="DrillTestReport.get", Description="Разрешение на получение отчетов drill test"},
}; };
} }
} }

View File

@ -13,6 +13,7 @@
<None Remove="CommonLibs\logo_720x404.png" /> <None Remove="CommonLibs\logo_720x404.png" />
<None Remove="CommonLibs\Readme.md" /> <None Remove="CommonLibs\Readme.md" />
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" /> <None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
<None Remove="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
<None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" /> <None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" /> <None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" /> <None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
@ -30,6 +31,7 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" /> <EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
<EmbeddedResource Include="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" /> <EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" /> <EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
<EmbeddedResource Include="Services\AutoGeneratedDailyReports\AutogeneratedDailyReportTemplate.xlsx" /> <EmbeddedResource Include="Services\AutoGeneratedDailyReports\AutogeneratedDailyReportTemplate.xlsx" />

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure
{
public static class AssemblyExtensions
{
public static async Task<Stream> GetTemplateCopyStreamAsync(this Assembly assembly, string templateName, CancellationToken cancellationToken)
{
var resourceName = assembly
.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith(templateName))!;
using var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName)!;
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream, cancellationToken);
memoryStream.Position = 0;
return memoryStream;
}
}
}

View File

@ -1,5 +1,6 @@
using System; using AsbCloudApp.Data;
using AsbCloudApp.Data; using AsbCloudApp.Data.AutogeneratedDailyReport;
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Data.Manuals; using AsbCloudApp.Data.Manuals;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.SAUB; using AsbCloudApp.Data.SAUB;
@ -24,6 +25,7 @@ using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
using AsbCloudInfrastructure.Services.DailyReport; using AsbCloudInfrastructure.Services.DailyReport;
using AsbCloudInfrastructure.Services.DetectOperations; using AsbCloudInfrastructure.Services.DetectOperations;
using AsbCloudInfrastructure.Services.DrillingProgram; using AsbCloudInfrastructure.Services.DrillingProgram;
using AsbCloudInfrastructure.Services.DrillTestReport;
using AsbCloudInfrastructure.Services.ProcessMaps.Report; using AsbCloudInfrastructure.Services.ProcessMaps.Report;
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling; using AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.SAUB; using AsbCloudInfrastructure.Services.SAUB;
@ -37,126 +39,127 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
public static class DependencyInjection public static class DependencyInjection
{ {
public static IAsbCloudDbContext MakeContext(string connectionString) public static IAsbCloudDbContext MakeContext(string connectionString)
{ {
var options = new DbContextOptionsBuilder<AsbCloudDbContext>() var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql(connectionString) .UseNpgsql(connectionString)
.Options; .Options;
var context = new AsbCloudDbContext(options); var context = new AsbCloudDbContext(options);
return context; return context;
} }
public static void MapsterSetup() public static void MapsterSetup()
{ {
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<DateTimeOffset, DateTime>() .ForType<DateTimeOffset, DateTime>()
.MapWith((source) => source.DateTime); .MapWith((source) => source.DateTime);
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<DateTime, DateTimeOffset>() .ForType<DateTime, DateTimeOffset>()
.MapWith((source) => source == default ? new DateTime(0, DateTimeKind.Utc) : source); .MapWith((source) => source == default ? new DateTime(0, DateTimeKind.Utc) : source);
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeDto, TimeOnly>() .ForType<TimeDto, TimeOnly>()
.MapWith((source) => source.MakeTimeOnly()); .MapWith((source) => source.MakeTimeOnly());
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeOnly, TimeDto>() .ForType<TimeOnly, TimeDto>()
.MapWith((source) => new(source)); .MapWith((source) => new(source));
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeOnly, TimeDto>() .ForType<TimeOnly, TimeDto>()
.MapWith((source) => new(source)); .MapWith((source) => new(source));
#pragma warning disable CS8603 // Possible null reference return. #pragma warning disable CS8603 // Possible null reference return.
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<WellDto, Well>() .ForType<WellDto, Well>()
.Ignore(dst => dst.Cluster, .Ignore(dst => dst.Cluster,
dst => dst.RelationCompaniesWells, dst => dst.RelationCompaniesWells,
dst => dst.Telemetry, dst => dst.Telemetry,
dst => dst.WellComposites, dst => dst.WellComposites,
dst => dst.WellCompositeSrcs, dst => dst.WellCompositeSrcs,
dst => dst.WellOperations, dst => dst.WellOperations,
dst => dst.WellType); dst => dst.WellType);
#pragma warning restore CS8603 // Possible null reference return. #pragma warning restore CS8603 // Possible null reference return.
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<ClusterDto, Cluster>() .ForType<ClusterDto, Cluster>()
.Ignore(dst => dst.Deposit, .Ignore(dst => dst.Deposit,
dst => dst.Wells); dst => dst.Wells);
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<FileCategoryDto, FileCategory>(); .ForType<FileCategoryDto, FileCategory>();
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<WellFinalDocumentDto, WellFinalDocument>(); .ForType<WellFinalDocumentDto, WellFinalDocument>();
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<NotificationDto, Notification>() .ForType<NotificationDto, Notification>()
.Ignore(dst => dst.NotificationCategory, .Ignore(dst => dst.NotificationCategory,
dst => dst.User); dst => dst.User);
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<ProcessMapWellDrilling, ProcessMapPlanWellDrillingDto>() .ForType<ProcessMapWellDrilling, ProcessMapPlanWellDrillingDto>()
.Map(dest => dest.AxialLoad, src => new PlanLimitDto .Map(dest => dest.AxialLoad, src => new PlanLimitDto
{ {
LimitMax = src.AxialLoadLimitMax, LimitMax = src.AxialLoadLimitMax,
Plan = src.AxialLoadPlan Plan = src.AxialLoadPlan
}) })
.Map(dest => dest.Flow, src => new PlanLimitDto .Map(dest => dest.Flow, src => new PlanLimitDto
{ {
LimitMax = src.FlowLimitMax, LimitMax = src.FlowLimitMax,
Plan = src.FlowPlan Plan = src.FlowPlan
}) })
.Map(dest => dest.Pressure, src => new PlanLimitDto .Map(dest => dest.Pressure, src => new PlanLimitDto
{ {
LimitMax = src.PressureLimitMax, LimitMax = src.PressureLimitMax,
Plan = src.PressurePlan Plan = src.PressurePlan
}) })
.Map(dest => dest.TopDriveSpeed, src => new PlanLimitDto .Map(dest => dest.TopDriveSpeed, src => new PlanLimitDto
{ {
LimitMax = src.TopDriveSpeedLimitMax, LimitMax = src.TopDriveSpeedLimitMax,
Plan = src.TopDriveSpeedPlan Plan = src.TopDriveSpeedPlan
}) })
.Map(dest => dest.TopDriveTorque, src => new PlanLimitDto .Map(dest => dest.TopDriveTorque, src => new PlanLimitDto
{ {
LimitMax = src.TopDriveTorqueLimitMax, LimitMax = src.TopDriveTorqueLimitMax,
Plan = src.TopDriveTorquePlan Plan = src.TopDriveTorquePlan
}); });
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>() .ForType<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>()
.Map(dest => dest.AxialLoadPlan, src => src.AxialLoad.Plan) .Map(dest => dest.AxialLoadPlan, src => src.AxialLoad.Plan)
.Map(dest => dest.AxialLoadLimitMax, src => src.AxialLoad.LimitMax) .Map(dest => dest.AxialLoadLimitMax, src => src.AxialLoad.LimitMax)
.Map(dest => dest.FlowPlan, src => src.Flow.Plan) .Map(dest => dest.FlowPlan, src => src.Flow.Plan)
.Map(dest => dest.FlowLimitMax, src => src.Flow.LimitMax) .Map(dest => dest.FlowLimitMax, src => src.Flow.LimitMax)
.Map(dest => dest.PressurePlan, src => src.Pressure.Plan) .Map(dest => dest.PressurePlan, src => src.Pressure.Plan)
.Map(dest => dest.PressureLimitMax, src => src.Pressure.LimitMax) .Map(dest => dest.PressureLimitMax, src => src.Pressure.LimitMax)
.Map(dest => dest.TopDriveSpeedPlan, src => src.TopDriveSpeed.Plan) .Map(dest => dest.TopDriveSpeedPlan, src => src.TopDriveSpeed.Plan)
.Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax) .Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax)
.Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan) .Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan)
.Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax); .Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax);
} }
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration) public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{ {
MapsterSetup(); MapsterSetup();
string connectionStringName = "DefaultConnection"; string connectionStringName = "DefaultConnection";
#if DEBUG #if DEBUG
connectionStringName = "DebugConnection"; connectionStringName = "DebugConnection";
#endif #endif
services.AddDbContext<AsbCloudDbContext>(options => services.AddDbContext<AsbCloudDbContext>(options =>
options.UseNpgsql(configuration.GetConnectionString(connectionStringName))); options.UseNpgsql(configuration.GetConnectionString(connectionStringName)));
services.AddMemoryCache(); services.AddMemoryCache();
services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>()); services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>());
services.AddSingleton(new WitsInfoService()); services.AddSingleton(new WitsInfoService());
services.AddSingleton<ITelemetryDataCache<TelemetryDataSaubDto>>(provider => TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider)); services.AddSingleton<ITelemetryDataCache<TelemetryDataSaubDto>>(provider => TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider));
@ -166,144 +169,145 @@ namespace AsbCloudInfrastructure
services.AddSingleton<NotificationBackgroundWorker>(); services.AddSingleton<NotificationBackgroundWorker>();
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration)); services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
services.AddTransient<IAuthService, AuthService>(); services.AddTransient<IAuthService, AuthService>();
services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>, ProcessMapPlanRepository<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>>(); services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>, ProcessMapPlanRepository<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>>();
services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellReamDto>, ProcessMapPlanRepository<ProcessMapPlanWellReamDto, ProcessMapWellReam>>(); services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellReamDto>, ProcessMapPlanRepository<ProcessMapPlanWellReamDto, ProcessMapWellReam>>();
services.AddTransient<IDepositRepository, DepositRepository>(); services.AddTransient<IDepositRepository, DepositRepository>();
services.AddTransient<IDrillingProgramService, DrillingProgramService>(); services.AddTransient<IDrillingProgramService, DrillingProgramService>();
services.AddTransient<IEventService, EventService>(); services.AddTransient<IEventService, EventService>();
services.AddTransient<FileService>(); services.AddTransient<FileService>();
services.AddTransient<IMeasureService, MeasureService>(); services.AddTransient<IMeasureService, MeasureService>();
services.AddTransient<IMessageService, MessageService>(); services.AddTransient<IMessageService, MessageService>();
services.AddTransient<IOperationsStatService, OperationsStatService>(); services.AddTransient<IOperationsStatService, OperationsStatService>();
services.AddTransient<IReportService, ReportService>(); services.AddTransient<IReportService, ReportService>();
services.AddTransient<ISetpointsService, SetpointsService>(); services.AddTransient<ISetpointsService, SetpointsService>();
services.AddTransient<ITelemetryService, TelemetryService>(); services.AddTransient<ITelemetryService, TelemetryService>();
services.AddTransient<ITelemetryUserService, TelemetryUserService>(); services.AddTransient<ITelemetryUserService, TelemetryUserService>();
services.AddTransient<ITimezoneService, TimezoneService>(); services.AddTransient<ITimezoneService, TimezoneService>();
services.AddTransient<IWellService, WellService>(); services.AddTransient<IWellService, WellService>();
services.AddTransient<IWellOperationImportService, WellOperationImportService>(); services.AddTransient<IWellOperationImportService, WellOperationImportService>();
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>(); services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>(); services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
services.AddTransient<IWellOperationRepository, WellOperationRepository>(); services.AddTransient<IWellOperationRepository, WellOperationRepository>();
services.AddTransient<IScheduleReportService, ScheduleReportService>(); services.AddTransient<IDailyReportService, DailyReportService>();
services.AddTransient<IDailyReportService, DailyReportService>(); services.AddTransient<IDetectedOperationService, DetectedOperationService>();
services.AddTransient<IDetectedOperationService, DetectedOperationService>(); services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>(); services.AddTransient<IScheduleRepository, ScheduleRepository>();
services.AddTransient<IScheduleRepository, ScheduleRepository>(); services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>(); services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>(); services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>(); services.AddTransient<IFileCategoryService, FileCategoryService>();
services.AddTransient<IFileCategoryService, FileCategoryService>(); services.AddTransient<ILimitingParameterService, LimitingParameterService>();
services.AddTransient<ILimitingParameterService, LimitingParameterService>(); services.AddTransient<IProcessMapReportWellDrillingService, ProcessMapReportWellDrillingService>();
services.AddTransient<IProcessMapReportWellDrillingService, ProcessMapReportWellDrillingService>(); services.AddTransient<IProcessMapPlanImportService, ProcessMapPlanImportWellDrillingService>();
services.AddTransient<IProcessMapPlanImportService, ProcessMapPlanImportWellDrillingService>(); services.AddTransient<WellInfoService>();
services.AddTransient<WellInfoService>(); services.AddTransient<IHelpPageService, HelpPageService>();
services.AddTransient<IHelpPageService, HelpPageService>();
services.AddTransient<TrajectoryService>(); services.AddTransient<TrajectoryService>();
services.AddTransient<IGtrRepository, GtrWitsRepository>(); services.AddTransient<IGtrRepository, GtrWitsRepository>();
services.AddTransient<NotificationService>(); services.AddTransient<NotificationService>();
services.AddTransient<INotificationRepository, NotificationRepository>(); services.AddTransient<INotificationRepository, NotificationRepository>();
services.AddTransient<ICrudRepository<NotificationCategoryDto>, CrudCacheRepositoryBase<NotificationCategoryDto, services.AddTransient<ICrudRepository<NotificationCategoryDto>, CrudCacheRepositoryBase<NotificationCategoryDto,
NotificationCategory>>(); NotificationCategory>>();
services.AddTransient<IDrillTestRepository, DrillTestRepository>(); services.AddTransient<IDrillTestRepository, DrillTestRepository>();
// admin crud services: // admin crud services:
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s => services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
new CrudCacheRepositoryBase<TelemetryDto, Telemetry>( new CrudCacheRepositoryBase<TelemetryDto, Telemetry>(
s.GetRequiredService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetRequiredService<IMemoryCache>(), s.GetRequiredService<IMemoryCache>(),
dbSet => dbSet.Include(t => t.Well))); // может быть включен в сервис TelemetryService dbSet => dbSet.Include(t => t.Well))); // может быть включен в сервис TelemetryService
services.AddTransient<ICrudRepository<DepositDto>, CrudCacheRepositoryBase<DepositDto, Deposit>>(s => services.AddTransient<ICrudRepository<DepositDto>, CrudCacheRepositoryBase<DepositDto, Deposit>>(s =>
new CrudCacheRepositoryBase<DepositDto, Deposit>( new CrudCacheRepositoryBase<DepositDto, Deposit>(
s.GetRequiredService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetRequiredService<IMemoryCache>(), s.GetRequiredService<IMemoryCache>(),
dbSet => dbSet.Include(d => d.Clusters))); dbSet => dbSet.Include(d => d.Clusters)));
services.AddTransient<ICrudRepository<CompanyDto>, CrudCacheRepositoryBase<CompanyDto, Company>>(s => services.AddTransient<ICrudRepository<CompanyDto>, CrudCacheRepositoryBase<CompanyDto, Company>>(s =>
new CrudCacheRepositoryBase<CompanyDto, Company>( new CrudCacheRepositoryBase<CompanyDto, Company>(
s.GetRequiredService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetRequiredService<IMemoryCache>(), s.GetRequiredService<IMemoryCache>(),
dbSet => dbSet.Include(c => c.CompanyType))); dbSet => dbSet.Include(c => c.CompanyType)));
services.AddTransient<ICrudRepository<CompanyTypeDto>, CrudCacheRepositoryBase<CompanyTypeDto, CompanyType>>(); services.AddTransient<ICrudRepository<CompanyTypeDto>, CrudCacheRepositoryBase<CompanyTypeDto, CompanyType>>();
services.AddTransient<ICrudRepository<ClusterDto>, CrudCacheRepositoryBase<ClusterDto, Cluster>>(s => services.AddTransient<ICrudRepository<ClusterDto>, CrudCacheRepositoryBase<ClusterDto, Cluster>>(s =>
new CrudCacheRepositoryBase<ClusterDto, Cluster>( new CrudCacheRepositoryBase<ClusterDto, Cluster>(
s.GetRequiredService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetRequiredService<IMemoryCache>(), s.GetRequiredService<IMemoryCache>(),
dbSet => dbSet dbSet => dbSet
.Include(c => c.Wells) .Include(c => c.Wells)
.Include(c => c.Deposit))); // может быть включен в сервис ClusterService .Include(c => c.Deposit))); // может быть включен в сервис ClusterService
services.AddTransient<ICrudRepository<DrillerDto>, CrudCacheRepositoryBase<DrillerDto, Driller>>(); services.AddTransient<ICrudRepository<DrillerDto>, CrudCacheRepositoryBase<DrillerDto, Driller>>();
services.AddTransient<IHelpPageRepository, HelpPageRepository>(); services.AddTransient<IHelpPageRepository, HelpPageRepository>();
services.AddTransient<IFileRepository, FileRepository>(); services.AddTransient<IFileRepository, FileRepository>();
services.AddTransient<IFileStorageRepository, FileStorageRepository>(); services.AddTransient<IFileStorageRepository, FileStorageRepository>();
services.AddTransient<IWellCompositeRepository, WellCompositeRepository>(); services.AddTransient<IWellCompositeRepository, WellCompositeRepository>();
services.AddTransient<IUserRoleRepository, UserRoleRepository>(); services.AddTransient<IUserRoleRepository, UserRoleRepository>();
services.AddTransient<IUserRepository, UserRepository>(); services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<ILimitingParameterRepository, LimitingParameterRepository>(); services.AddTransient<ILimitingParameterRepository, LimitingParameterRepository>();
services.AddTransient<ITelemetryWirelineRunOutRepository, TelemetryWirelineRunOutRepository>(); services.AddTransient<ITelemetryWirelineRunOutRepository, TelemetryWirelineRunOutRepository>();
services.AddTransient<IWellFinalDocumentsRepository, WellFinalDocumentsRepository>(); services.AddTransient<IWellFinalDocumentsRepository, WellFinalDocumentsRepository>();
services.AddTransient<ITrajectoryPlanRepository, TrajectoryPlanRepository>(); services.AddTransient<ITrajectoryPlanRepository, TrajectoryPlanRepository>();
services.AddTransient<ITrajectoryFactRepository, TrajectoryFactRepository>(); services.AddTransient<ITrajectoryFactRepository, TrajectoryFactRepository>();
services.AddTransient<IFaqRepository, FaqRepository>(); services.AddTransient<IFaqRepository, FaqRepository>();
services.AddTransient<ISlipsStatService, SlipsStatService>(); services.AddTransient<ISlipsStatService, SlipsStatService>();
services.AddTransient<IWellContactService, WellContactService>(); services.AddTransient<IWellContactService, WellContactService>();
services.AddTransient<ICrudRepository<WellSectionTypeDto>, CrudCacheRepositoryBase<WellSectionTypeDto, services.AddTransient<ICrudRepository<WellSectionTypeDto>, CrudCacheRepositoryBase<WellSectionTypeDto,
WellSectionType>>(); WellSectionType>>();
// Subsystem service // Subsystem service
services.AddTransient<ICrudRepository<SubsystemDto>, CrudCacheRepositoryBase<SubsystemDto, Subsystem>>(); services.AddTransient<ICrudRepository<SubsystemDto>, CrudCacheRepositoryBase<SubsystemDto, Subsystem>>();
services.AddTransient<ISubsystemService, SubsystemService>(); services.AddTransient<ISubsystemService, SubsystemService>();
services.AddTransient<ICrudRepository<PermissionDto>, CrudCacheRepositoryBase<PermissionDto, Permission>>(); services.AddTransient<ICrudRepository<PermissionDto>, CrudCacheRepositoryBase<PermissionDto, Permission>>();
// TelemetryData services // TelemetryData services
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>(); services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>(); services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
// Wits // Wits
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>();
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>();
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto, AsbCloudDb.Model.WITS.Record8>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto, AsbCloudDb.Model.WITS.Record8>>();
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto, AsbCloudDb.Model.WITS.Record50>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto, AsbCloudDb.Model.WITS.Record50>>();
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto, AsbCloudDb.Model.WITS.Record60>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto, AsbCloudDb.Model.WITS.Record60>>();
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>();
services.AddTransient<IAutoGeneratedDailyReportService, AutoGeneratedDailyReportService>(); services.AddTransient<IAutoGeneratedDailyReportService, AutoGeneratedDailyReportService>();
services.AddTransient<IAutoGeneratedDailyReportMakerService, AutoGeneratedDailyReportMakerService>(); services.AddTransient<IReportMakerService<AutoGeneratedDailyReportDto>, AutoGeneratedDailyReportMakerService>();
services.AddTransient<IDrillTestReportService, DrillTestReportService>();
services.AddTransient<IReportMakerService<DrillTestReportDataDto>, DrillTestReportMakerService>();
services.AddTransient<IManualDirectoryRepository, ManualDirectoryRepository>(); services.AddTransient<IManualDirectoryRepository, ManualDirectoryRepository>();
services.AddTransient<IManualCatalogService, ManualCatalogService>(); services.AddTransient<IManualCatalogService, ManualCatalogService>();
services.AddTransient<ICrudRepository<ManualDto>, CrudRepositoryBase<ManualDto, Manual>>(); services.AddTransient<ICrudRepository<ManualDto>, CrudRepositoryBase<ManualDto, Manual>>();
services.AddTransient<IWellboreService, WellboreService>(); services.AddTransient<IWellboreService, WellboreService>();
services.AddTransient<IWellOperationExportService, WellOperationExportService>(); services.AddTransient<IWellOperationExportService, WellOperationExportService>();
services.AddTransient<IWellOperationImportService, WellOperationImportService>(); services.AddTransient<IWellOperationImportService, WellOperationImportService>();
services.AddTransient<IWellOperationImportTemplateService, WellOperationImportTemplateService>(); services.AddTransient<IWellOperationImportTemplateService, WellOperationImportTemplateService>();
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>(); services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>(); services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
return services; return services;
} }
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services) public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
where TService : class where TService : class
where TImplementation : class, TService where TImplementation : class, TService
=> services.AddTransient<TService, TImplementation>() => services.AddTransient<TService, TImplementation>()
.AddTransient(provider => new Lazy<TService>(provider.GetRequiredService<TService>)); .AddTransient(provider => new Lazy<TService>(provider.GetRequiredService<TService>));
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory) public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
where TService : class where TService : class
where TImplementation : class, TService where TImplementation : class, TService
=> services.AddTransient<TService, TImplementation>(implementationFactory) => services.AddTransient<TService, TImplementation>(implementationFactory)
.AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider))); .AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider)));
} }

View File

@ -1,7 +1,13 @@
using AsbCloudApp.Data.SAUB; using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -16,6 +22,47 @@ namespace AsbCloudInfrastructure.Repository
this.db = db; this.db = db;
} }
public async Task<IEnumerable<DrillTestDto>> GetAllAsync(int idTelemetry, FileReportRequest request, CancellationToken cancellationToken)
{
var query = db.DrillTests
.Where(d => d.IdTelemetry == idTelemetry)
.Include(d => d.Telemetry)
.AsNoTracking();
if (request.GeDate.HasValue)
{
var startDateUTC = new DateTimeOffset(request.GeDate.Value.Year, request.GeDate.Value.Month, request.GeDate.Value.Day, 0, 0, 0, TimeSpan.Zero);
query = query.Where(q => q.TimeStampStart >= startDateUTC);
}
if (request.LeDate.HasValue)
{
var finishDateUTC = new DateTimeOffset(request.LeDate.Value.Year, request.LeDate.Value.Month, request.LeDate.Value.Day, 0, 0, 0, TimeSpan.Zero);
query = query.Where(q => q.TimeStampStart <= finishDateUTC);
}
var entities = await query.ToListAsync(cancellationToken);
var dtos = entities.Select(e => Convert(e));
return dtos;
}
public async Task<DrillTestDto> GetAsync(int idTelemetry, int id, CancellationToken cancellationToken)
{
var drillTest = await db.DrillTests
.Where(d => d.Id == id)
.Include(d => d.Telemetry)
.Where(d => d.Telemetry.Id == idTelemetry)
.FirstOrDefaultAsync(cancellationToken);
if (drillTest is null)
throw new ArgumentInvalidException(new string[] { nameof(id), nameof(idTelemetry) }, $"Drill test with id: {id} and idTelemetry: {idTelemetry} does not exist.");
var dto = Convert(drillTest);
return dto;
}
public async Task<int> SaveDataAsync(int idTelemetry, DrillTestDto dto, CancellationToken token) public async Task<int> SaveDataAsync(int idTelemetry, DrillTestDto dto, CancellationToken token)
{ {
var entity = dto.Adapt<DrillTest>(); var entity = dto.Adapt<DrillTest>();
@ -24,5 +71,12 @@ namespace AsbCloudInfrastructure.Repository
var result = await db.SaveChangesAsync(token); var result = await db.SaveChangesAsync(token);
return result; return result;
} }
private DrillTestDto Convert(DrillTest entity)
{
var dto = entity.Adapt<DrillTestDto>();
dto.TimeStampStart = dto.TimeStampStart.ToRemoteDateTime(dto.Telemetry?.TimeZone?.Hours ?? 0);
return dto;
}
} }
} }

View File

@ -5,14 +5,16 @@ using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data.AutogeneratedDailyReport; using AsbCloudApp.Data.AutogeneratedDailyReport;
using AsbCloudApp.Services.AutoGeneratedDailyReports; using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
using ClosedXML.Excel; using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports; namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
public class AutoGeneratedDailyReportMakerService : IAutoGeneratedDailyReportMakerService public class AutoGeneratedDailyReportMakerService : IReportMakerService<AutoGeneratedDailyReportDto>
{ {
private readonly string templateName = "AutogeneratedDailyReportTemplate.xlsx";
private readonly IEnumerable<IExcelBlockWriter> blockWriters = new List<IExcelBlockWriter>() private readonly IEnumerable<IExcelBlockWriter> blockWriters = new List<IExcelBlockWriter>()
{ {
new HeadExcelBlockWriter(), new HeadExcelBlockWriter(),
@ -20,10 +22,12 @@ public class AutoGeneratedDailyReportMakerService : IAutoGeneratedDailyReportMak
new LimitingParameterExcelBlockWriter(), new LimitingParameterExcelBlockWriter(),
new TimeBalanceExcelBlockWriter() new TimeBalanceExcelBlockWriter()
}; };
public async Task<Stream> MakeReportAsync(AutoGeneratedDailyReportDto report, CancellationToken cancellationToken) public async Task<Stream> MakeReportAsync(AutoGeneratedDailyReportDto report, CancellationToken cancellationToken)
{ {
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken); using var excelTemplateStream = await Assembly
.GetExecutingAssembly()
.GetTemplateCopyStreamAsync(templateName, cancellationToken);
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled); using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
@ -35,22 +39,6 @@ public class AutoGeneratedDailyReportMakerService : IAutoGeneratedDailyReportMak
return memoryStream; return memoryStream;
} }
private async Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
{
var resourceName = Assembly.GetExecutingAssembly()
.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith("AutogeneratedDailyReportTemplate.xlsx"))!;
using var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName)!;
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream, cancellationToken);
memoryStream.Position = 0;
return memoryStream;
}
private void AddToWorkbook(XLWorkbook workbook, AutoGeneratedDailyReportDto report) private void AddToWorkbook(XLWorkbook workbook, AutoGeneratedDailyReportDto report)
{ {

View File

@ -26,14 +26,14 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
private readonly ISubsystemOperationTimeService subsystemOperationTimeService; private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
private readonly ICrudRepository<SubsystemDto> subsystemRepository; private readonly ICrudRepository<SubsystemDto> subsystemRepository;
private readonly ILimitingParameterService limitingParameterService; private readonly ILimitingParameterService limitingParameterService;
private readonly IAutoGeneratedDailyReportMakerService autoGeneratedDailyReportMakerService; private readonly IReportMakerService<AutoGeneratedDailyReportDto> autoGeneratedDailyReportMakerService;
public AutoGeneratedDailyReportService(IWellService wellService, public AutoGeneratedDailyReportService(IWellService wellService,
IWellOperationRepository wellOperationRepository, IWellOperationRepository wellOperationRepository,
ISubsystemOperationTimeService subsystemOperationTimeService, ISubsystemOperationTimeService subsystemOperationTimeService,
ICrudRepository<SubsystemDto> subsystemRepository, ICrudRepository<SubsystemDto> subsystemRepository,
ILimitingParameterService limitingParameterService, ILimitingParameterService limitingParameterService,
IAutoGeneratedDailyReportMakerService autoGeneratedDailyReportMakerService) IReportMakerService<AutoGeneratedDailyReportDto> autoGeneratedDailyReportMakerService)
{ {
this.wellOperationRepository = wellOperationRepository; this.wellOperationRepository = wellOperationRepository;
this.wellService = wellService; this.wellService = wellService;
@ -44,7 +44,7 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
} }
public async Task<PaginationContainer<AutoGeneratedDailyReportInfoDto>> GetListAsync(int idWell, public async Task<PaginationContainer<AutoGeneratedDailyReportInfoDto>> GetListAsync(int idWell,
AutoGeneratedDailyReportRequest request, FileReportRequest request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var result = new PaginationContainer<AutoGeneratedDailyReportInfoDto> var result = new PaginationContainer<AutoGeneratedDailyReportInfoDto>
@ -67,19 +67,19 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
if (datesRange is null) if (datesRange is null)
return result; return result;
if (request.StartDate.HasValue) if (request.GeDate.HasValue)
{ {
var startDate = new DateTime(request.StartDate.Value.Year, request.StartDate.Value.Month, var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month,
request.StartDate.Value.Day); request.GeDate.Value.Day);
if(startDate.Date >= datesRange.From.Date) if(startDate.Date >= datesRange.From.Date)
datesRange.From = startDate; datesRange.From = startDate;
} }
if (request.FinishDate.HasValue) if (request.LeDate.HasValue)
{ {
var finishDate = new DateTime(request.FinishDate.Value.Year, request.FinishDate.Value.Month, var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month,
request.FinishDate.Value.Day); request.LeDate.Value.Day);
if (finishDate.Date <= datesRange.To.Date) if (finishDate.Date <= datesRange.To.Date)
datesRange.To = finishDate; datesRange.To = finishDate;

View File

@ -0,0 +1,90 @@
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Services;
using ClosedXML.Excel;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.DrillTestReport
{
public class DrillTestReportMakerService : IReportMakerService<DrillTestReportDataDto>
{
private readonly string templateName = "DrillTestReportTemplate.xlsx";
private readonly string sheetName = "Лист1";
private readonly int startRowNumber = 8;
public async Task<Stream> MakeReportAsync(DrillTestReportDataDto report, CancellationToken cancellationToken)
{
using var excelTemplateStream = await Assembly.GetExecutingAssembly().GetTemplateCopyStreamAsync(templateName, cancellationToken);
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
AddToWorkbook(workbook, report);
MemoryStream memoryStream = new MemoryStream();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
private void AddToWorkbook(XLWorkbook workbook, DrillTestReportDataDto report)
{
var drillTestEntities = report.Data.Params;
if (!drillTestEntities.Any())
return;
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
sheet.Cell(4, 2).Value = report.Caption;
sheet.Cell(5, 2)._SetValue(report.Date, setAllBorders: false);
var rowNumber = startRowNumber;
var stepWithMaxDepthSpeed = drillTestEntities.OrderByDescending(p => p.DepthSpeed).FirstOrDefault()!.Step;
var startDepth = report.Data.DepthStart;
var startDate = report.Data.TimeStampStart;
foreach (var drillTestEntity in drillTestEntities)
{
var endDepth = startDepth + (drillTestEntity.DepthDrillStep ?? 0);
var endDateTime = startDate.AddSeconds(drillTestEntity.TimeDrillStep ?? 0);
sheet.Cell(rowNumber, 2).Value = startDepth;
sheet.Cell(rowNumber, 3).Value = endDepth;
sheet.Cell(rowNumber, 4).Value = drillTestEntity.DepthDrillStep;
sheet.Cell(rowNumber, 5).Value = drillTestEntity.Workload;
sheet.Cell(rowNumber, 6).Value = drillTestEntity.Speed;
var cell = sheet.Cell(rowNumber, 7);
cell._SetValue(startDate.DateTime);
cell = sheet.Cell(rowNumber, 8);
cell._SetValue(endDateTime.DateTime);
sheet.Cell(rowNumber, 9).Value = Math.Round((drillTestEntity.TimeDrillStep ?? 0) / (60 * 60), 2);
sheet.Cell(rowNumber, 10).Value = drillTestEntity.DepthSpeed;
if (drillTestEntity.Step == stepWithMaxDepthSpeed)
{
var currentCells = sheet.Row(rowNumber).Cells(1, 10);
currentCells.Style.Fill.BackgroundColor = XLColor.Yellow;
}
startDepth = endDepth;
startDate = endDateTime;
rowNumber++;
}
}
}
}

View File

@ -0,0 +1,99 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.DrillTestReport
{
public class DrillTestReportService : IDrillTestReportService
{
private readonly IWellService wellService;
private readonly IDrillTestRepository drillTestRepository;
private readonly ITelemetryService telemetryService;
private readonly IReportMakerService<DrillTestReportDataDto> drillTestReportMakerService;
public DrillTestReportService(
IWellService wellService,
IDrillTestRepository drillTestRepository,
ITelemetryService telemetryService,
IReportMakerService<DrillTestReportDataDto> drillTestReportMakerService)
{
this.wellService = wellService;
this.drillTestRepository = drillTestRepository;
this.telemetryService = telemetryService;
this.drillTestReportMakerService = drillTestReportMakerService;
}
public async Task<(string fileName, Stream stream)> GenerateAsync(int idWell, int id, CancellationToken cancellationToken)
{
var well = wellService.GetOrDefault(idWell);
if (well is null)
throw new ArgumentInvalidException(nameof(idWell), $"Well with id: {idWell} does not exist.");
if (well.IdTelemetry is null)
throw new ArgumentInvalidException(nameof(well.IdTelemetry), $"Well with id: {idWell} does not have telemetry.");
var dto = await drillTestRepository.GetAsync(well.IdTelemetry.Value, id, cancellationToken);
var report = new DrillTestReportDataDto()
{
Data = dto,
Caption = string.Format("Месторождение: {0}, куст: {1}, скважина: {2}",
well.Deposit ?? "-",
well.Cluster ?? "-",
well.Caption ?? "-"),
Date = DateTime.Now,
};
var fileName = string.Format("Drill_test_{0}.xlsx", dto.TimeStampStart.ToString("dd.mm.yyyy_HH_MM_ss"));
var stream = await drillTestReportMakerService.MakeReportAsync(report, cancellationToken);
return (fileName, stream);
}
public async Task<PaginationContainer<DrillTestReportInfoDto>> GetListAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
{
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
if (telemetry is null)
throw new Exception($"Telemetry with idWell: {idWell} does not exist.");
var result = new PaginationContainer<DrillTestReportInfoDto>
{
Skip = request.Skip ?? 0,
Take = request.Take ?? 10,
Items = Enumerable.Empty<DrillTestReportInfoDto>()
};
var reports = new List<DrillTestReportInfoDto>();
var timezone = telemetryService.GetTimezone(telemetry.Id);
var dtos = await drillTestRepository.GetAllAsync(telemetry.Id, request, cancellationToken);
foreach (var dto in dtos)
{
var remoteDateTime = dto.TimeStampStart.ToRemoteDateTime(timezone.Hours);
reports.Add(new DrillTestReportInfoDto
{
FileName = string.Format("Drill_test_{0}", dto.TimeStampStart.DateTime),
DrillDepth = (dto.Params
.Where(p => p.DepthDrillStep.HasValue)
.Sum(x => x.DepthDrillStep) ?? 0) + dto.DepthStart,
DateTime = dto.TimeStampStart.DateTime,
Id = dto.Id,
});
}
result.Items = reports;
return result;
}
}
}

View File

@ -8,119 +8,123 @@ namespace AsbCloudInfrastructure;
internal static class XLExtentions internal static class XLExtentions
{ {
internal static IXLRange _SetValue(this IXLRange range, object value) internal static IXLRange _SetValue(this IXLRange range, object value)
{ {
var mergedRange = range.Merge(); var mergedRange = range.Merge();
mergedRange.FirstCell()._SetValue(value); mergedRange.FirstCell()._SetValue(value);
var colWidth = mergedRange.FirstCell().WorksheetColumn().Width; var colWidth = mergedRange.FirstCell().WorksheetColumn().Width;
var maxCharsToWrap = colWidth / (0.1d * mergedRange.FirstCell().Style.Font.FontSize); var maxCharsToWrap = colWidth / (0.1d * mergedRange.FirstCell().Style.Font.FontSize);
if (value is string valueString && valueString.Length > maxCharsToWrap) if (value is string valueString && valueString.Length > maxCharsToWrap)
{ {
var row = mergedRange.FirstCell().WorksheetRow(); var row = mergedRange.FirstCell().WorksheetRow();
var baseHeight = row.Height; var baseHeight = row.Height;
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + valueString.Length / maxCharsToWrap); row.Height = 0.5d * baseHeight * Math.Ceiling(1d + valueString.Length / maxCharsToWrap);
} }
mergedRange.Style.SetAllBorders() mergedRange.Style.SetAllBorders()
.Alignment.SetWrapText(true); .Alignment.SetWrapText(true);
return mergedRange; return mergedRange;
} }
internal static IXLCell _SetValue(this IXLCell cell, object value) internal static IXLCell _SetValue(this IXLCell cell, object value)
{ {
switch (value) switch (value)
{ {
case DateTime dateTime: case DateTime dateTime:
cell._SetValue(dateTime); cell._SetValue(dateTime);
break; break;
case IFormattable formattable: case IFormattable formattable:
cell._SetValue(formattable); cell._SetValue(formattable);
break; break;
case string valueString: case string valueString:
cell._SetValue(valueString); cell._SetValue(valueString);
break; break;
default: default:
cell.Value = value; cell.Value = value;
break; break;
} }
return cell; return cell;
} }
internal static IXLCell _SetValue(this IXLCell cell, string value, bool adaptRowHeight = false) internal static IXLCell _SetValue(this IXLCell cell, string value, bool adaptRowHeight = false)
{ {
cell.Value = value; cell.Value = value;
cell.Style cell.Style
.SetAllBorders() .SetAllBorders()
.Alignment.WrapText = true; .Alignment.WrapText = true;
cell.Value = value; cell.Value = value;
if (adaptRowHeight) if (adaptRowHeight)
{ {
var colWidth = cell.WorksheetColumn().Width; var colWidth = cell.WorksheetColumn().Width;
var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize); var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize);
if (value.Length > maxCharsToWrap) if (value.Length > maxCharsToWrap)
{ {
var row = cell.WorksheetRow(); var row = cell.WorksheetRow();
var baseHeight = row.Height; var baseHeight = row.Height;
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap);
} }
} }
return cell; return cell;
} }
internal static IXLCell _ValueNoBorder(this IXLCell cell, string value, bool adaptRowHeight = false) internal static IXLCell _ValueNoBorder(this IXLCell cell, string value, bool adaptRowHeight = false)
{ {
cell.Value = value; cell.Value = value;
cell.Style.Alignment.WrapText = true; cell.Style.Alignment.WrapText = true;
cell.Value = value; cell.Value = value;
if (adaptRowHeight) if (adaptRowHeight)
{ {
var colWidth = cell.WorksheetColumn().Width; var colWidth = cell.WorksheetColumn().Width;
var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize); var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize);
if (value.Length > maxCharsToWrap) if (value.Length > maxCharsToWrap)
{ {
var row = cell.WorksheetRow(); var row = cell.WorksheetRow();
var baseHeight = row.Height; var baseHeight = row.Height;
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap);
} }
} }
return cell; return cell;
} }
internal static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS") internal static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS", bool setAllBorders = true)
{ {
cell.Value = value; cell.Value = value;
cell.Style if (setAllBorders == true)
.SetAllBorders() {
.Alignment.WrapText = true; cell.Style
.SetAllBorders()
.Alignment.WrapText = true;
}
cell.Value = value;
cell.DataType = XLDataType.DateTime; cell.Value = value;
cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
return cell; cell.DataType = XLDataType.DateTime;
} cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
internal static IXLCell _SetValue(this IXLCell cell, IFormattable value, string format = "0.00") return cell;
{ }
cell.Value = value;
cell.Style
.SetAllBorders()
.Alignment.WrapText = true;
cell.Value = value; internal static IXLCell _SetValue(this IXLCell cell, IFormattable value, string format = "0.00")
{
cell.Value = value;
cell.Style
.SetAllBorders()
.Alignment.WrapText = true;
cell.DataType = XLDataType.Number; cell.Value = value;
cell.Style.NumberFormat.Format = "0.00";
return cell; cell.DataType = XLDataType.Number;
} cell.Style.NumberFormat.Format = "0.00";
return cell;
}
public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00") public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00")
{ {
@ -158,60 +162,60 @@ internal static class XLExtentions
} }
internal static IXLStyle SetAllBorders(this IXLStyle style, XLBorderStyleValues borderStyle = XLBorderStyleValues.Thin) internal static IXLStyle SetAllBorders(this IXLStyle style, XLBorderStyleValues borderStyle = XLBorderStyleValues.Thin)
{ {
style.Border.RightBorder = borderStyle; style.Border.RightBorder = borderStyle;
style.Border.LeftBorder = borderStyle; style.Border.LeftBorder = borderStyle;
style.Border.TopBorder = borderStyle; style.Border.TopBorder = borderStyle;
style.Border.BottomBorder = borderStyle; style.Border.BottomBorder = borderStyle;
style.Border.InsideBorder = borderStyle; style.Border.InsideBorder = borderStyle;
style.Border.OutsideBorder = borderStyle; style.Border.OutsideBorder = borderStyle;
return style; return style;
} }
internal static IXLStyle SetBaseFont(this IXLStyle style) internal static IXLStyle SetBaseFont(this IXLStyle style)
{ {
style.Font.FontName = "Calibri"; style.Font.FontName = "Calibri";
style.Font.FontSize = 10; style.Font.FontSize = 10;
return style; return style;
} }
internal static IXLStyle SetH1(this IXLStyle style) internal static IXLStyle SetH1(this IXLStyle style)
{ {
style.Font.FontName = "Calibri"; style.Font.FontName = "Calibri";
style.Font.FontSize = 14; style.Font.FontSize = 14;
return style; return style;
} }
/// <summary> /// <summary>
/// Костыль исправляющий проблему в библиотеке IXLRange Range(this IXLWorksheet, IXLAddress, IXLAddress) с кастингом IXLAddress к XLAddress. /// Костыль исправляющий проблему в библиотеке IXLRange Range(this IXLWorksheet, IXLAddress, IXLAddress) с кастингом IXLAddress к XLAddress.
/// </summary> /// </summary>
/// <param name="sheet"></param> /// <param name="sheet"></param>
/// <param name="begin"></param> /// <param name="begin"></param>
/// <param name="end"></param> /// <param name="end"></param>
/// <returns></returns> /// <returns></returns>
internal static IXLRange _Range(this IXLWorksheet sheet, CellAddress begin, CellAddress end) internal static IXLRange _Range(this IXLWorksheet sheet, CellAddress begin, CellAddress end)
=> sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber); => sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber);
internal static T? GetCellValue<T>(this IXLCell cell) internal static T? GetCellValue<T>(this IXLCell cell)
{ {
try try
{ {
if (cell.IsEmpty() && default(T) == null) if (cell.IsEmpty() && default(T) == null)
return default; return default;
if (typeof(T) != typeof(DateTime)) if (typeof(T) != typeof(DateTime))
return (T)Convert.ChangeType(cell.GetFormattedString(), typeof(T), CultureInfo.InvariantCulture); return (T)Convert.ChangeType(cell.GetFormattedString(), typeof(T), CultureInfo.InvariantCulture);
if (cell.Value is DateTime dateTime) if (cell.Value is DateTime dateTime)
return (T)(object)dateTime; return (T)(object)dateTime;
return (T)(object)DateTime.FromOADate((double)cell.Value); return (T)(object)DateTime.FromOADate((double)cell.Value);
} }
catch catch
{ {
throw new FileFormatException( throw new FileFormatException(
$"Лист '{cell.Worksheet.Name}'. Ячейка: ({cell.Address.RowNumber},{cell.Address.ColumnNumber}) содержит некорректное значение"); $"Лист '{cell.Worksheet.Name}'. Ячейка: ({cell.Address.RowNumber},{cell.Address.ColumnNumber}) содержит некорректное значение");
} }
} }
} }

View File

@ -25,7 +25,8 @@ public class AutoGeneratedDailyReportController : ControllerBase
private readonly IAutoGeneratedDailyReportService autoGeneratedDailyReportService; private readonly IAutoGeneratedDailyReportService autoGeneratedDailyReportService;
private readonly IWellService wellService; private readonly IWellService wellService;
public AutoGeneratedDailyReportController(IAutoGeneratedDailyReportService autoGeneratedDailyReportService, public AutoGeneratedDailyReportController(
IAutoGeneratedDailyReportService autoGeneratedDailyReportService,
IWellService wellService) IWellService wellService)
{ {
this.autoGeneratedDailyReportService = autoGeneratedDailyReportService; this.autoGeneratedDailyReportService = autoGeneratedDailyReportService;
@ -66,7 +67,7 @@ public class AutoGeneratedDailyReportController : ControllerBase
[HttpGet("all")] [HttpGet("all")]
[ProducesResponseType(typeof(PaginationContainer<AutoGeneratedDailyReportInfoDto>), (int)HttpStatusCode.OK)] [ProducesResponseType(typeof(PaginationContainer<AutoGeneratedDailyReportInfoDto>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> GetListAsync([FromRoute][Required] int idWell, public async Task<IActionResult> GetListAsync([FromRoute][Required] int idWell,
[FromQuery] AutoGeneratedDailyReportRequest request, [FromQuery] FileReportRequest request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (!await CanUserAccessToWellAsync(idWell, cancellationToken)) if (!await CanUserAccessToWellAsync(idWell, cancellationToken))

View File

@ -0,0 +1,133 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudWebApi.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.ComponentModel.DataAnnotations;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers;
/// <summary>
/// Контроллер для drill_test отчётов
/// </summary>
[ApiController]
[Authorize]
public class DrillTestController : ControllerBase
{
private readonly IDrillTestReportService drillTestReportService;
private readonly IDrillTestRepository drillTestRepository;
private readonly IWellService wellService;
private readonly ITelemetryService telemetryService;
private readonly IHubContext<TelemetryHub> telemetryHubContext;
public string SignalRMethodGetDataName { get; protected set; } = "ReceiveDrilltestData";
public DrillTestController(
IDrillTestReportService drillTestReportService,
IDrillTestRepository drillTestRepository,
IWellService wellService,
ITelemetryService telemetryService,
IHubContext<TelemetryHub> telemetryHubContext)
{
this.drillTestReportService = drillTestReportService;
this.drillTestRepository = drillTestRepository;
this.wellService = wellService;
this.telemetryService = telemetryService;
this.telemetryHubContext = telemetryHubContext;
}
/// <summary>
/// Метод получения данных drill_test и drill_test_params от панели оператора.
/// Сохраняет в БД.
/// </summary>
/// <param name="uid">уникальный идентификатор записи drill_test</param>
/// <param name="dto">запись drill test</param>
/// <param name="token"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("api/telemetry/{uid}/[controller]")]
public async Task<IActionResult> PostDataAsync(
string uid,
[FromBody] DrillTestDto dto,
CancellationToken token)
{
var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid);
if (telemetry is null)
throw new Exception($"Telemetry with RemoteUid: {uid} does not exist.");
await drillTestRepository.SaveDataAsync(telemetry.Id, dto, token);
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
if (idWell is not null)
_ = Task.Run(async () =>
{
var clients = telemetryHubContext.Clients.Group($"well_{idWell}");
await clients.SendAsync(SignalRMethodGetDataName, dto);
}, CancellationToken.None);
return Ok();
}
/// <summary>
/// Формирование отчёта
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="id">Ключ entity test записи</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("api/well/{idWell}/[controller]")]
[Permission]
[ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK, "application/octet-stream")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> GenerateReportAsync([FromRoute] int idWell,
[FromQuery] int id,
CancellationToken cancellationToken)
{
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
return Forbid();
var reportFile = await drillTestReportService.GenerateAsync(idWell, id, cancellationToken);
return File(reportFile.stream, "application/octet-stream", reportFile.fileName);
}
/// <summary>
/// Список файлов drill test отчётов
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="request">Параметры запроса</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("api/well/{idWell}/[controller]/all")]
[Permission]
[ProducesResponseType(typeof(PaginationContainer<DrillTestReportInfoDto>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> GetListAsync([FromRoute][Required] int idWell,
[FromQuery] FileReportRequest request,
CancellationToken cancellationToken)
{
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
return Forbid();
var reports = await drillTestReportService.GetListAsync(idWell,
request,
cancellationToken);
return Ok(reports);
}
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken cancellationToken)
{
int? idCompany = User.GetCompanyId();
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
idWell, cancellationToken).ConfigureAwait(false);
}
}

View File

@ -1,69 +0,0 @@
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudWebApi.SignalR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers.SAUB
{
[Route("api/telemetry")]
[ApiController]
public class DrillTestController : ControllerBase
{
protected readonly IWellService wellService;
private readonly ITelemetryService telemetryService;
private readonly IDrillTestRepository drillTestRepository;
private readonly IHubContext<TelemetryHub> telemetryHubContext;
public string SignalRMethodGetDataName { get; protected set; } = "ReceiveDrilltestData";
public DrillTestController(
ITelemetryService telemetryService,
IDrillTestRepository drillTestRepository,
IWellService wellService,
IHubContext<TelemetryHub> telemetryHubContext)
{
this.telemetryService = telemetryService;
this.drillTestRepository = drillTestRepository;
this.wellService = wellService;
this.telemetryHubContext = telemetryHubContext;
}
/// <summary>
/// Метод получения данных drill_test и drill_test_params от панели оператора.
/// Сохраняет в БД.
/// </summary>
/// <param name="uid">уникальный идентификатор записи drill_test</param>
/// <param name="dto">запись drill test</param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPost("{uid}/[controller]")]
public async Task<IActionResult> PostDataAsync(
string uid,
[FromBody] DrillTestDto dto,
CancellationToken token)
{
var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid);
if (telemetry is null)
throw new Exception($"Telemetry with RemoteUid: {uid} does not exist.");
await drillTestRepository.SaveDataAsync(telemetry.Id, dto, token);
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
if (idWell is not null)
_ = Task.Run(async () =>
{
var clients = telemetryHubContext.Clients.Group($"well_{idWell}");
await clients.SendAsync(SignalRMethodGetDataName, dto);
}, CancellationToken.None);
return Ok();
}
}
}

View File

@ -56,10 +56,7 @@ namespace AsbCloudWebApi.Middlewares
private static string MakeJsonBody(ArgumentInvalidException ex) private static string MakeJsonBody(ArgumentInvalidException ex)
{ {
var errors = new Dictionary<string, string[]> { var problem = new ValidationProblemDetails(ex.ErrorState);
{ ex.ParamName, new[]{ ex.Message } }
};
var problem = new ValidationProblemDetails(errors);
var buffer = System.Text.Json.JsonSerializer.Serialize(problem); var buffer = System.Text.Json.JsonSerializer.Serialize(problem);
return buffer; return buffer;
} }

View File

@ -0,0 +1,45 @@
@baseUrl = http://127.0.0.1:5000
@contentType = application/json
@contentTypeForFiles = application/octet-stream
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2OTc0MzcwMzEsImV4cCI6MTcyODk5NDYzMSwiaXNzIjoiYSIsImF1ZCI6ImEifQ.vB7Qb3K9gG77iP8y25zB3RcZIQk9cHkq3I1SkcooYJs
@uid = 20210101_000000000
@id = 1
@idWell = 55
### ïîëó÷åíèå äàííûõ drill test ñ ïàíåëè è ñîõðàíåíèå èõ â ÅÖÏ
POST {{baseUrl}}/api/telemetry/{{uid}}/DrillTest
Content-Type: {{contentType}}
accept: */*
{
"id": {{id}},
"timeStampStart": "2023-10-23T08:55:36.882Z",
"depthStart": 10,
"params": [
{
"step": 1,
"workload": 2,
"speed": 3,
"depthSpeed": 4,
"timeDrillStep": 5,
"depthDrillStep": 15
}
]
}
### Ïîëó÷åíèå ñïèñêà ôàéëîâ drill test îò÷¸òîâ
GET {{baseUrl}}/api/well/{{idWell}}/DrillTest/all
Content-Type: {{contentType}}
accept: */*
Authorization: {{auth}}
### Ãåíåðàöèÿ ôàéëà ñ drill test îò÷¸òîì
GET {{baseUrl}}/api/well/{{idWell}}/DrillTest?id={{id}}
Content-Type: {{contentTypeForFiles}}
accept: */*
Authorization: {{auth}}