Merge branch 'dev' into gtr

This commit is contained in:
ngfrolov 2023-04-18 10:17:52 +05:00
commit 1bdb88492e
Signed by: ng.frolov
GPG Key ID: E99907A0357B29A7
54 changed files with 23971 additions and 102 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
namespace AsbCloudApp.Data.SAUB namespace AsbCloudApp.Data.SAUB
{ {
/// <summary> /// <summary>
@ -217,5 +218,20 @@ namespace AsbCloudApp.Data.SAUB
/// MSE /// MSE
/// </summary> /// </summary>
public float? Mse { get; set; } public float? Mse { get; set; }
/// <summary>
/// Расход. Буровой насос 1
/// </summary>
public float? Pump0Flow { get; set; }
/// <summary>
/// Расход. Буровой насос 2
/// </summary>
public float? Pump1Flow { get; set; }
/// <summary>
/// Расход. Буровой насос 3
/// </summary>
public float? Pump2Flow { get; set; }
} }
} }

View File

@ -16,7 +16,7 @@ namespace AsbCloudApp.Services
/// <param name="id"></param> /// <param name="id"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<FileCategoryDto> GetOrDefaultAsync(int id, CancellationToken token); Task<FileCategoryDto?> GetOrDefaultAsync(int id, CancellationToken token);
/// <summary> /// <summary>
/// Получение справочника категорий файлов /// Получение справочника категорий файлов

View File

@ -24,7 +24,7 @@ namespace AsbCloudApp.Services
/// <param name="idCategory"></param> /// <param name="idCategory"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<MeasureDto> GetLastAsync(int idWell, int idCategory, CancellationToken token); Task<MeasureDto?> GetLastOrDefaultAsync(int idWell, int idCategory, CancellationToken token);
/// <summary> /// <summary>
/// История измерений по категории /// История измерений по категории

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class UpdateTable_t_telemetry_data_saub : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<float>(
name: "pump0Flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true);
migrationBuilder.AddColumn<float>(
name: "pump1Flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true);
migrationBuilder.AddColumn<float>(
name: "pump2Flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "pump0Flow",
table: "t_telemetry_data_saub");
migrationBuilder.DropColumn(
name: "pump1Flow",
table: "t_telemetry_data_saub");
migrationBuilder.DropColumn(
name: "pump2Flow",
table: "t_telemetry_data_saub");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class EditTable_t_telemetry_data_saub : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "pump2Flow",
table: "t_telemetry_data_saub",
newName: "pump2_flow");
migrationBuilder.RenameColumn(
name: "pump1Flow",
table: "t_telemetry_data_saub",
newName: "pump1_flow");
migrationBuilder.RenameColumn(
name: "pump0Flow",
table: "t_telemetry_data_saub",
newName: "pump0_flow");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "pump2_flow",
table: "t_telemetry_data_saub",
newName: "pump2Flow");
migrationBuilder.RenameColumn(
name: "pump1_flow",
table: "t_telemetry_data_saub",
newName: "pump1Flow");
migrationBuilder.RenameColumn(
name: "pump0_flow",
table: "t_telemetry_data_saub",
newName: "pump0Flow");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class EditCommentTable_t_telemetry_data_saub : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<float>(
name: "pump2_flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true,
comment: "Расход. Буровой насос 3",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true);
migrationBuilder.AlterColumn<float>(
name: "pump1_flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true,
comment: "Расход. Буровой насос 2",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true);
migrationBuilder.AlterColumn<float>(
name: "pump0_flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true,
comment: "Расход. Буровой насос 1",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<float>(
name: "pump2_flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true,
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Расход. Буровой насос 3");
migrationBuilder.AlterColumn<float>(
name: "pump1_flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true,
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Расход. Буровой насос 2");
migrationBuilder.AlterColumn<float>(
name: "pump0_flow",
table: "t_telemetry_data_saub",
type: "real",
nullable: true,
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Расход. Буровой насос 1");
}
}
}

View File

@ -4211,6 +4211,21 @@ namespace AsbCloudDb.Migrations
.HasColumnName("pressure_sp_slide") .HasColumnName("pressure_sp_slide")
.HasComment("Давление. Задание для режима слайда"); .HasComment("Давление. Задание для режима слайда");
b.Property<float?>("Pump0Flow")
.HasColumnType("real")
.HasColumnName("pump0_flow")
.HasComment("Расход. Буровой насос 1");
b.Property<float?>("Pump1Flow")
.HasColumnType("real")
.HasColumnName("pump1_flow")
.HasComment("Расход. Буровой насос 2");
b.Property<float?>("Pump2Flow")
.HasColumnType("real")
.HasColumnName("pump2_flow")
.HasComment("Расход. Буровой насос 3");
b.Property<float?>("RotorSpeed") b.Property<float?>("RotorSpeed")
.HasColumnType("real") .HasColumnType("real")
.HasColumnName("rotor_speed") .HasColumnName("rotor_speed")

View File

@ -125,6 +125,15 @@ namespace AsbCloudDb.Model
[Column("mse"), Comment("MSE")] [Column("mse"), Comment("MSE")]
public float? Mse { get; set; } public float? Mse { get; set; }
[Column("pump0_flow"), Comment("Расход. Буровой насос 1")]
public float? Pump0Flow { get; set; }
[Column("pump1_flow"), Comment("Расход. Буровой насос 2")]
public float? Pump1Flow { get; set; }
[Column("pump2_flow"), Comment("Расход. Буровой насос 3")]
public float? Pump2Flow { get; set; }
[JsonIgnore] [JsonIgnore]
[ForeignKey(nameof(IdTelemetry))] [ForeignKey(nameof(IdTelemetry))]
[InverseProperty(nameof(Model.Telemetry.DataSaub))] [InverseProperty(nameof(Model.Telemetry.DataSaub))]

View File

@ -2,6 +2,7 @@
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
#nullable enable
public static class DateTimeExtentions public static class DateTimeExtentions
{ {
/// <summary> /// <summary>
@ -77,4 +78,5 @@ namespace AsbCloudInfrastructure
return indexOfMiddle; return indexOfMiddle;
} }
} }
#nullable disable
} }

View File

