Process map some nit refactoring

This commit is contained in:
ngfrolov 2023-10-17 10:20:27 +05:00
parent 278913b9be
commit fb307ccceb
Signed by untrusted user who does not match committer: ng.frolov
GPG Key ID: E99907A0357B29A7
13 changed files with 203 additions and 204 deletions

View File

@ -62,11 +62,6 @@ public class ProcessMapPlanWellReamDto : ProcessMapPlanBaseDto, IValidatableObje
[Range(0, 99999.9, ErrorMessage = "Крутящий момент должен быть в пределах от 0 до 99999.9")] [Range(0, 99999.9, ErrorMessage = "Крутящий момент должен быть в пределах от 0 до 99999.9")]
public double Torque { get; set; } public double Torque { get; set; }
/// <summary>
/// Комментарий
/// </summary>
public string? Comment { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{ {

View File

@ -37,8 +37,8 @@
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" /> <EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" /> <EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" /> <EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
<EmbeddedResource Include="Services\ProcessMaps\Files\DrillingProcessMapReportTemplate.xlsx" /> <EmbeddedResource Include="Services\ProcessMaps\Report\ProcessMapReportTemplate.xlsx" />
<EmbeddedResource Include="Services\ProcessMaps\Files\DrillingProcessMapTemplate.xlsx" /> <EmbeddedResource Include="Services\ProcessMaps\WellDrilling\ProcessMapPlanImportWellDrillingTemplate.xlsx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -24,8 +24,8 @@ 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.ProcessMaps.WellDrillingProcessMap; using AsbCloudInfrastructure.Services.ProcessMaps.Report;
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap.Report; using AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.SAUB; using AsbCloudInfrastructure.Services.SAUB;
using AsbCloudInfrastructure.Services.Subsystems; using AsbCloudInfrastructure.Services.Subsystems;
using AsbCloudInfrastructure.Services.Trajectory; using AsbCloudInfrastructure.Services.Trajectory;
@ -197,7 +197,7 @@ namespace AsbCloudInfrastructure
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, ProcessMapPlanWellDrillingImportService>(); services.AddTransient<IProcessMapPlanImportService, ProcessMapPlanImportWellDrillingService>();
services.AddTransient<WellInfoService>(); services.AddTransient<WellInfoService>();
services.AddTransient<IHelpPageService, HelpPageService>(); services.AddTransient<IHelpPageService, HelpPageService>();

View File

@ -15,7 +15,7 @@ namespace AsbCloudInfrastructure.Repository
{ {
protected readonly IMemoryCache memoryCache; protected readonly IMemoryCache memoryCache;
protected string CacheTag = typeof(TEntity).Name; protected string CacheTag = typeof(TEntity).Name;
protected TimeSpan CacheOlescence = TimeSpan.FromMinutes(5); protected TimeSpan CacheObsolescence = TimeSpan.FromMinutes(5);
public CacheBase(IAsbCloudDbContext context, IMemoryCache memoryCache) public CacheBase(IAsbCloudDbContext context, IMemoryCache memoryCache)
: base(context) : base(context)
@ -36,8 +36,8 @@ namespace AsbCloudInfrastructure.Repository
{ {
var cache = memoryCache.GetOrCreate(CacheTag, cacheEntry => var cache = memoryCache.GetOrCreate(CacheTag, cacheEntry =>
{ {
cacheEntry.AbsoluteExpirationRelativeToNow = CacheOlescence; cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence;
cacheEntry.SlidingExpiration = CacheOlescence; cacheEntry.SlidingExpiration = CacheObsolescence;
var entities = this.GetQuery().ToArray(); var entities = this.GetQuery().ToArray();
cacheEntry.Value = entities; cacheEntry.Value = entities;
@ -50,8 +50,8 @@ namespace AsbCloudInfrastructure.Repository
{ {
var cache = memoryCache.GetOrCreateAsync(CacheTag, async (cacheEntry) => var cache = memoryCache.GetOrCreateAsync(CacheTag, async (cacheEntry) =>
{ {
cacheEntry.AbsoluteExpirationRelativeToNow = CacheOlescence; cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence;
cacheEntry.SlidingExpiration = CacheOlescence; cacheEntry.SlidingExpiration = CacheObsolescence;
var entities = await this.GetQuery().ToArrayAsync(token); var entities = await this.GetQuery().ToArrayAsync(token);
cacheEntry.Value = entities; cacheEntry.Value = entities;

View File

@ -0,0 +1,110 @@
using System;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Data.SAUB;
namespace AsbCloudInfrastructure.Services.ProcessMaps.Report.Data;
internal class ParamStat
{
private double spWSum;
private double pvWSum;
private double limitMaxWSum;
private double deltaDepthSum;
private readonly Func<TelemetryDataSaubStatDto, double> getterSp;
private readonly Func<TelemetryDataSaubStatDto, double> getterPv;
private readonly Func<TelemetryDataSaubStatDto, double>? getterLimitMax;
private readonly int idFeedRegulator;
private readonly int idMode;
private TelemetryDataSaubStatDto? previous;
public double SpUsageDepth { get; private set; }
private static double spUsageTotal;
public ParamStat(Func<TelemetryDataSaubStatDto, double> getterSp,
Func<TelemetryDataSaubStatDto, double> getterPv,
Func<TelemetryDataSaubStatDto, double>? getterLimitMax,
int idFeedRegulator,
int idMode)
{
this.getterSp = getterSp;
this.getterPv = getterPv;
this.getterLimitMax = getterLimitMax;
this.idFeedRegulator = idFeedRegulator;
this.idMode = idMode;
spUsageTotal = 0d;
}
public void UpdateStat(TelemetryDataSaubStatDto current)
{
if (previous is not null)
{
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
if (deltaDepth > 0)
{
var deltaDepthHalf = deltaDepth / 2;
double CalculateWeight(Func<TelemetryDataSaubStatDto, double> getter) =>
(getter(previous!) + getter(current)) * deltaDepthHalf;
spWSum += CalculateWeight(getterSp);
pvWSum += CalculateWeight(getterPv);
if (getterLimitMax is not null)
limitMaxWSum += CalculateWeight(getterLimitMax!);
if (current.IdFeedRegulator is not null)
if (current.IdFeedRegulator == idFeedRegulator)
{
SpUsageDepth += deltaDepth;
spUsageTotal += deltaDepth;
}
else
{
var pvErr = (getterSp(current) - getterPv(current)) / getterSp(current);
if (pvErr < 0.03d) //3%
{
SpUsageDepth += deltaDepth;
spUsageTotal += deltaDepth;
}
}
deltaDepthSum += deltaDepth;
}
}
previous = current;
}
public ProcessMapReportWellDrillingParamsDto MakeParams(double? spPlan)
{
var result = new ProcessMapReportWellDrillingParamsDto
{
SetpointPlan = spPlan,
Fact = DivideValByDepth(pvWSum),
};
if (idMode == 0)
{
result.SetpointFact = null;
result.Limit = null;
result.SetpointUsage = null;
}
else
{
result.SetpointFact = DivideValByDepth(spWSum);
result.Limit = getterLimitMax is not null ? DivideValByDepth(limitMaxWSum) : null;
result.SetpointUsage = deltaDepthSum > 0d ? 100d * SpUsageDepth / spUsageTotal : null;
}
return result;
}
private double? DivideValByDepth(double? val)
{
if (val is null || val == 0d || deltaDepthSum == 0d)
return null;
return val / deltaDepthSum;
}
}

View File

@ -1,8 +1,7 @@
using System; using System;
using AsbCloudApp.Data.SAUB; using AsbCloudApp.Data.SAUB;
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling.Report.Data;
namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap.Report.Data; namespace AsbCloudInfrastructure.Services.ProcessMaps.Report.Data;
internal class TelemetryStat internal class TelemetryStat
{ {
@ -24,7 +23,7 @@ internal class TelemetryStat
public float DeltaDepth { get; } public float DeltaDepth { get; }
public int IdMode { get; } public int IdMode { get; }
public string ModeName { get; } public string ModeName { get; }
public double MechDrillingHours { get; } public double DrillingHours { get; }
public TelemetryStat(Span<TelemetryDataSaubStatDto> telemetry) public TelemetryStat(Span<TelemetryDataSaubStatDto> telemetry)
{ {
@ -35,7 +34,7 @@ internal class TelemetryStat
ModeName = GetModeName(IdMode); ModeName = GetModeName(IdMode);
DateStart = telemetryFirst.DateMin; DateStart = telemetryFirst.DateMin;
DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin; DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin;
MechDrillingHours = (telemetryLast.DateMax - telemetryFirst.DateMin).TotalHours; DrillingHours = (telemetryLast.DateMax - telemetryFirst.DateMin).TotalHours;
BlockSpeed = new(t => t.BlockSpeedSp, t => t.BlockSpeed, null, 1, IdMode); BlockSpeed = new(t => t.BlockSpeedSp, t => t.BlockSpeed, null, 1, IdMode);
Pressure = new(t => t.PressureSpDelta, t => t.PressureDelta, t => t.PressureDeltaLimitMax, 2, IdMode); Pressure = new(t => t.PressureSpDelta, t => t.PressureDelta, t => t.PressureDeltaLimitMax, 2, IdMode);

View File

@ -9,7 +9,7 @@ using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling; using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using ClosedXML.Excel; using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap.Report; namespace AsbCloudInfrastructure.Services.ProcessMaps.Report;
public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDrillingExportService public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDrillingExportService
{ {
@ -208,8 +208,8 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
{ {
var stream = Assembly.GetExecutingAssembly() var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream( .GetManifestResourceStream(
"AsbCloudInfrastructure.Services.ProcessMaps.Files.DrillingProcessMapReportTemplate.xlsx"); "AsbCloudInfrastructure.Services.ProcessMaps.Report.ProcessMapReportTemplate.xlsx");
return stream!; return stream!;
} }

View File

@ -10,9 +10,9 @@ using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling; using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap.Report.Data; using AsbCloudInfrastructure.Services.ProcessMaps.Report.Data;
namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap.Report; namespace AsbCloudInfrastructure.Services.ProcessMaps.Report;
public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrillingService public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrillingService
{ {
@ -22,7 +22,7 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling
private readonly IWellOperationRepository wellOperationRepository; private readonly IWellOperationRepository wellOperationRepository;
public ProcessMapReportWellDrillingService(IWellService wellService, public ProcessMapReportWellDrillingService(IWellService wellService,
IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository, IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository,
ITelemetryDataSaubService telemetryDataSaubService, ITelemetryDataSaubService telemetryDataSaubService,
IWellOperationRepository wellOperationRepository) IWellOperationRepository wellOperationRepository)
{ {
@ -178,7 +178,7 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling
DepthEnd = subInterval.DepthEnd, DepthEnd = subInterval.DepthEnd,
DateStart = telemetryStat.DateStart, DateStart = telemetryStat.DateStart,
MechDrillingHours = telemetryStat.MechDrillingHours, MechDrillingHours = telemetryStat.DrillingHours,
DrillingMode = telemetryStat.ModeName, DrillingMode = telemetryStat.ModeName,
DeltaDepth = telemetryStat.DeltaDepth, DeltaDepth = telemetryStat.DeltaDepth,

View File

@ -13,12 +13,12 @@ using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps; using AsbCloudApp.Services.ProcessMaps;
using ClosedXML.Excel; using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap; namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling;
/* /*
* password for ProcessMapImportTemplate.xlsx is ASB2020! * password for ProcessMapImportTemplate.xlsx is ASB2020!
*/ */
public class ProcessMapPlanWellDrillingImportService : IProcessMapPlanImportService public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportService
{ {
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository; private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository;
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository; private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
@ -49,7 +49,7 @@ public class ProcessMapPlanWellDrillingImportService : IProcessMapPlanImportServ
private WellSectionTypeDto[] sections = null!; private WellSectionTypeDto[] sections = null!;
public ProcessMapPlanWellDrillingImportService(IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository, public ProcessMapPlanImportWellDrillingService(IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository,
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository, ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
IWellService wellService) IWellService wellService)
{ {
@ -100,7 +100,7 @@ public class ProcessMapPlanWellDrillingImportService : IProcessMapPlanImportServ
{ {
var resourceName = Assembly.GetExecutingAssembly() var resourceName = Assembly.GetExecutingAssembly()
.GetManifestResourceNames() .GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith("DrillingProcessMapTemplate.xlsx"))!; .FirstOrDefault(n => n.EndsWith("ProcessMapPlanImportWellDrillingTemplate.xlsx"))!;
using var stream = Assembly.GetExecutingAssembly() using var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName)!; .GetManifestResourceStream(resourceName)!;
@ -225,6 +225,10 @@ public class ProcessMapPlanWellDrillingImportService : IProcessMapPlanImportServ
?? throw new FileFormatException( ?? throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная секция"); $"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная секция");
if(string.IsNullOrEmpty(modeName))
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} не указан режим");
var idMode = GetIdMode(modeName) var idMode = GetIdMode(modeName)
?? throw new FileFormatException( ?? throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректный режим"); $"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректный режим");

View File

@ -1,110 +0,0 @@
using System;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Data.SAUB;
namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling.Report.Data;
internal class ParamStat
{
private double spWSum;
private double pvWSum;
private double limitMaxWSum;
private double deltaDepthSum;
private readonly Func<TelemetryDataSaubStatDto, double> getterSp;
private readonly Func<TelemetryDataSaubStatDto, double> getterPv;
private readonly Func<TelemetryDataSaubStatDto, double>? getterLimitMax;
private readonly int idFeedRegulator;
private readonly int idMode;
private TelemetryDataSaubStatDto? previous;
public double SpUsageDepth { get; private set; }
private static double spUsageTotal;
public ParamStat(Func<TelemetryDataSaubStatDto, double> getterSp,
Func<TelemetryDataSaubStatDto, double> getterPv,
Func<TelemetryDataSaubStatDto, double>? getterLimitMax,
int idFeedRegulator,
int idMode)
{
this.getterSp = getterSp;
this.getterPv = getterPv;
this.getterLimitMax = getterLimitMax;
this.idFeedRegulator = idFeedRegulator;
this.idMode = idMode;
spUsageTotal = 0d;
}
public void UpdateStat(TelemetryDataSaubStatDto current)
{
if (previous is not null)
{
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
if (deltaDepth > 0)
{
var deltaDepthHalf = deltaDepth / 2;
double CalculateWeight(Func<TelemetryDataSaubStatDto, double> getter) =>
(getter(previous!) + getter(current)) * deltaDepthHalf;
spWSum += CalculateWeight(getterSp);
pvWSum += CalculateWeight(getterPv);
if (getterLimitMax is not null)
limitMaxWSum += CalculateWeight(getterLimitMax!);
if (current.IdFeedRegulator is not null)
if (current.IdFeedRegulator == idFeedRegulator)
{
SpUsageDepth += deltaDepth;
spUsageTotal += deltaDepth;
}
else
{
var pvErr = (getterSp(current) - getterPv(current)) / getterSp(current);
if (pvErr < 0.03d) //3%
{
SpUsageDepth += deltaDepth;
spUsageTotal += deltaDepth;
}
}
deltaDepthSum += deltaDepth;
}
}
previous = current;
}
public ProcessMapReportWellDrillingParamsDto MakeParams(double? spPlan)
{
var result = new ProcessMapReportWellDrillingParamsDto
{
SetpointPlan = spPlan,
Fact = DivideValByDepth(pvWSum),
};
if (idMode == 0)
{
result.SetpointFact = null;
result.Limit = null;
result.SetpointUsage = null;
}
else
{
result.SetpointFact = DivideValByDepth(spWSum);
result.Limit = getterLimitMax is not null ? DivideValByDepth(limitMaxWSum) : null;
result.SetpointUsage = deltaDepthSum > 0d ? 100d * SpUsageDepth / spUsageTotal : null;
}
return result;
}
private double? DivideValByDepth(double? val)
{
if (val is null || val == 0d || deltaDepthSum == 0d)
return null;
return val / deltaDepthSum;
}
}

View File

@ -32,15 +32,15 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
protected int IdUser protected int IdUser
{ {
get get
{ {
var idUser = User.GetUserId(); var idUser = User.GetUserId();
if (!idUser.HasValue) if (!idUser.HasValue)
throw new ForbidException("Неизвестный пользователь"); throw new ForbidException("Неизвестный пользователь");
return idUser.Value; return idUser.Value;
} }
} }
private readonly IWellService wellService; private readonly IWellService wellService;
@ -50,18 +50,18 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
protected readonly IProcessMapPlanRepository<T> repository; protected readonly IProcessMapPlanRepository<T> repository;
protected ProcessMapBaseController(IWellService wellService, protected ProcessMapBaseController(IWellService wellService,
IProcessMapPlanRepository<T> repository, IProcessMapPlanRepository<T> repository,
IUserRepository userRepository, IUserRepository userRepository,
ICrudRepository<WellSectionTypeDto> wellSectionRepository, ICrudRepository<WellSectionTypeDto> wellSectionRepository,
IHubContext<TelemetryHub> telemetryHubContext, IHubContext<TelemetryHub> telemetryHubContext,
ITelemetryService telemetryService) ITelemetryService telemetryService)
{ {
this.wellService = wellService; this.wellService = wellService;
this.repository = repository; this.repository = repository;
this.userRepository = userRepository; this.userRepository = userRepository;
this.wellSectionRepository = wellSectionRepository; this.wellSectionRepository = wellSectionRepository;
this.telemetryHubContext = telemetryHubContext; this.telemetryHubContext = telemetryHubContext;
this.telemetryService = telemetryService; this.telemetryService = telemetryService;
} }
/// <summary> /// <summary>
@ -76,19 +76,19 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public virtual async Task<IActionResult> InsertAsync(T processMap, int idWell, CancellationToken cancellationToken) public virtual async Task<IActionResult> InsertAsync(T processMap, int idWell, CancellationToken cancellationToken)
{ {
processMap.IdWell = idWell; processMap.IdWell = idWell;
processMap.IdUser = IdUser; processMap.IdUser = IdUser;
processMap.LastUpdate = DateTime.UtcNow; processMap.LastUpdate = DateTime.UtcNow;
await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken); await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken);
await AssertUserHasAccessToEditProcessMapAsync(processMap.IdWell, cancellationToken); await AssertUserHasAccessToEditProcessMapAsync(processMap.IdWell, cancellationToken);
var result = await repository.InsertAsync(processMap, cancellationToken); var result = await repository.InsertAsync(processMap, cancellationToken);
await NotifyUsersBySignalR(idWell, cancellationToken); await NotifyUsersBySignalR(idWell, cancellationToken);
return Ok(result); return Ok(result);
} }
/// <summary> /// <summary>
@ -103,22 +103,22 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public virtual async Task<IActionResult> UpdateAsync(T processMap, int idWell, CancellationToken cancellationToken) public virtual async Task<IActionResult> UpdateAsync(T processMap, int idWell, CancellationToken cancellationToken)
{ {
processMap.IdWell = idWell; processMap.IdWell = idWell;
processMap.IdUser = IdUser; processMap.IdUser = IdUser;
processMap.LastUpdate = DateTime.UtcNow; processMap.LastUpdate = DateTime.UtcNow;
await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken); await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken);
await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken);
var result = await repository.UpdateAsync(processMap, cancellationToken); var result = await repository.UpdateAsync(processMap, cancellationToken);
if (result == ICrudRepository<T>.ErrorIdNotFound) if (result == ICrudRepository<T>.ErrorIdNotFound)
return this.ValidationBadRequest(nameof(processMap.Id), $"РТК с Id: {processMap.Id} не существует"); return this.ValidationBadRequest(nameof(processMap.Id), $"РТК с Id: {processMap.Id} не существует");
await NotifyUsersBySignalR(idWell, cancellationToken); await NotifyUsersBySignalR(idWell, cancellationToken);
return Ok(result); return Ok(result);
} }
/// <summary> /// <summary>
@ -132,13 +132,13 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
public virtual async Task<IActionResult> DeleteAsync(int id, int idWell, CancellationToken cancellationToken) public virtual async Task<IActionResult> DeleteAsync(int id, int idWell, CancellationToken cancellationToken)
{ {
await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken);
var result = await repository.DeleteAsync(id, cancellationToken); var result = await repository.DeleteAsync(id, cancellationToken);
await NotifyUsersBySignalR(idWell, cancellationToken); await NotifyUsersBySignalR(idWell, cancellationToken);
return Ok(result); return Ok(result);
} }
/// <summary> /// <summary>
@ -150,9 +150,9 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
[HttpGet] [HttpGet]
public async Task<ActionResult<IEnumerable<T>>> GetAsync(int idWell, CancellationToken cancellationToken) public async Task<ActionResult<IEnumerable<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
{ {
var processMaps = await repository.GetByIdWellAsync(idWell, cancellationToken); var processMaps = await repository.GetByIdWellAsync(idWell, cancellationToken);
return Ok(processMaps); return Ok(processMaps);
} }
/// <summary> /// <summary>
@ -167,49 +167,50 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<ActionResult<IEnumerable<T>>> GetProcessMapPlanByTelemetry(string uid, DateTime updateFrom, CancellationToken cancellationToken) public async Task<ActionResult<IEnumerable<T>>> GetProcessMapPlanByTelemetry(string uid, DateTime updateFrom, CancellationToken cancellationToken)
{ {
var idWell = telemetryService.GetIdWellByTelemetryUid(uid); var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
if (!idWell.HasValue) if (!idWell.HasValue)
return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}"); return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}");
var wellDrillingProcessMaps = await repository.GetAsync(new[] { new ProcessMapPlanRequest var requests = new[] { new ProcessMapPlanRequest
{ {
IdWell = idWell.Value, IdWell = idWell.Value,
UpdateFrom = updateFrom UpdateFrom = updateFrom
}}, cancellationToken); }
};
return Ok(wellDrillingProcessMaps); var processMaps = await repository.GetAsync(requests, cancellationToken);
return Ok(processMaps);
} }
protected async Task AssertUserHasAccessToEditProcessMapAsync(int idWell, CancellationToken cancellationToken) protected async Task AssertUserHasAccessToEditProcessMapAsync(int idWell, CancellationToken cancellationToken)
{ {
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
?? throw new ArgumentInvalidException(nameof(idWell), $"Скважины с {idWell} не существует"); ?? throw new ArgumentInvalidException(nameof(idWell), $"Скважины с {idWell} не существует");
var idCompany = User.GetCompanyId(); var idCompany = User.GetCompanyId();
if (!idCompany.HasValue || if (!idCompany.HasValue ||
!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken)) !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
throw new ForbidException("Нет доступа к скважине"); throw new ForbidException("Нет доступа к скважине");
if (well.IdState == 2 && !userRepository.HasPermission(IdUser, "ProcessMap.editCompletedWell")) if (well.IdState == 2 && !userRepository.HasPermission(IdUser, "ProcessMap.editCompletedWell"))
throw new ForbidException("Недостаточно прав для редактирования РТК завершенной скважины"); throw new ForbidException("Недостаточно прав для редактирования РТК завершенной скважины");
} }
protected async Task NotifyUsersBySignalR(int idWell, CancellationToken cancellationToken) protected async Task NotifyUsersBySignalR(int idWell, CancellationToken cancellationToken)
{ {
var dtos = await repository.GetByIdWellAsync(idWell, cancellationToken); var dtos = await repository.GetByIdWellAsync(idWell, cancellationToken);
await telemetryHubContext.Clients await telemetryHubContext.Clients
.Group($"{SignalRMethod}_{idWell}") .Group($"{SignalRMethod}_{idWell}")
.SendAsync("UpdateProcessMap", dtos, cancellationToken); .SendAsync("UpdateProcessMap", dtos, cancellationToken);
} }
private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken) private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken)
{ {
var wellSection = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken); _ = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken)
?? throw new ArgumentInvalidException(nameof(ProcessMapPlanWellDrillingDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден");
if (wellSection is null)
throw new ArgumentInvalidException(nameof(ProcessMapPlanWellDrillingDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден");
} }
} }