@ -28,6 +28,7 @@ using System;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
#nullable enable
public static class DependencyInjection public static class DependencyInjection
{ {
public static IAsbCloudDbContext MakeContext(string connectionString) public static IAsbCloudDbContext MakeContext(string connectionString)
@ -51,7 +52,7 @@ namespace AsbCloudInfrastructure
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeDto, TimeOnly>() .ForType<TimeDto, TimeOnly>()
.MapWith((source) => source == default ? default : source.MakeTimeOnly()); .MapWith((source) => source.MakeTimeOnly());
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeOnly, TimeDto>() .ForType<TimeOnly, TimeDto>()
@ -61,6 +62,7 @@ namespace AsbCloudInfrastructure
.ForType<TimeOnly, TimeDto>() .ForType<TimeOnly, TimeDto>()
.MapWith((source) => new(source)); .MapWith((source) => new(source));
#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,
@ -70,6 +72,7 @@ namespace AsbCloudInfrastructure
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.
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<ClusterDto, Cluster>() .ForType<ClusterDto, Cluster>()
@ -95,7 +98,7 @@ namespace AsbCloudInfrastructure
services.AddMemoryCache(); services.AddMemoryCache();
services.AddScoped<IAsbCloudDbContext>(provider => provider.GetService<AsbCloudDbContext>()); services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>());
services.AddScoped<IEmailService, EmailService>(); services.AddScoped<IEmailService, EmailService>();
services.AddSingleton(new WitsInfoService()); services.AddSingleton(new WitsInfoService());
@ -143,25 +146,25 @@ namespace AsbCloudInfrastructure
// 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.GetService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetService<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.GetService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetService<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.GetService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetService<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.GetService<IAsbCloudDbContext>(), s.GetRequiredService<IAsbCloudDbContext>(),
s.GetService<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
@ -203,7 +206,7 @@ namespace AsbCloudInfrastructure
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.GetService<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
@ -212,4 +215,5 @@ namespace AsbCloudInfrastructure
.AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider))); .AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider)));
} }
#nullable disable
} }

View File

@ -1,8 +0,0 @@
namespace AsbCloudInfrastructure
{
/// <summary>
/// Тип для поиска этой сборки
/// </summary>
public interface IInfrastructureMarker
{ }
}

View File

@ -8,6 +8,7 @@ using System.Linq;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
#nullable enable
public class ReportDataSourcePgCloud : IReportDataSource public class ReportDataSourcePgCloud : IReportDataSource
{ {
private readonly IAsbCloudDbContext context; private readonly IAsbCloudDbContext context;
@ -37,6 +38,9 @@ namespace AsbCloudInfrastructure
.Include(w => w.Telemetry) .Include(w => w.Telemetry)
.FirstOrDefault(w => w.Id == idWell); .FirstOrDefault(w => w.Id == idWell);
if(well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
idTelemetry = well?.IdTelemetry; idTelemetry = well?.IdTelemetry;
if (idTelemetry is null) if (idTelemetry is null)
throw new ArgumentInvalidException($"Well {idWell} doesn't contain telemetry", nameof(idWell)); throw new ArgumentInvalidException($"Well {idWell} doesn't contain telemetry", nameof(idWell));
@ -49,7 +53,7 @@ namespace AsbCloudInfrastructure
.Where(u => u.IdTelemetry == idTelemetry) .Where(u => u.IdTelemetry == idTelemetry)
.ToDictionary(u => u.IdUser, u => u); .ToDictionary(u => u.IdUser, u => u);
timezoneOffset = well?.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? well.Timezone?.Hours ?? 5.0; timezoneOffset = well!.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? well.Timezone?.Hours ?? 5.0;
info = new WellInfoReport info = new WellInfoReport
{ {
@ -155,4 +159,5 @@ namespace AsbCloudInfrastructure
public WellInfoReport GetWellInfo() public WellInfoReport GetWellInfo()
=> info; => info;
} }
#nullable disable
} }

View File

@ -5,6 +5,7 @@ using System.Linq;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
#nullable enable
public class QueryContainer<TEntity> where TEntity : class, IId public class QueryContainer<TEntity> where TEntity : class, IId
{ {
protected readonly IAsbCloudDbContext dbContext; protected readonly IAsbCloudDbContext dbContext;
@ -25,4 +26,5 @@ namespace AsbCloudInfrastructure.Repository
GetQuery = () => makeQuery(dbSet); GetQuery = () => makeQuery(dbSet);
} }
} }
#nullable disable
} }

View File

@ -11,6 +11,7 @@ using System.Linq;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
#nullable enable
public class SetpointsRequestRepository : CrudWellRelatedCacheRepositoryBase<SetpointsRequestDto, SetpointsRequest> public class SetpointsRequestRepository : CrudWellRelatedCacheRepositoryBase<SetpointsRequestDto, SetpointsRequest>
{ {
private readonly IWellService wellService; private readonly IWellService wellService;
@ -61,4 +62,5 @@ namespace AsbCloudInfrastructure.Repository
return result; return result;
} }
} }
#nullable disable
} }

View File

@ -1,5 +1,4 @@
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -11,6 +10,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
#nullable enable
public class WitsRecordRepository<TDto, TEntity> : IWitsRecordRepository<TDto> public class WitsRecordRepository<TDto, TEntity> : IWitsRecordRepository<TDto>
where TEntity : AsbCloudDb.Model.WITS.RecordBase, ITelemetryData where TEntity : AsbCloudDb.Model.WITS.RecordBase, ITelemetryData
where TDto : AsbCloudApp.Data.ITelemetryData where TDto : AsbCloudApp.Data.ITelemetryData
@ -64,7 +64,10 @@ namespace AsbCloudInfrastructure.Repository
.OrderBy(d => d.DateTime) .OrderBy(d => d.DateTime)
.AsNoTracking(); .AsNoTracking();
var data = await query.LastOrDefaultAsync(token); var data = await query.LastOrDefaultAsync(token);
return new TDto[] { Convert(data, timezoneHours) }; if(data is not null)
return new TDto[] { Convert(data, timezoneHours) };
return Enumerable.Empty<TDto>();
} }
public async Task SaveDataAsync(int idTelemetry, IEnumerable<TDto> dtos, CancellationToken token) public async Task SaveDataAsync(int idTelemetry, IEnumerable<TDto> dtos, CancellationToken token)
@ -128,9 +131,6 @@ namespace AsbCloudInfrastructure.Repository
private static TEntity Convert(TDto dto, int idTelemetry, double timezoneHours) private static TEntity Convert(TDto dto, int idTelemetry, double timezoneHours)
{ {
if (dto is null)
return null;
var entity = dto.Adapt<TEntity>(); var entity = dto.Adapt<TEntity>();
entity.Recid = GetRecId(dto); entity.Recid = GetRecId(dto);
entity.IdTelemetry = idTelemetry; entity.IdTelemetry = idTelemetry;
@ -140,13 +140,11 @@ namespace AsbCloudInfrastructure.Repository
private static TDto Convert(TEntity entity, double timezoneHours) private static TDto Convert(TEntity entity, double timezoneHours)
{ {
if (entity is null)
return default;
var data = entity.Adapt<TDto>(); var data = entity.Adapt<TDto>();
data.DateTime = entity.DateTime.ToRemoteDateTime(timezoneHours); data.DateTime = entity.DateTime.ToRemoteDateTime(timezoneHours);
return data; return data;
} }
} }
#nullable disable
} }

View File

@ -2,10 +2,12 @@
namespace AsbCloudInfrastructure.Services.DailyReport namespace AsbCloudInfrastructure.Services.DailyReport
{ {
#nullable enable
abstract class BlockAbstract abstract class BlockAbstract
{ {
public abstract CellAddress AddressBlockBegin { get; } public abstract CellAddress AddressBlockBegin { get; }
public abstract CellAddress AddressBlockEnd { get; } public abstract CellAddress AddressBlockEnd { get; }
public abstract void Draw(IXLWorksheet sheet); public abstract void Draw(IXLWorksheet sheet);
} }
#nullable disable
} }

View File

@ -3,6 +3,7 @@ using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{ {
#nullable enable
class BhaBlock : BlockAbstract class BhaBlock : BlockAbstract
{ {
private readonly BhaDto blockDto; private readonly BhaDto blockDto;
@ -110,7 +111,8 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
.SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[4], AddressDurationDataFinish[4])}").Style.SetAllBorders(); .SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[4], AddressDurationDataFinish[4])}").Style.SetAllBorders();
} }
} }
#nullable disable
} }

View File

@ -3,12 +3,12 @@ using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{ {
#nullable enable
internal class DimensionlessBlock : BlockAbstract internal class DimensionlessBlock : BlockAbstract
{ {
private readonly NoDrillingDto blockDto; private readonly NoDrillingDto blockDto;
public SaubBlock SaubBlock { get; set; } public SaubBlock SaubBlock { get; set; } = null!;
public CellAddress AddressDimensionTitle { get; } public CellAddress AddressDimensionTitle { get; }
public CellAddress AddressPreparationTitle { get; } public CellAddress AddressPreparationTitle { get; }
@ -19,7 +19,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
public CellAddress[] AddressPreparationValue { get; } public CellAddress[] AddressPreparationValue { get; }
public CellAddress[] AddressExtensionHead { get; } public CellAddress[] AddressExtensionHead { get; }
public CellAddress[] AddressExtensionValue { get; } public CellAddress[] AddressExtensionValue { get; }
public CellAddress AddressBlockFormula { get; } public CellAddress AddressBlockFormula { get; } = null!;
public override CellAddress AddressBlockBegin { get; } public override CellAddress AddressBlockBegin { get; }
public override CellAddress AddressBlockEnd { get; } public override CellAddress AddressBlockEnd { get; }
public DimensionlessBlock(CellAddress addressBlockBegin, NoDrillingDto blockDto) public DimensionlessBlock(CellAddress addressBlockBegin, NoDrillingDto blockDto)
@ -114,6 +114,6 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
._SetValue("Наращивание"); ._SetValue("Наращивание");
} }
} }
#nullable disable
} }

View File

@ -3,7 +3,7 @@ using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{ {
#nullable enable
class HeadBlock : BlockAbstract class HeadBlock : BlockAbstract
{ {
private readonly HeadDto blockDto; private readonly HeadDto blockDto;
@ -175,6 +175,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
._SetValue($"{blockDto.CountLaunchesMSE}"); ._SetValue($"{blockDto.CountLaunchesMSE}");
} }
} }
#nullable disable
} }

View File

@ -3,6 +3,7 @@ using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{ {
#nullable enable
internal class SaubBlock : BlockAbstract internal class SaubBlock : BlockAbstract
{ {
private readonly SaubDto blockDto; private readonly SaubDto blockDto;
@ -224,5 +225,6 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
._SetValue($"Примечание: {blockDto.DeclinesReasonsROP}"); ._SetValue($"Примечание: {blockDto.DeclinesReasonsROP}");
} }
} }
#nullable disable
} }

View File

@ -3,6 +3,7 @@ using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{ {
#nullable enable
internal class SignBlock : BlockAbstract internal class SignBlock : BlockAbstract
{ {
private readonly SignDto blockDto; private readonly SignDto blockDto;
@ -10,7 +11,6 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
public CellAddress AddressDrillMaster { get; } public CellAddress AddressDrillMaster { get; }
public CellAddress AddressSupervisorHead { get; } public CellAddress AddressSupervisorHead { get; }
public CellAddress AddressSupervisor { get; } public CellAddress AddressSupervisor { get; }
public CellAddress[] AddressPeriodTableDataArray { get; }
public override CellAddress AddressBlockBegin { get; } public override CellAddress AddressBlockBegin { get; }
public override CellAddress AddressBlockEnd { get; } public override CellAddress AddressBlockEnd { get; }
@ -45,7 +45,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
.SetValue($"{blockDto.Supervisor}"); .SetValue($"{blockDto.Supervisor}");
} }
} }
#nullable disable
} }

View File

@ -6,9 +6,10 @@ using System.Collections.Generic;
using System.IO; using System.IO;
namespace AsbCloudInfrastructure.Services.DailyReport namespace AsbCloudInfrastructure.Services.DailyReport
{ {
#nullable enable
public class DailyReportMakerExcel public class DailyReportMakerExcel
{ {
private IEnumerable<WellOperationCategoryDto> OperationCategories; private IEnumerable<WellOperationCategoryDto> OperationCategories = null!;
public Stream MakeReportFromBlocks(DailyReportDto dto, IEnumerable<WellOperationCategoryDto> operationCategories) public Stream MakeReportFromBlocks(DailyReportDto dto, IEnumerable<WellOperationCategoryDto> operationCategories)
{ {
@ -55,5 +56,6 @@ namespace AsbCloudInfrastructure.Services.DailyReport
sheet.Rows().AdjustToContents(); sheet.Rows().AdjustToContents();
} }
} }
#nullable disable
} }

View File

@ -3,6 +3,7 @@ using System;
namespace AsbCloudInfrastructure.Services.DailyReport namespace AsbCloudInfrastructure.Services.DailyReport
{ {
#nullable enable
internal static class XLExtentions internal static class XLExtentions
{ {
public static IXLRange _SetValue(this IXLRange range, object value) public static IXLRange _SetValue(this IXLRange range, object value)
@ -156,4 +157,5 @@ namespace AsbCloudInfrastructure.Services.DailyReport
=> sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber); => sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber);
} }
#nullable disable
} }

View File

@ -2,6 +2,7 @@
namespace AsbCloudInfrastructure.Services.DetectOperations namespace AsbCloudInfrastructure.Services.DetectOperations
{ {
#nullable enable
public class DetectableTelemetry public class DetectableTelemetry
{ {
public DateTimeOffset DateTime { get; set; } public DateTimeOffset DateTime { get; set; }
@ -13,4 +14,5 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
public float BitDepth { get; set; } public float BitDepth { get; set; }
public float RotorSpeed { get; set; } public float RotorSpeed { get; set; }
} }
#nullable disable
} }

View File

@ -12,6 +12,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.DetectOperations namespace AsbCloudInfrastructure.Services.DetectOperations
{ {
#nullable enable
internal class DetectedOperationExportService internal class DetectedOperationExportService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
@ -41,7 +42,8 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
return; return;
var wells = idsWells.Select(i => wellService.GetOrDefault(i)) var wells = idsWells.Select(i => wellService.GetOrDefault(i))
.Where(w => w is not null && w.IdTelemetry is not null); .Where(w => w is not null && w.IdTelemetry is not null)
.Select(w => w!);
if (!wells.Any()) if (!wells.Any())
return; return;
@ -114,4 +116,5 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
sheet.Cell(rowNumber, 6).Value = operation.Value; sheet.Cell(rowNumber, 6).Value = operation.Value;
} }
} }
#nullable enable
} }

View File

@ -2,10 +2,12 @@
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
{ {
#nullable enable
class OperationDetectorResult class OperationDetectorResult
{ {
public int TelemetryBegin { get; set; } public int TelemetryBegin { get; set; }
public int TelemetryEnd { get; set; } public int TelemetryEnd { get; set; }
public DetectedOperation Operation { get; set; } public DetectedOperation Operation { get; set; } = null!;
} }
#nullable enable
} }

View File

@ -2,6 +2,7 @@
namespace AsbCloudInfrastructure.Services.DetectOperations namespace AsbCloudInfrastructure.Services.DetectOperations
{ {
#nullable enable
public class InterpolationLine public class InterpolationLine
{ {
private readonly double xSum; private readonly double xSum;
@ -52,4 +53,5 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
public bool IsAverageYGreaterThan(double bound) => public bool IsAverageYGreaterThan(double bound) =>
(ySum / count) >= bound; (ySum / count) >= bound;
} }
#nullable disable
} }

View File

@ -6,6 +6,7 @@ using System.Linq;
namespace AsbCloudInfrastructure.Services.DrillingProgram namespace AsbCloudInfrastructure.Services.DrillingProgram
{ {
#nullable enable
internal class DrillingProgramMaker internal class DrillingProgramMaker
{ {
private const int maxAllowedColumns = 256; private const int maxAllowedColumns = 256;
@ -15,7 +16,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
var resultExcelFile = new XLWorkbook(XLEventTracking.Disabled); var resultExcelFile = new XLWorkbook(XLEventTracking.Disabled);
var titleSheet = resultExcelFile.AddWorksheet("Титульный лист"); var titleSheet = resultExcelFile.AddWorksheet("Титульный лист");
var marks = parts.SelectMany(p => p.File.FileMarks); var marks = parts.SelectMany(p => p.File!.FileMarks);
var titleSheetMaker = new TitleListSheet(marks, well); var titleSheetMaker = new TitleListSheet(marks, well);
titleSheetMaker.Draw(titleSheet); titleSheetMaker.Draw(titleSheet);
@ -128,4 +129,5 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
return rngData; return rngData;
} }
} }
#nullable disable
} }

View File

@ -369,10 +369,13 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{ {
var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token); var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token);
var well = await wellService.GetOrDefaultAsync(file!.IdWell, token); var well = await wellService.GetOrDefaultAsync(file!.IdWell, token);
if (well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(file.IdWell));
var user = file.Author!; var user = file.Author!;
var factory = new DrillingMailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, "Загруженный вами документ полностью согласован"); var subject = factory.MakeSubject(well, "Загруженный вами документ полностью согласован");
var body = factory.MakeMailBodyForPublisherOnFullAccept(well, user.Name, file.Id, file.Name); var body = factory.MakeMailBodyForPublisherOnFullAccept(well, user.Name ?? string.Empty, file.Id, file.Name);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
} }
@ -381,10 +384,13 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{ {
var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token); var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token);
var well = await wellService.GetOrDefaultAsync(file!.IdWell, token); var well = await wellService.GetOrDefaultAsync(file!.IdWell, token);
if (well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(file.IdWell));
var user = file.Author!; var user = file.Author!;
var factory = new DrillingMailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, "Загруженный вами документ отклонен"); var subject = factory.MakeSubject(well, "Загруженный вами документ отклонен");
var body = factory.MakeMailBodyForPublisherOnReject(well, user.Name, file.Id, file.Name, fileMark); var body = factory.MakeMailBodyForPublisherOnReject(well, user.Name ?? string.Empty, file.Id, file.Name, fileMark);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
} }
@ -392,6 +398,9 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
private async Task NotifyApproversAsync(DrillingProgramPart part, int idFile, string fileName, CancellationToken token) private async Task NotifyApproversAsync(DrillingProgramPart part, int idFile, string fileName, CancellationToken token)
{ {
var well = await wellService.GetOrDefaultAsync(part.IdWell, token); var well = await wellService.GetOrDefaultAsync(part.IdWell, token);
if (well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(part.IdWell));
var factory = new DrillingMailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, "Загружен новый документ для согласования."); var subject = factory.MakeSubject(well, "Загружен новый документ для согласования.");
var users = part.RelatedUsers var users = part.RelatedUsers
@ -400,7 +409,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
foreach (var user in users) foreach (var user in users)
{ {
var body = factory.MakeMailBodyForApproverNewFile(well, user.Name, idFile, fileName); var body = factory.MakeMailBodyForApproverNewFile(well, user.Name ?? string.Empty, idFile, fileName);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
} }
} }
@ -408,9 +417,12 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
private async Task NotifyNewPublisherAsync(int idWell, UserDto user, string documentCategory, CancellationToken token) private async Task NotifyNewPublisherAsync(int idWell, UserDto user, string documentCategory, CancellationToken token)
{ {
var well = await wellService.GetOrDefaultAsync(idWell, token); var well = await wellService.GetOrDefaultAsync(idWell, token);
if (well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
var factory = new DrillingMailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, $"От вас ожидается загрузка на портал документа «{documentCategory}»"); var subject = factory.MakeSubject(well, $"От вас ожидается загрузка на портал документа «{documentCategory}»");
var body = factory.MakeMailBodyForNewPublisher(well, user.Name, documentCategory); var body = factory.MakeMailBodyForNewPublisher(well, user.Name ?? string.Empty, documentCategory);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
} }

View File

@ -2,14 +2,16 @@
namespace AsbCloudInfrastructure.Services.DrillingProgram namespace AsbCloudInfrastructure.Services.DrillingProgram
{ {
#nullable enable
class ImageInfo class ImageInfo
{ {
public int Id { get; set; } public int Id { get; set; }
public byte[] Data { get; set; } public byte[] Data { get; set; } = null!;
public int Height { get; set; } public int Height { get; set; }
public int Width { get; set; } public int Width { get; set; }
public IXLAddress TopLeftCellAddress { get; set; } public IXLAddress TopLeftCellAddress { get; set; } = null!;
public int Left { get; set; } public int Left { get; set; }
public int Top { get; set; } public int Top { get; set; }
} }
#nullable disable
} }

View File

@ -1,10 +1,12 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System; using System;
using System.IO; using System.IO;
namespace AsbCloudInfrastructure.Services.Email namespace AsbCloudInfrastructure.Services.Email
{ {
#nullable enable
public class BaseFactory public class BaseFactory
{ {
private readonly string platformName; private readonly string platformName;
@ -20,17 +22,23 @@ namespace AsbCloudInfrastructure.Services.Email
supportMail = configuration.GetValue("email:supportMail", "support@digitaldrilling.ru"); supportMail = configuration.GetValue("email:supportMail", "support@digitaldrilling.ru");
} }
public static string GetImageBase64(string resourceFileName) public static string GetOrEmptyImageBase64(string resourceFileName)
{ {
if (string.IsNullOrEmpty(resourceFileName)) if (string.IsNullOrEmpty(resourceFileName))
return null; throw new ArgumentInvalidException("ResourceFileName doesn`t exist", nameof(resourceFileName));
var baseDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); var baseDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
var resoursesDir = "Res"; ?? string.Empty;
var resourcesDir = "Res";
var logoFilePath = Path.Combine(baseDir, resoursesDir, resourceFileName); var logoFilePath = Path.Combine(baseDir, resourcesDir, resourceFileName);
if(!File.Exists(logoFilePath))
if (!File.Exists(logoFilePath))
{
System.Diagnostics.Trace.TraceWarning($"GetOrEmptyImageBase64(). File {logoFilePath} not found.");
return string.Empty; return string.Empty;
}
var imageBytes = File.ReadAllBytes(logoFilePath); var imageBytes = File.ReadAllBytes(logoFilePath);
var format = Path.GetExtension(resourceFileName).Trim('.'); var format = Path.GetExtension(resourceFileName).Trim('.');
return "data:image/" + format + ";base64," + Convert.ToBase64String(imageBytes); return "data:image/" + format + ";base64," + Convert.ToBase64String(imageBytes);
@ -41,7 +49,7 @@ namespace AsbCloudInfrastructure.Services.Email
public string MakeSignatue() public string MakeSignatue()
{ {
var logo = GetImageBase64("logo_32.png"); var logo = GetOrEmptyImageBase64("logo_32.png");
var sign = $"<br><br>---<br><img src=\"{logo}\"/><br>" + var sign = $"<br><br>---<br><img src=\"{logo}\"/><br>" +
$"{companyName}<br>" + $"{companyName}<br>" +
$"Это письмо сформировано автоматически.<br>" + $"Это письмо сформировано автоматически.<br>" +
@ -53,4 +61,5 @@ namespace AsbCloudInfrastructure.Services.Email
public virtual string MakeSubject(WellDto well, string action) public virtual string MakeSubject(WellDto well, string action)
=> $"{well.Deposit}, {well.Cluster}, {well.Caption}. {action}"; => $"{well.Deposit}, {well.Cluster}, {well.Caption}. {action}";
} }
#nullable disable
} }

View File

@ -6,7 +6,8 @@ using System.IO;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
class DrillingMailBodyFactory : BaseFactory #nullable enable
class DrillingMailBodyFactory : BaseFactory
{ {
private readonly string platformName; private readonly string platformName;
private readonly string platformUrl; private readonly string platformUrl;
@ -84,4 +85,5 @@ namespace AsbCloudInfrastructure
return drillingProgramHref; return drillingProgramHref;
} }
} }
#nullable disable
} }

View File

@ -6,7 +6,8 @@ using System.IO;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
class WellFinalDocumentMailBodyFactory : BaseFactory #nullable enable
class WellFinalDocumentMailBodyFactory : BaseFactory
{ {
private readonly string platformName; private readonly string platformName;
@ -29,4 +30,5 @@ namespace AsbCloudInfrastructure
return body; return body;
} }
} }
#nullable disable
} }

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
#nullable enable
public class FileCategoryService : CrudCacheRepositoryBase<FileCategoryDto, FileCategory>, IFileCategoryService public class FileCategoryService : CrudCacheRepositoryBase<FileCategoryDto, FileCategory>, IFileCategoryService
{ {
public FileCategoryService(IAsbCloudDbContext context, IMemoryCache memoryCache) public FileCategoryService(IAsbCloudDbContext context, IMemoryCache memoryCache)
@ -28,4 +29,5 @@ namespace AsbCloudInfrastructure.Services
return dtos; return dtos;
} }
} }
#nullable disable
} }

View File

@ -1,8 +0,0 @@
namespace AsbCloudInfrastructure.Services
{
public interface IConverter<TDto, TModel>
{
TModel Convert(TDto src);
TDto Convert(TModel src);
}
}

View File

@ -13,6 +13,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
#nullable enable
public class MeasureService : IMeasureService public class MeasureService : IMeasureService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
@ -40,7 +41,7 @@ namespace AsbCloudInfrastructure.Services
return cache; return cache;
} }
public async Task<MeasureDto> GetLastAsync(int idWell, int idCategory, CancellationToken token) public async Task<MeasureDto?> GetLastOrDefaultAsync(int idWell, int idCategory, CancellationToken token)
{ {
var query = db.Measures var query = db.Measures
.Include(m => m.Category) .Include(m => m.Category)
@ -54,8 +55,11 @@ namespace AsbCloudInfrastructure.Services
.ConfigureAwait(false); .ConfigureAwait(false);
var timezone = wellService.GetTimezone(idWell); var timezone = wellService.GetTimezone(idWell);
var dto = Convert(entity, timezone.Hours);
return dto; if (entity is null)
return null;
return Convert(entity, timezone.Hours);
} }
public async Task<IEnumerable<MeasureDto>> GetHisoryAsync(int idWell, int? idCategory = null, CancellationToken token = default) public async Task<IEnumerable<MeasureDto>> GetHisoryAsync(int idWell, int? idCategory = null, CancellationToken token = default)
@ -124,6 +128,9 @@ namespace AsbCloudInfrastructure.Services
.FirstOrDefaultAsync(token) .FirstOrDefaultAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
if (entity is null)
throw new ArgumentInvalidException($"Measure doesn't exist", nameof(idWell));
entity.IsDeleted = true; entity.IsDeleted = true;
return await db.SaveChangesAsync(token).ConfigureAwait(false); return await db.SaveChangesAsync(token).ConfigureAwait(false);
@ -140,16 +147,16 @@ namespace AsbCloudInfrastructure.Services
private MeasureDto Convert(Measure entity, double hours) private MeasureDto Convert(Measure entity, double hours)
{ {
var dto = entity.Adapt<MeasureDto>(); var dto = entity.Adapt<MeasureDto>();
dto.CategoryName = entity.Category?.Name; dto.CategoryName = entity.Category?.Name ?? String.Empty;
dto.Timestamp = entity.Timestamp.ToRemoteDateTime(hours); dto.Timestamp = entity.Timestamp.ToRemoteDateTime(hours);
return dto; return dto;
} }
private Measure Convert(MeasureDto dto, double hours) private Measure Convert(MeasureDto dto, double hours)
{ {
var entity = dto.Adapt<Measure>(); var entity = dto.Adapt<Measure>();
entity.Category = null;
entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(hours); entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(hours);
return entity; return entity;
} }
} }
#nullable disable
} }

View File

@ -6,7 +6,6 @@ using AsbCloudApp.Services;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -5,6 +5,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap;
internal static class XLExtentions internal static class XLExtentions
{ {
#nullable enable
public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false) public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false)
{ {
cell.Value = value; cell.Value = value;
@ -47,4 +48,5 @@ internal static class XLExtentions
cell.Style.NumberFormat.Format = format; cell.Style.NumberFormat.Format = format;
return cell; return cell;
} }
#nullable disable
} }

View File

@ -1,5 +1,4 @@
using DocumentFormat.OpenXml.Drawing.Diagrams; using System.Collections.Generic;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.SAUB namespace AsbCloudInfrastructure.Services.SAUB
{ {
#nullable enable
public class EventService : IEventService public class EventService : IEventService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
@ -42,4 +43,5 @@ namespace AsbCloudInfrastructure.Services.SAUB
memoryCache.DropBasic<TelemetryEvent>(); memoryCache.DropBasic<TelemetryEvent>();
} }
} }
#nullable disable
} }

View File

@ -113,4 +113,5 @@ namespace AsbCloudInfrastructure.Services.SAUB
public IEnumerable<SetpointInfoDto> GetSetpointsNames() public IEnumerable<SetpointInfoDto> GetSetpointsNames()
=> SetpointInfos.Values; => SetpointInfos.Values;
} }
#nullable disable
} }

View File

@ -5,6 +5,7 @@ using Mapster;
namespace AsbCloudInfrastructure.Services.SAUB namespace AsbCloudInfrastructure.Services.SAUB
{ {
#nullable enable
public class TelemetryDataSpinService : TelemetryDataBaseService<TelemetryDataSpinDto, TelemetryDataSpin> public class TelemetryDataSpinService : TelemetryDataBaseService<TelemetryDataSpinDto, TelemetryDataSpin>
{ {
public TelemetryDataSpinService( public TelemetryDataSpinService(
@ -28,4 +29,5 @@ namespace AsbCloudInfrastructure.Services.SAUB
return dto; return dto;
} }
} }
#nullable disable
} }

View File

@ -12,13 +12,14 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.SAUB namespace AsbCloudInfrastructure.Services.SAUB
{ {
#nullable enable
public class TelemetryTracker : ITelemetryTracker public class TelemetryTracker : ITelemetryTracker
{ {
class TrackerStat class TrackerStat
{ {
//public int Id { get; set; } //public int Id { get; set; }
public string RemoteUid { get; set; } public string RemoteUid { get; set; } = null!;
/// <summary> /// <summary>
/// Время последнего запроса (по времени сервера) /// Время последнего запроса (по времени сервера)
@ -88,10 +89,14 @@ namespace AsbCloudInfrastructure.Services.SAUB
foreach (var oldReq in oldRequests) foreach (var oldReq in oldRequests)
{ {
var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid }); if (oldReq.Uid is not null)
telemetryStat.TelemetryDateUtcMin = oldReq.DateMin; {
telemetryStat.TelemetryDateUtcMax = oldReq.DateMax; var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid });
telemetryStat.LastTimeServer = oldReq.DateMax; telemetryStat.TelemetryDateUtcMin = oldReq.DateMin;
telemetryStat.TelemetryDateUtcMax = oldReq.DateMax;
telemetryStat.LastTimeServer = oldReq.DateMax;
}
} }
}).ContinueWith((t) => }).ContinueWith((t) =>
{ {
@ -147,4 +152,5 @@ namespace AsbCloudInfrastructure.Services.SAUB
public IEnumerable<string> GetTransmittingTelemetriesUids() => public IEnumerable<string> GetTransmittingTelemetriesUids() =>
telemetriesStats.Keys; telemetriesStats.Keys;
} }
#nullable disable
} }

View File

@ -54,4 +54,5 @@ namespace AsbCloudInfrastructure.Services.Trajectory
return cartesianCoordinates; return cartesianCoordinates;
} }
} }
#nullable disable
} }

View File

@ -125,18 +125,30 @@ namespace AsbCloudInfrastructure.Services
{ {
var category = await fileCategoryService.GetOrDefaultAsync(item.IdCategory, token); var category = await fileCategoryService.GetOrDefaultAsync(item.IdCategory, token);
var well = await wellService.GetOrDefaultAsync(item.IdWell, token); var well = await wellService.GetOrDefaultAsync(item.IdWell, token);
if(well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(item.IdWell));
SendMessage(well, user, category.Name, message); SendMessage(well, user, category?.Name ?? string.Empty, message);
} }
} }
} }
private void SendMessage(WellDto? well, UserDto user, string documentCategory, string message) private void SendMessage(WellDto well, UserDto user, string documentCategory, string message)
{ {
var factory = new WellFinalDocumentMailBodyFactory(configuration); var factory = new WellFinalDocumentMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, documentCategory); var subject = factory.MakeSubject(well, documentCategory);
var body = factory.MakeMailBodyForWellFinalDocument(well, user.Name ?? user.Surname, string.Format(message, documentCategory));
emailService.EnqueueSend(user.Email, subject, body); if(!string.IsNullOrEmpty(user.Email))
{
var body = factory.MakeMailBodyForWellFinalDocument(
well,
(user.Name ?? user.Surname ?? string.Empty),
string.Format(message, documentCategory)
);
emailService.EnqueueSend(user.Email, subject, body);
}
} }
} }
#nullable disable #nullable disable

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using ClosedXML.Excel; using ClosedXML.Excel;
@ -11,6 +12,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.WellOperationService namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
#nullable enable
public class ScheduleReportService : IScheduleReportService public class ScheduleReportService : IScheduleReportService
{ {
private readonly IOperationsStatService operationsStatService; private readonly IOperationsStatService operationsStatService;
@ -29,11 +31,11 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
var tvd = await operationsStatService.GetTvdAsync(idWell, token); var tvd = await operationsStatService.GetTvdAsync(idWell, token);
if (!tvd.Any())
return null;
var well = await wellService.GetOrDefaultAsync(idWell, token); var well = await wellService.GetOrDefaultAsync(idWell, token);
if(well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
var ecxelTemplateStream = GetExcelTemplateStream(); var ecxelTemplateStream = GetExcelTemplateStream();
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
FillScheduleSheetToWorkbook(workbook, tvd, well); FillScheduleSheetToWorkbook(workbook, tvd, well);
@ -80,7 +82,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
var tvdList = tvd.ToList(); var tvdList = tvd.ToList();
var facts = tvd var facts = tvd
.Where(t => t.Fact is not null) .Where(t => t.Fact is not null)
.Select(t => t.Fact) .Select(t => t.Fact!)
.ToList(); .ToList();
DateTime lastFactDate = default; DateTime lastFactDate = default;
@ -236,9 +238,9 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
? operation.DateStart.AddHours(operation.DurationHours) ? operation.DateStart.AddHours(operation.DurationHours)
: default; : default;
var endDatePlan = GetEndDate(planLast); var endDatePlan = planLast is not null ? GetEndDate(planLast) : default;
var endDateFact = GetEndDate(factLast); var endDateFact = factLast is not null ? GetEndDate(factLast) : default;
var endDatePredict = GetEndDate(predictLast); var endDatePredict = predictLast is not null ? GetEndDate(predictLast) : default;
var endDate = endDatePredict > endDateFact var endDate = endDatePredict > endDateFact
? endDatePredict ? endDatePredict
@ -301,7 +303,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return cell; return cell;
} }
private static IXLCell SetCell(IXLRow row, int colunm, object value) private static IXLCell SetCell(IXLRow row, int colunm, object? value)
{ {
var cell = row.Cell(colunm); var cell = row.Cell(colunm);
cell.Value = value; cell.Value = value;
@ -330,8 +332,9 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
private static Stream GetExcelTemplateStream() private static Stream GetExcelTemplateStream()
{ {
var stream = System.Reflection.Assembly.GetExecutingAssembly() var stream = System.Reflection.Assembly.GetExecutingAssembly()
.GetManifestResourceStream("AsbCloudInfrastructure.Services.WellOperationService.ScheduleReportTemplate.xlsx"); .GetManifestResourceStream("AsbCloudInfrastructure.Services.WellOperationService.ScheduleReportTemplate.xlsx")!;
return stream; return stream;
} }
} }
#nullable disable
} }

View File

@ -11,6 +11,7 @@ using System.Linq;
namespace AsbCloudInfrastructure.Services.WellOperationService namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
#nullable enable
/* /*
* password for WellOperationImportTemplate.xlsx is ASB2020! * password for WellOperationImportTemplate.xlsx is ASB2020!
*/ */
@ -36,7 +37,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly IWellService wellService; private readonly IWellService wellService;
private List<WellOperationCategory> categories = null; private List<WellOperationCategory> categories = null!;
public List<WellOperationCategory> Categories public List<WellOperationCategory> Categories
{ {
get get
@ -52,7 +53,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
} }
} }
private List<WellSectionType> sections = null; private List<WellSectionType> sections = null!;
public List<WellSectionType> Sections public List<WellSectionType> Sections
{ {
get get
@ -92,9 +93,6 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
.AsNoTracking() .AsNoTracking()
.ToList(); .ToList();
if (!operations.Any())
return null;
var timezone = wellService.GetTimezone(idWell); var timezone = wellService.GetTimezone(idWell);
return MakeExelFileStream(operations, timezone.Hours); return MakeExelFileStream(operations, timezone.Hours);
@ -102,8 +100,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
public Stream GetExcelTemplateStream() public Stream GetExcelTemplateStream()
{ {
var resourceName = System.Reflection.Assembly.GetExecutingAssembly()
.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith("WellOperationImportTemplate.xlsx"))!;
var stream = System.Reflection.Assembly.GetExecutingAssembly() var stream = System.Reflection.Assembly.GetExecutingAssembly()
.GetManifestResourceStream("AsbCloudInfrastructure.Services.WellOperationService.WellOperationImportTemplate.xlsx"); .GetManifestResourceStream(resourceName)!;
return stream; return stream;
} }
@ -126,14 +128,16 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
if (planOperations.Any()) if (planOperations.Any())
{ {
var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan); var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan);
AddOperationsToSheet(sheetPlan, planOperations, timezoneOffset); if (sheetPlan is not null)
AddOperationsToSheet(sheetPlan, planOperations, timezoneOffset);
} }
var factOperations = operations.Where(o => o.IdType == 1); var factOperations = operations.Where(o => o.IdType == 1);
if (factOperations.Any()) if (factOperations.Any())
{ {
var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameFact); var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameFact);
AddOperationsToSheet(sheetFact, factOperations, timezoneOffset); if (sheetFact is not null)
AddOperationsToSheet(sheetFact, factOperations, timezoneOffset);
} }
} }
@ -328,4 +332,5 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return operation; return operation;
} }
} }
#nullable disable
} }

View File

@ -13,6 +13,7 @@ using AsbCloudInfrastructure.Background;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
#nullable enable
public class Startup public class Startup
{ {
public static void BeforeRunHandler(IHost host) public static void BeforeRunHandler(IHost host)
@ -20,7 +21,7 @@ namespace AsbCloudInfrastructure
using var scope = host.Services.CreateScope(); using var scope = host.Services.CreateScope();
var provider = scope.ServiceProvider; var provider = scope.ServiceProvider;
var context = provider.GetService<IAsbCloudDbContext>(); var context = provider.GetRequiredService<IAsbCloudDbContext>();
context.Database.SetCommandTimeout(TimeSpan.FromSeconds(2 * 60)); context.Database.SetCommandTimeout(TimeSpan.FromSeconds(2 * 60));
context.Database.Migrate(); context.Database.Migrate();
@ -70,4 +71,5 @@ namespace AsbCloudInfrastructure
return bytes.ToString("### ### ###"); return bytes.ToString("### ### ###");
} }
} }
#nullable disable
} }

View File

@ -44,7 +44,7 @@ namespace AsbCloudWebApi.Controllers
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
var result = await measureService.GetLastAsync(idWell, idCategory, token).ConfigureAwait(false); var result = await measureService.GetLastOrDefaultAsync(idWell, idCategory, token).ConfigureAwait(false);
return Ok(result); return Ok(result);
} }

View File

@ -366,7 +366,10 @@ namespace AsbCloudWebApi
.Add(36, nameof(TelemetryDataSaubDto.FlowDeltaLimitMax)) .Add(36, nameof(TelemetryDataSaubDto.FlowDeltaLimitMax))
.Add(37, nameof(TelemetryDataSaubDto.IdFeedRegulator)) .Add(37, nameof(TelemetryDataSaubDto.IdFeedRegulator))
.Add(38, nameof(TelemetryDataSaubDto.MseState)) .Add(38, nameof(TelemetryDataSaubDto.MseState))
.Add(39, nameof(TelemetryDataSaubDto.Mse)); .Add(39, nameof(TelemetryDataSaubDto.Mse))
.Add(40, nameof(TelemetryDataSaubDto.Pump0Flow))
.Add(41, nameof(TelemetryDataSaubDto.Pump1Flow))
.Add(42, nameof(TelemetryDataSaubDto.Pump2Flow));
} }
} }
} }

View File

@ -0,0 +1,61 @@
@baseUrl = http://127.0.0.1:5000
@contentType = application/json
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2NjI1NDgxNjIsImV4cCI6MTY5NDEwNTc2MiwiaXNzIjoiYSIsImF1ZCI6ImEifQ.OEAlNzxi7Jat6pzDBTAjTbChskc-tdJthJexyWwwUKE
@uid = 20210917_165407777
# https://marketplace.visualstudio.com/items?itemName=humao.rest-client
###
POST {{baseUrl}}/api/TelemetryDataSaub/{{uid}}
Content-Type: {{contentType}}
accept: */*
Authorization: {{auth}}
[
{
"idTelemetry": 8,
"dateTime": "2022-07-18T14:53:17",
"mode": 10,
"user": null,
"wellDepth": 0,
"bitDepth": 0,
"blockPosition": 5,
"blockPositionMin": 1.5,
"blockPositionMax": 0,
"blockSpeed": 0,
"blockSpeedSp": 50,
"blockSpeedSpRotor": 100,
"blockSpeedSpSlide": 50,
"blockSpeedSpDevelop": 100,
"pressure": 0,
"pressureIdle": 0,
"pressureSp": 18,
"pressureSpRotor": 28,
"pressureSpSlide": 18,
"pressureSpDevelop": 15,
"pressureDeltaLimitMax": 50,
"axialLoad": 0,
"axialLoadSp": 8,
"axialLoadLimitMax": 15,
"hookWeight": 0,
"hookWeightIdle": 0,
"hookWeightLimitMin": 0,
"hookWeightLimitMax": 0,
"rotorTorque": 0,
"rotorTorqueIdle": 0,
"rotorTorqueSp": 20,
"rotorTorqueLimitMax": 32,
"rotorSpeed": 0,
"flow": 0,
"flowIdle": 0,
"flowDeltaLimitMax": 3,
"idFeedRegulator": 0,
"mseState": 32,
"mse": 0,
"pump0Flow": 213.12,
"pump1Flow": 234.33,
"pump2Flow": 215.36,
"date": "2022-07-18T14:53:17"
}
]