Замена репозитория ProcessMapPlanRepository на ChangeLogRepositoryAbstract

This commit is contained in:
Olga Nemt 2024-02-20 15:54:18 +05:00
parent 97e01be7db
commit d07f5f182a
23 changed files with 176 additions and 1206 deletions

View File

@ -6,7 +6,7 @@ namespace AsbCloudApp.Data.ProcessMaps;
/// <summary>
/// РТК план проработка скважины
/// </summary>
public class ProcessMapPlanWellReamDto : ProcessMapPlanBaseDto, IValidatableObject
public class ProcessMapPlanWellReamDto : AsbCloudApp.Data.ProcessMapPlan.ProcessMapPlanBaseDto, IValidatableObject
{
/// <summary>
/// Количество повторений

View File

@ -1,32 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using System;
namespace AsbCloudApp.Repositories;
/// <summary>
/// РТК план
/// </summary>
[Obsolete]
public interface IProcessMapPlanRepository<TDto> : IRepositoryWellRelated<TDto>
where TDto : ProcessMapPlanBaseDto
{
/// <summary>
/// Получить РТК по коллекции параметров
/// </summary>
/// <param name="requests"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<TDto>> GetAsync(IEnumerable<ProcessMapPlanRequest> requests, CancellationToken cancellationToken);
/// <summary>
/// Удалить РТК по скважине
/// </summary>
/// <param name="idWell"></param>
/// <returns></returns>
Task<int> RemoveByWellAsync(int idWell);
}

View File

@ -1,8 +1,8 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMapPlan;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMaps;
namespace AsbCloudApp.Repositories
{
@ -34,6 +34,6 @@ namespace AsbCloudApp.Repositories
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<ProcessMapPlanWellDrillingDto>> GetCompositeProcessMap(int idWell, CancellationToken token);
Task<IEnumerable<ProcessMapPlanDrillingDto>> GetCompositeProcessMap(int idWell, CancellationToken token);
}
}

View File

@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
namespace AsbCloudApp.Services.ProcessMaps;
@ -10,7 +9,7 @@ namespace AsbCloudApp.Services.ProcessMaps;
/// РТК
/// </summary>
public interface IProcessMapPlanService<T>
where T : ProcessMapPlanBaseDto
where T : AsbCloudApp.Data.ProcessMapPlan.ProcessMapPlanBaseDto
{
/// <summary>
/// Получение РТК план по скважине

View File

@ -1,19 +0,0 @@
using System.IO;
using System.Threading.Tasks;
using System.Threading;
namespace AsbCloudApp.Services.ProcessMaps.WellDrilling;
/// <summary>
/// Сервис экспорт РТК
/// </summary>
public interface IProcessMapReportWellDrillingExportService
{
/// <summary>
/// Сформировать файл с данными
/// </summary>
/// <param name="idWell"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<(string Name, Stream File)?> ExportAsync(int idWell, CancellationToken cancellationToken);
}

View File

@ -1,20 +0,0 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMaps.Report;
namespace AsbCloudApp.Services.ProcessMaps.WellDrilling;
/// <summary>
/// Сервис формирования отчёта РТК бурение
/// </summary>
public interface IProcessMapReportWellDrillingService
{
/// <summary>
/// Получить отчёт РТК по бурению
/// </summary>
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<ProcessMapReportWellDrillingDto>> GetAsync(int idWell, CancellationToken token);
}

View File

@ -48,7 +48,6 @@
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
<EmbeddedResource Include="Services\ProcessMaps\Report\ProcessMapReportTemplate.xlsx" />
<EmbeddedResource Include="Services\ProcessMaps\WellDrilling\ProcessMapPlanImportWellDrillingTemplate.xlsx" />
</ItemGroup>
<ItemGroup>

View File

@ -1,23 +1,27 @@
using System;
using System.Collections.Generic;
using AsbCloudApp.Data;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Data.DrillTestReport;
using AsbCloudApp.Data.Manuals;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Data.WellOperationImport.Options;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.DailyReport;
using AsbCloudApp.Services.Notifications;
using AsbCloudApp.Services.ProcessMaps;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudApp.Services.WellOperationImport;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
using AsbCloudDb.Model.Manuals;
using AsbCloudDb.Model.ProcessMaps;
using AsbCloudDb.Model.Trajectory;
using AsbCloudDb.Model.WellSections;
using AsbCloudInfrastructure.Background;
using AsbCloudInfrastructure.Repository;
using AsbCloudInfrastructure.Services;
@ -25,12 +29,14 @@ using AsbCloudInfrastructure.Services.DailyReport;
using AsbCloudInfrastructure.Services.DetectOperations;
using AsbCloudInfrastructure.Services.DrillingProgram;
using AsbCloudInfrastructure.Services.DrillTestReport;
using AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
using AsbCloudInfrastructure.Services.ProcessMaps;
using AsbCloudInfrastructure.Services.ProcessMaps.Report;
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.SAUB;
using AsbCloudInfrastructure.Services.Subsystems;
using AsbCloudInfrastructure.Services.Trajectory;
using AsbCloudInfrastructure.Services.Trajectory.Export;
using AsbCloudInfrastructure.Services.Trajectory.Parser;
using AsbCloudInfrastructure.Services.WellOperationImport;
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
using AsbCloudInfrastructure.Services.WellOperationService;
@ -39,16 +45,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Services.DailyReport;
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
using AsbCloudDb.Model.WellSections;
using AsbCloudInfrastructure.Services.ProcessMaps;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Requests;
using AsbCloudInfrastructure.Services.Parser;
using AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
using AsbCloudInfrastructure.Services.Trajectory.Parser;
using System;
namespace AsbCloudInfrastructure
{
@ -144,21 +141,21 @@ namespace AsbCloudInfrastructure
.Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax)
.Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan)
.Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax);
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeBalanceRecord, TimeBalanceRecordDto>()
.Map(dest => dest.DurationHours, src => new PlanFactDto<double?>()
{
Plan = src.DurationHoursPlan,
Fact = src.DurationHoursFact
Plan = src.DurationHoursPlan,
Fact = src.DurationHoursFact
});
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TimeBalanceBlock, TimeBalanceBlockDto>()
.Map(dest => dest.WellDepth, src => new PlanFactDto<double?>()
{
Plan = src.WellDepthPlan
Plan = src.WellDepthPlan
});
}
@ -188,8 +185,6 @@ namespace AsbCloudInfrastructure
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
services.AddTransient<IAuthService, AuthService>();
services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>, ProcessMapPlanRepository<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>>();
services.AddTransient<IProcessMapPlanRepository<ProcessMapPlanWellReamDto>, ProcessMapPlanRepository<ProcessMapPlanWellReamDto, ProcessMapWellReam>>();
services.AddTransient<IDepositRepository, DepositRepository>();
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
services.AddTransient<IEventService, EventService>();
@ -204,7 +199,6 @@ namespace AsbCloudInfrastructure
services.AddTransient<ITimezoneService, TimezoneService>();
services.AddScoped<IWellService, WellService>();
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
services.AddTransient<IProcessMapReportDataSaubStatExportService, ProcessMapReportDataSaubStatExportService>();
services.AddTransient<TrajectoryPlanExportService>();
services.AddTransient<TrajectoryFactManualExportService>();
@ -219,17 +213,19 @@ namespace AsbCloudInfrastructure
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
services.AddTransient<IFileCategoryService, FileCategoryService>();
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
services.AddTransient<IProcessMapReportWellDrillingService, ProcessMapReportWellDrillingService>();
services.AddTransient<IProcessMapPlanImportService, ProcessMapPlanImportWellDrillingService>();
services.AddTransient<WellInfoService>();
services.AddTransient<IHelpPageService, HelpPageService>();
services.AddTransient<IScheduleReportService, ScheduleReportService>();
services.AddTransient<IDataSaubStatRepository, DataSaubStatRepository>();
services.AddTransient<
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell>,
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell>,
ProcessMapPlanBaseRepository<ProcessMapPlanDrillingDto, ProcessMapPlanDrilling>>();
services.AddTransient<
IChangeLogRepository<ProcessMapPlanWellReamDto, ProcessMapPlanBaseRequestWithWell>,
ProcessMapPlanBaseRepository<ProcessMapPlanWellReamDto, ProcessMapPlanDrilling>>();
services.AddTransient<IProcessMapReportDataSaubStatService, ProcessMapReportDataSaubStatService>();
services.AddTransient<TrajectoryService>();
@ -304,7 +300,7 @@ namespace AsbCloudInfrastructure
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.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>();
services.AddTransient<IDrillTestReportService, DrillTestReportService>();
services.AddTransient<IReportMakerService<DrillTestReportDataDto>, DrillTestReportMakerService>();
@ -326,10 +322,10 @@ namespace AsbCloudInfrastructure
services.AddTransient<IDailyReportService, DailyReportService>();
services.AddTransient<IDailyReportRepository, DailyReportRepository>();
services.AddTransient<IDailyReportExportService, DailyReportExportService>();
services.AddTransient<IRepositoryWellRelated<WellSectionPlanDto>, CrudWellRelatedRepositoryBase<WellSectionPlanDto, WellSectionPlan>>();
services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellDrillingDto>, ProcessMapPlanService<ProcessMapPlanWellDrillingDto>>();
services.AddTransient<IProcessMapPlanService<ProcessMapPlanDrillingDto>, ProcessMapPlanService<ProcessMapPlanDrillingDto>>();
services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellReamDto>, ProcessMapPlanService<ProcessMapPlanWellReamDto>>();
services.AddTransient<IWellSectionPlanRepository, WellSectionPlanRepository>();

View File

@ -1,89 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudDb.Model.ProcessMaps;
using Microsoft.EntityFrameworkCore;
namespace AsbCloudInfrastructure.Repository;
public class ProcessMapPlanRepository<TDto, TEntity> : CrudWellRelatedRepositoryBase<TDto, TEntity>,
IProcessMapPlanRepository<TDto>
where TDto : ProcessMapPlanBaseDto
where TEntity : ProcessMapBase
{
private readonly IWellService wellService;
public ProcessMapPlanRepository(IAsbCloudDbContext context, IWellService wellService)
: base(context, dbSet =>
dbSet
.Include(p => p.WellSectionType)
.Include(p => p.Well))
{
this.wellService = wellService;
}
public async Task<IEnumerable<TDto>> GetAsync(IEnumerable<ProcessMapPlanRequest> requests, CancellationToken cancellationToken)
{
var query = BuildQuery(requests);
var entities = await query.ToArrayAsync(cancellationToken);
return entities.Select(Convert);
}
public Task<int> RemoveByWellAsync(int idWell)
{
var query = GetQuery().Where(x => x.IdWell == idWell);
dbSet.RemoveRange(query);
return dbContext.SaveChangesAsync(CancellationToken.None);
}
private IQueryable<TEntity> BuildQuery(IEnumerable<ProcessMapPlanRequest> requests)
{
var queries = requests
.Select(request => BuildQuery(request))
.ToArray();
var query = queries.FirstOrDefault()
?? throw new ArgumentInvalidException(nameof(requests), "Пустые запросы недопустимы");
for ( var i = 1; i < queries.Length; i++)
query = query.Union(queries[i]);
query = query
.Distinct()
.OrderBy(e => e.DepthStart)
.ThenBy(e => e.Id)
.AsNoTracking();
return query;
}
private IQueryable<TEntity> BuildQuery(ProcessMapPlanRequest request)
{
var query = GetQuery();
query = query.Where(p => p.IdWell == request.IdWell);
if (request.IdWellSectionType is not null)
query = query.Where(p => p.IdWellSectionType == request.IdWellSectionType);
if (request.UpdateFrom is not null)
{
var timezone = wellService.GetTimezone(request.IdWell);
var updateFromUtc = request.UpdateFrom?.ToUtcDateTimeOffset(timezone.Hours);
query = query.Where(p => p.LastUpdate >= updateFromUtc);
}
return query;
}
}

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
@ -17,12 +18,14 @@ namespace AsbCloudInfrastructure.Repository
public class WellCompositeRepository : IWellCompositeRepository
{
private readonly IAsbCloudDbContext db;
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository;
private readonly IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanDrillingRepository;
public WellCompositeRepository(IAsbCloudDbContext db, IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository)
public WellCompositeRepository(
IAsbCloudDbContext db,
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanDrillingRepository)
{
this.db = db;
this.processMapPlanWellDrillingRepository = processMapPlanWellDrillingRepository;
this.processMapPlanDrillingRepository = processMapPlanDrillingRepository;
}
/// <inheritdoc/>
@ -50,7 +53,7 @@ namespace AsbCloudInfrastructure.Repository
}
/// <inheritdoc/>
public async Task<IEnumerable<ProcessMapPlanWellDrillingDto>> GetCompositeProcessMap(int idWell, CancellationToken token)
public async Task<IEnumerable<ProcessMapPlanDrillingDto>> GetCompositeProcessMap(int idWell, CancellationToken token)
{
var dtos = await GetAsync(idWell, token);
@ -59,8 +62,8 @@ namespace AsbCloudInfrastructure.Repository
IdWellSectionType = x.IdWellSectionType
});
var result = await processMapPlanWellDrillingRepository.GetAsync(requests, token);
return result;
//var result = await processMapPlanDrillingRepository.GetAsync(requests, token);
return Enumerable.Empty<ProcessMapPlanDrillingDto>();
}
private static WellComposite Convert(int idWell, WellCompositeDto dto)

View File

@ -29,7 +29,7 @@ public class DailyReportService : IDailyReportService
private readonly IScheduleRepository scheduleRepository;
private readonly IWellOperationRepository wellOperationRepository;
private readonly ISubsystemService subsystemService;
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService;
private readonly IProcessMapReportDataSaubStatService processMapReportDataSaubStatService;
private readonly IDetectedOperationService detectedOperationService;
public DailyReportService(IWellService wellService,
@ -38,7 +38,7 @@ public class DailyReportService : IDailyReportService
IScheduleRepository scheduleRepository,
IWellOperationRepository wellOperationRepository,
ISubsystemService subsystemService,
IProcessMapReportWellDrillingService processMapReportWellDrillingService,
IProcessMapReportDataSaubStatService processMapReportDataSaubStatService,
IDetectedOperationService detectedOperationService)
{
this.wellService = wellService;
@ -47,7 +47,7 @@ public class DailyReportService : IDailyReportService
this.scheduleRepository = scheduleRepository;
this.wellOperationRepository = wellOperationRepository;
this.subsystemService = subsystemService;
this.processMapReportWellDrillingService = processMapReportWellDrillingService;
this.processMapReportDataSaubStatService = processMapReportDataSaubStatService;
this.detectedOperationService = detectedOperationService;
}
@ -374,8 +374,9 @@ public class DailyReportService : IDailyReportService
{
var geDate = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
var leDate = dailyReport.Date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
dailyReport.ProcessMapWellDrillingBlock = (await processMapReportWellDrillingService.GetAsync(dailyReport.IdWell,
var request = new DataSaubStatRequest();
dailyReport.ProcessMapWellDrillingBlock = (await processMapReportDataSaubStatService.GetAsync(dailyReport.IdWell, request,
cancellationToken)).Where(p => p.DateStart >= geDate && p.DateStart <= leDate)
.GroupBy(p => p.DrillingMode)
.Select(g => new ProcessMapWellDrillingRecordDto
@ -387,7 +388,7 @@ public class DailyReportService : IDailyReportService
Plan = g.Sum(p => p.Rop.Plan),
Fact = g.Sum(p => p.Rop.Fact)
},
MechDrillingHours = g.Sum(p => p.MechDrillingHours)
MechDrillingHours = g.Sum(p => p.DrilledTime)
});
}

View File

@ -1,65 +1,68 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps;
namespace AsbCloudInfrastructure.Services.ProcessMaps;
public class ProcessMapPlanService<T> : IProcessMapPlanService<T>
where T : ProcessMapPlanBaseDto
public class ProcessMapPlanService<T> : AsbCloudApp.Services.ProcessMaps.IProcessMapPlanService<T>
where T : AsbCloudApp.Data.ProcessMapPlan.ProcessMapPlanBaseDto
{
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
private readonly IProcessMapPlanRepository<T> processMapPlanRepository;
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository;
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
private readonly IChangeLogRepository<T, ProcessMapPlanBaseRequestWithWell> processMapPlanBaseRepository;
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository;
public ProcessMapPlanService(ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
IProcessMapPlanRepository<T> processMapPlanRepository,
IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository)
{
this.wellSectionTypeRepository = wellSectionTypeRepository;
this.processMapPlanRepository = processMapPlanRepository;
this.wellSectionPlanRepository = wellSectionPlanRepository;
}
public ProcessMapPlanService(
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
IChangeLogRepository<T, ProcessMapPlanBaseRequestWithWell> processMapPlanBaseRepository,
IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository)
{
this.wellSectionTypeRepository = wellSectionTypeRepository;
this.processMapPlanBaseRepository = processMapPlanBaseRepository;
this.wellSectionPlanRepository = wellSectionPlanRepository;
}
public async Task<IEnumerable<ValidationResultDto<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
{
var wellSectionTypes = await wellSectionTypeRepository.GetAllAsync(cancellationToken);
public async Task<IEnumerable<ValidationResultDto<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
{
var wellSectionTypes = await wellSectionTypeRepository.GetAllAsync(cancellationToken);
var processMapsPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
var request = new ProcessMapPlanBaseRequestWithWell(idWell);
var wellSectionsPlan = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
var processMapsPlan = await processMapPlanBaseRepository.Get(request, cancellationToken);
return processMapsPlan.Select(processMapPlan =>
{
var wellSectionPlan = wellSectionsPlan.FirstOrDefault(s => s.IdSectionType == processMapPlan.IdWellSectionType);
var wellSectionsPlan = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
var isValid = wellSectionPlan is not null && wellSectionPlan.DepthStart <= processMapPlan.DepthStart &&
wellSectionPlan.DepthEnd >= processMapPlan.DepthEnd;
return processMapsPlan.Select(processMapPlan =>
{
var wellSectionPlan = wellSectionsPlan.FirstOrDefault(s => s.IdSectionType == processMapPlan.IdWellSectionType);
var validationResult = new ValidationResultDto<T>
{
Item = processMapPlan
};
var isValid = wellSectionPlan is not null && wellSectionPlan.DepthStart <= processMapPlan.DepthStart &&
wellSectionPlan.DepthEnd >= processMapPlan.DepthEnd;
if (isValid)
return validationResult;
var validationResult = new ValidationResultDto<T>
{
Item = processMapPlan
};
var wellSectionType = wellSectionTypes.FirstOrDefault(s => s.Id == processMapPlan.IdWellSectionType);
if (isValid)
return validationResult;
validationResult.Warnings = new ValidationResult[]
{
new($"Конструкция секции: {wellSectionType?.Caption}; " +
$"Интервал бурения от {processMapPlan.DepthStart} до {processMapPlan.DepthEnd} не совпадает с данными указанными на странице " +
$"Конструкция скважины / План", new[] { nameof(processMapPlan.DepthStart), nameof(processMapPlan.DepthEnd) })
};
var wellSectionType = wellSectionTypes.FirstOrDefault(s => s.Id == processMapPlan.IdWellSectionType);
return validationResult;
});
}
validationResult.Warnings = new ValidationResult[]
{
new($"Конструкция секции: {wellSectionType?.Caption}; " +
$"Интервал бурения от {processMapPlan.DepthStart} до {processMapPlan.DepthEnd} не совпадает с данными указанными на странице " +
$"Конструкция скважины / План", new[] { nameof(processMapPlan.DepthStart), nameof(processMapPlan.DepthEnd) })
};
return validationResult;
});
}
}

View File

@ -1,195 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.ProcessMaps.Report;
public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDrillingExportService
{
const int firstColumn = 2;
const int lastColumn = 42;
const int headerRowsCount = 5;
private readonly IWellService wellService;
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService;
public ProcessMapReportWellDrillingExportService(IWellService wellService,
IProcessMapReportWellDrillingService processMapReportWellDrillingService)
{
this.wellService = wellService;
this.processMapReportWellDrillingService = processMapReportWellDrillingService;
}
public async Task<(string Name, Stream File)?> ExportAsync(int idWell, CancellationToken cancellationToken)
{
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken);
if (well is null)
return null;
var stream = GetExcelTemplateStream();
using var workbook = new XLWorkbook(stream);
var data = await processMapReportWellDrillingService.GetAsync(idWell, cancellationToken);
FillProcessMapToWorkbook(workbook, data);
MemoryStream memoryStream = new();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
var name = $"РТК бурение. Отчёт по скважине {well.Caption} куст {well.Cluster}.xlsx";
return (name, memoryStream);
}
private static void FillProcessMapToWorkbook(XLWorkbook workbook,
IEnumerable<ProcessMapReportWellDrillingDto> data)
{
const string sheetName = "Отчёт";
var sheet = workbook.GetWorksheet(sheetName);
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
FillSheet(sheet, dataBySections);
}
private static void FillSheet(IXLWorksheet sheet,
IEnumerable<IGrouping<int, ProcessMapReportWellDrillingDto>> dataBySections)
{
var startRow = headerRowsCount + 1;
foreach (var sectionData in dataBySections)
{
if (sectionData.Any())
startRow = FillSection(sheet, sectionData, startRow);
}
}
private static int FillSection(IXLWorksheet sheet, IGrouping<int, ProcessMapReportWellDrillingDto> sectionData,
int row)
{
var rowStart = row;
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
?? sectionData.Key.ToString();
sheet.Range(row, firstColumn, row, lastColumn)
.Merge()
.FirstCell()
.SetCellValue(sectionName)
.Style
.Fill.SetBackgroundColor(XLColor.LightGray);
row++;
foreach (var interval in sectionData)
row = FillIntervalData(sheet, interval, row);
var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastColumn).Style;
SetBorders(sectionStyle);
return row;
}
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportWellDrillingDto interval, int row)
{
const int columnDepth = firstColumn + 1;
const int columnDate = firstColumn + 2;
const int columnRopTime = firstColumn + 3;
const int columnMode = firstColumn + 4;
sheet.Cell(row, firstColumn).SetCellValue(interval.DepthStart);
sheet.Cell(row, columnDepth).SetCellValue(interval.DepthEnd);
sheet.Cell(row, columnDate).SetCellValue(interval.DateStart);
sheet.Cell(row, columnRopTime).SetCellValue(interval.MechDrillingHours);
row = FillIntervalModeData(sheet, interval, columnMode, row);
return row;
}
private static int FillIntervalModeData(IXLWorksheet sheet, ProcessMapReportWellDrillingDto modeData,
int column, int row)
{
int columnDeltaDepth = column + 1;
int columnPressure = columnDeltaDepth + 1;
int columnLoad = columnPressure + 5;
int columnTorque = columnLoad + 5;
int columnSpeed = columnTorque + 5;
int columnUsagePlan = columnSpeed + 5;
int columnUsageFact = columnUsagePlan + 1;
int columnRop = columnUsageFact + 12;
sheet.Cell(row, column).SetCellValue(modeData.DrillingMode);
sheet.Cell(row, columnDeltaDepth).SetCellValue(modeData.DeltaDepth);
FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
sheet.Cell(row, columnUsagePlan).SetCellValue(modeData.UsagePlan);
sheet.Cell(row, columnUsageFact).SetCellValue(modeData.UsageFact);
sheet.Cell(row, columnRop).SetCellValue(modeData.Rop.Fact);
return row + 1;
}
private static void FillIntervalModeDataParam(IXLWorksheet sheet,
ProcessMapReportWellDrillingParamsDto dataParam, int column, int row)
{
const int columnOffsetSpPlan = 0;
const int columnOffsetSpFact = 1;
const int columnOffsetFact = 2;
const int columnOffsetLimit = 3;
const int columnOffsetPercent = 4;
sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(dataParam.SetpointPlan);
sheet.Cell(row, column + columnOffsetSpFact).SetCellValue(dataParam.SetpointFact);
sheet.Cell(row, column + columnOffsetFact).SetCellValue(dataParam.Fact);
sheet.Cell(row, column + columnOffsetLimit).SetCellValue(dataParam.Limit);
sheet.Cell(row, column + columnOffsetPercent).SetCellValue(dataParam.SetpointUsage);
}
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet,
ProcessMapReportWellDrillingParamsDto dataParam, int column, int row)
{
const int columnOffsetSpPlan = 0;
const int columnOffsetSpFact = 1;
const int columnOffsetFact = 2;
const int columnOffsetLimit = 3;
const int columnOffsetPercent = 4;
sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(dataParam.SetpointPlan);
sheet.Cell(row, column + columnOffsetSpFact).SetCellValue(dataParam.SetpointFact);
sheet.Cell(row, column + columnOffsetFact).SetCellValue(dataParam.Fact);
sheet.Cell(row, column + columnOffsetLimit).SetCellValue(dataParam.Limit);
sheet.Cell(row, column + columnOffsetPercent).SetCellValue(dataParam.SetpointUsage);
}
//TODO: использовать метод расширения, избавиться от этого метода
private static Stream GetExcelTemplateStream()
{
var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(
"AsbCloudInfrastructure.Services.ProcessMaps.Report.ProcessMapReportTemplate.xlsx");
return stream!;
}
//TODO: нужен ли этот метод? Это можно настроить в шаблоне
private static void SetBorders(IXLStyle style)
{
style.Border.RightBorder = XLBorderStyleValues.Thin;
style.Border.LeftBorder = XLBorderStyleValues.Thin;
style.Border.TopBorder = XLBorderStyleValues.Thin;
style.Border.BottomBorder = XLBorderStyleValues.Thin;
style.Border.InsideBorder = XLBorderStyleValues.Thin;
}
}

View File

@ -1,235 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.ProcessMaps.Report.Data;
namespace AsbCloudInfrastructure.Services.ProcessMaps.Report;
public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrillingService
{
private readonly IWellService wellService;
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository;
private readonly ITelemetryDataSaubService telemetryDataSaubService;
private readonly IWellOperationRepository wellOperationRepository;
public ProcessMapReportWellDrillingService(IWellService wellService,
IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository,
ITelemetryDataSaubService telemetryDataSaubService,
IWellOperationRepository wellOperationRepository)
{
this.wellService = wellService;
this.processMapPlanWellDrillingRepository = processMapPlanWellDrillingRepository;
this.telemetryDataSaubService = telemetryDataSaubService;
this.wellOperationRepository = wellOperationRepository;
}
public async Task<IEnumerable<ProcessMapReportWellDrillingDto>> GetAsync(int idWell,
CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token)
?? throw new ArgumentInvalidException(nameof(idWell), $"Скважина с Id: {idWell} не найдена");
if (!well.IdTelemetry.HasValue)
return Enumerable.Empty<ProcessMapReportWellDrillingDto>();
var processMapPlanWellDrillings = await processMapPlanWellDrillingRepository.GetByIdWellAsync(idWell, token);
if (!processMapPlanWellDrillings.Any())
return Enumerable.Empty<ProcessMapReportWellDrillingDto>();
var telemetryDataStat =
(await telemetryDataSaubService.GetTelemetryDataStatAsync(well.IdTelemetry.Value, token)).ToArray();
if (!telemetryDataStat.Any())
return Enumerable.Empty<ProcessMapReportWellDrillingDto>();
var result = CalcByIntervals(processMapPlanWellDrillings, telemetryDataStat);
return result;
}
private IEnumerable<ProcessMapReportWellDrillingDto> CalcByIntervals(
IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings,
TelemetryDataSaubStatDto[] telemetryDataStat)
{
var processMapIntervals = CalcDepthIntervals(processMapPlanWellDrillings);
var result = new List<ProcessMapReportWellDrillingDto>(processMapIntervals.Count() * 4);
var telemetryIndexStart =
Array.FindIndex(telemetryDataStat, t => t.WellDepthMin >= processMapIntervals.First().DepthStart);
if (telemetryIndexStart < 0)
return Enumerable.Empty<ProcessMapReportWellDrillingDto>();
IDictionary<int, string> sectionTypes = wellOperationRepository
.GetSectionTypes()
.ToDictionary(s => s.Id, s => s.Caption);
foreach (var interval in processMapIntervals)
{
var processMapPlanWellDrillingInterval = processMapPlanWellDrillings
.Where(p => p.DepthStart <= interval.DepthEnd && p.DepthEnd >= interval.DepthStart);
if (!processMapPlanWellDrillingInterval.Any())
continue;
var telemetryIndexEnd = Array.FindIndex(telemetryDataStat, telemetryIndexStart,
t => t.WellDepthMin >= interval.DepthEnd);
if (telemetryIndexEnd < 0)
telemetryIndexEnd = telemetryDataStat.Length - 1;
var telemetryDataInterval =
telemetryDataStat.AsSpan(telemetryIndexStart, telemetryIndexEnd - telemetryIndexStart);
IEnumerable<ProcessMapReportWellDrillingDto> subIntervalsResult =
CalcSubIntervals(interval, processMapPlanWellDrillingInterval, telemetryDataInterval, sectionTypes);
result.AddRange(subIntervalsResult);
telemetryIndexStart = telemetryIndexEnd;
}
return result;
}
private static IEnumerable<(double DepthStart, double DepthEnd)> CalcDepthIntervals(
IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings)
{
if (!processMapPlanWellDrillings.Any())
yield break;
var intervalStarts = processMapPlanWellDrillings
.OrderBy(i => i.DepthStart)
.Select(p => p.DepthStart)
.Distinct()
.ToArray();
for (var i = 1; i < intervalStarts.Length; i++)
yield return (intervalStarts[i - 1], intervalStarts[i]);
yield return (intervalStarts[^1], processMapPlanWellDrillings.Max(p => p.DepthEnd));
}
private static IEnumerable<ProcessMapReportWellDrillingDto> CalcSubIntervals(
(double DepthStart, double DepthEnd) interval,
IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingInterval,
Span<TelemetryDataSaubStatDto> telemetryDataInterval,
IDictionary<int, string> sectionTypes)
{
var telemetryDataIntervalLength = telemetryDataInterval.Length;
if (telemetryDataInterval.Length == 0)
return Enumerable.Empty<ProcessMapReportWellDrillingDto>();
var result = new List<ProcessMapReportWellDrillingDto>();
var telemetryIndexStart = 0;
var subInterval = interval;
for (var i = telemetryIndexStart + 1; i < telemetryDataIntervalLength; i++)
{
if (IsDifferent(telemetryDataInterval[telemetryIndexStart], telemetryDataInterval[i]))
{
subInterval.DepthEnd = telemetryDataInterval[i - 1].WellDepthMax;
var telemetryRowSpan = telemetryDataInterval[telemetryIndexStart..(i - 1)];
if (!telemetryRowSpan.IsEmpty)
{
var intervalReportRow = CalcSubIntervalReportRow(subInterval, processMapPlanWellDrillingInterval,
telemetryRowSpan, sectionTypes);
result.Add(intervalReportRow);
}
telemetryIndexStart = i;
subInterval.DepthStart = subInterval.DepthEnd;
}
}
subInterval.DepthEnd = interval.DepthEnd;
var intervalReportRowLast = CalcSubIntervalReportRow(subInterval, processMapPlanWellDrillingInterval,
telemetryDataInterval[telemetryIndexStart..telemetryDataIntervalLength], sectionTypes);
result.Add(intervalReportRowLast);
return result;
}
private static ProcessMapReportWellDrillingDto CalcSubIntervalReportRow(
(double DepthStart, double DepthEnd) subInterval,
IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings,
Span<TelemetryDataSaubStatDto> telemetryRowSpan,
IDictionary<int, string> sectionTypes)
{
var telemetryStat = new TelemetryStat(telemetryRowSpan);
var processMapByMode = processMapPlanWellDrillings.FirstOrDefault(p => p.IdMode == telemetryStat.IdMode);
var processMapFirst = processMapPlanWellDrillings.First();
var idWellSectionType = processMapByMode?.IdWellSectionType ?? processMapFirst.IdWellSectionType;
var result = new ProcessMapReportWellDrillingDto
{
IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell,
IdWellSectionType = idWellSectionType,
WellSectionTypeName = sectionTypes[idWellSectionType],
DepthStart = subInterval.DepthStart,
DepthEnd = subInterval.DepthEnd,
DateStart = telemetryStat.DateStart,
MechDrillingHours = telemetryStat.DrillingHours,
DrillingMode = telemetryStat.ModeName,
DeltaDepth = telemetryStat.DeltaDepth,
PressureDiff = telemetryStat.Pressure.MakeParams(processMapByMode?.Pressure.Plan),
AxialLoad = telemetryStat.AxialLoad.MakeParams(processMapByMode?.AxialLoad.Plan),
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan),
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan),
Rop = new PlanFactDto<double?>
{
Plan = processMapByMode?.RopPlan,
Fact = telemetryStat.Rop
},
UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan,
UsageFact = telemetryStat.UsageSaub,
};
return result;
}
private static bool IsDifferent(TelemetryDataSaubStatDto intervalStart, TelemetryDataSaubStatDto current)
{
if (intervalStart.WellDepthMin > current.WellDepthMin)
return true;
if (intervalStart.IdMode != current.IdMode)
return true;
if (Math.Abs(intervalStart.PressureSp - current.PressureSp) > 5d)
return true;
if (Math.Abs(intervalStart.AxialLoadSp - current.AxialLoadSp) > 1d)
return true;
if (Math.Abs(intervalStart.RotorTorqueSp - current.RotorTorqueSp) > 5d)
return true;
var blockSpeedSpDiff = Math.Abs(intervalStart.BlockSpeedSp - current.BlockSpeedSp);
if (!(blockSpeedSpDiff > 5d))
return false;
switch (intervalStart.BlockSpeedSp)
{
case <= 30:
case > 30 when blockSpeedSpDiff > 15d:
case > 80 when blockSpeedSpDiff > 20d:
return true;
}
return false;
}
}

View File

@ -1,368 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps;
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling;
/*
* password for ProcessMapImportTemplate.xlsx is ASB2020!
*/
[Obsolete]
public class ProcessMapPlanImportWellDrillingService : IProcessMapPlanImportService
{
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository;
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
private readonly IWellService wellService;
private const string sheetNamePlan = "План";
private const int headerRowsCount = 2;
private const int columnSection = 1;
private const int columnMode = 2;
private const int columnDepthStart = 3;
private const int columnDepthEnd = 4;
private const int columnPressurePlan = 5;
private const int columnPressureLimitMax = 6;
private const int columnAxialLoadPlan = 7;
private const int columnAxialLoadLimitMax = 8;
private const int columnTopDriveTorquePlan = 9;
private const int columnTopDriveTorqueLimitMax = 10;
private const int columnTopDriveSpeedPlan = 11;
private const int columnTopDriveSpeedLimitMax = 12;
private const int columnFlowPlan = 13;
private const int columnFlowLimitMax = 14;
private const int columnRopPlan = 15;
private const int columnUsageSaub = 16;
private const int columnUsageSpin = 17;
private const int columnComment = 18;
private WellSectionTypeDto[] sections = null!;
public ProcessMapPlanImportWellDrillingService(IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository,
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
IWellService wellService)
{
this.processMapPlanWellDrillingRepository = processMapPlanWellDrillingRepository;
this.wellSectionTypeRepository = wellSectionTypeRepository;
this.wellService = wellService;
}
public async Task ImportAsync(int idWell, int idUser, bool deleteProcessMapPlansBeforeImport, Stream stream,
CancellationToken cancellationToken)
{
sections = (await wellSectionTypeRepository.GetAllAsync(cancellationToken)).ToArray();
using var workBook = new XLWorkbook(stream);
var wellDrillingProcessMaps = ParseWorkBook(workBook);
if (deleteProcessMapPlansBeforeImport)
await processMapPlanWellDrillingRepository.RemoveByWellAsync(idWell);
foreach (var wellDrillingProcessMap in wellDrillingProcessMaps)
{
wellDrillingProcessMap.IdWell = idWell;
wellDrillingProcessMap.IdUser = idUser;
}
await processMapPlanWellDrillingRepository.InsertRangeAsync(wellDrillingProcessMaps, cancellationToken);
}
public async Task<(string Name, Stream File)> ExportAsync(int idWell, CancellationToken cancellationToken)
{
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
?? throw new ArgumentInvalidException(nameof(idWell), $"Скважины с {idWell} не существует");
sections = (await wellSectionTypeRepository.GetAllAsync(cancellationToken)).ToArray();
var processMapPlans = (await processMapPlanWellDrillingRepository.GetByIdWellAsync(idWell,
cancellationToken)).ToArray();
var file = await GenerateExcelFileStreamAsync(processMapPlans, cancellationToken);
var fileName = $"РТК-план бурение по скважине {well.Caption} куст {well.Cluster}.xlsx";
return (fileName, file);
}
public async Task<(string Name, Stream File)> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
{
var resourceName = Assembly.GetExecutingAssembly()
.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith("ProcessMapPlanImportWellDrillingTemplate.xlsx"))!;
using var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName)!;
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream, cancellationToken);
memoryStream.Position = 0;
var name = "ЕЦП_шаблон_файла_РТК_бурение.xlsx";
return (name, memoryStream);
}
private void AddToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings)
{
var sheet = workbook.GetWorksheet(sheetNamePlan);
AddToSheet(sheet, processMapPlanWellDrillings.ToArray());
}
private void AddToSheet(IXLWorksheet sheet, IList<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillings)
{
if (!processMapPlanWellDrillings.Any())
return;
for (int i = 0; i < processMapPlanWellDrillings.Count; i++)
{
var row = sheet.Row(1 + i + headerRowsCount);
AddToRow(row, processMapPlanWellDrillings[i]);
}
}
private void AddToRow(IXLRow row, ProcessMapPlanWellDrillingDto processMapPlanWellDrillings)
{
var section = sections.First(x => x.Id == processMapPlanWellDrillings.IdWellSectionType).Caption;
var modeCaption = GetModeCaption(processMapPlanWellDrillings.IdMode);
row.Cell(columnSection).SetCellValue(section);
row.Cell(columnMode).SetCellValue(modeCaption);
row.Cell(columnDepthStart).SetCellValue(processMapPlanWellDrillings.DepthStart);
row.Cell(columnDepthEnd).SetCellValue(processMapPlanWellDrillings.DepthEnd);
row.Cell(columnPressurePlan).SetCellValue(processMapPlanWellDrillings.Pressure.Plan);
row.Cell(columnPressureLimitMax).SetCellValue(processMapPlanWellDrillings.Pressure.LimitMax);
row.Cell(columnAxialLoadPlan).SetCellValue(processMapPlanWellDrillings.AxialLoad.Plan);
row.Cell(columnAxialLoadLimitMax).SetCellValue(processMapPlanWellDrillings.AxialLoad.LimitMax);
row.Cell(columnTopDriveTorquePlan).SetCellValue(processMapPlanWellDrillings.TopDriveTorque.Plan);
row.Cell(columnTopDriveTorqueLimitMax).SetCellValue(processMapPlanWellDrillings.TopDriveTorque.LimitMax);
row.Cell(columnTopDriveSpeedPlan).SetCellValue(processMapPlanWellDrillings.TopDriveSpeed.Plan);
row.Cell(columnTopDriveSpeedLimitMax).SetCellValue(processMapPlanWellDrillings.TopDriveSpeed.LimitMax);
row.Cell(columnFlowPlan).SetCellValue(processMapPlanWellDrillings.Flow.Plan);
row.Cell(columnFlowLimitMax).SetCellValue(processMapPlanWellDrillings.Flow.LimitMax);
row.Cell(columnRopPlan).SetCellValue(processMapPlanWellDrillings.RopPlan);
row.Cell(columnUsageSaub).SetCellValue(processMapPlanWellDrillings.UsageSaub);
row.Cell(columnUsageSpin).SetCellValue(processMapPlanWellDrillings.UsageSpin);
row.Cell(columnComment).SetCellValue(processMapPlanWellDrillings.Comment);
}
private IEnumerable<ProcessMapPlanWellDrillingDto> ParseWorkBook(IXLWorkbook workbook)
{
var sheet = workbook.GetWorksheet(sheetNamePlan);
return ParseSheet(sheet);
}
private IEnumerable<ProcessMapPlanWellDrillingDto> ParseSheet(IXLWorksheet sheet)
{
const int columnsCount = 17;
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < columnsCount)
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
var rowsCount = sheet.RowsUsed().Count() - headerRowsCount;
if (rowsCount <= 0)
return Array.Empty<ProcessMapPlanWellDrillingDto>();
var processMapPlans = new ProcessMapPlanWellDrillingDto[rowsCount];
var parseErrors = new List<string>();
for (int i = 0; i < processMapPlans.Length; i++)
{
var row = sheet.Row(1 + i + headerRowsCount);
try
{
processMapPlans[i] = ParseRow(row);
}
catch (FileFormatException ex)
{
parseErrors.Add(ex.Message);
}
}
if (parseErrors.Any())
throw new FileFormatException(string.Join("\r\n", parseErrors));
return processMapPlans;
}
private ProcessMapPlanWellDrillingDto ParseRow(IXLRow row)
{
var wellSectionTypeCaption = row.Cell(columnSection).GetCellValue<string>()?.Trim().ToLower();
var modeName = row.Cell(columnMode).GetCellValue<string>()?.Trim().ToLower();
var depthStart = row.Cell(columnDepthStart).GetCellValue<double>();
var depthEnd = row.Cell(columnDepthEnd).GetCellValue<double>();
var pressurePlan = row.Cell(columnPressurePlan).GetCellValue<double>();
var pressureLimitMax = row.Cell(columnPressureLimitMax).GetCellValue<double>();
var axialLoadPlan = row.Cell(columnAxialLoadPlan).GetCellValue<double>();
var axialLoadLimitMax = row.Cell(columnAxialLoadLimitMax).GetCellValue<double>();
var topDriveTorquePlan = row.Cell(columnTopDriveTorquePlan).GetCellValue<double>();
var topDriveTorqueLimitMax = row.Cell(columnTopDriveTorqueLimitMax).GetCellValue<double>();
var topDriveSpeedPlan = row.Cell(columnTopDriveSpeedPlan).GetCellValue<double>();
var topDriveSpeedLimitMax = row.Cell(columnTopDriveSpeedLimitMax).GetCellValue<double>();
var flowPlan = row.Cell(columnFlowPlan).GetCellValue<double>();
var flowLimitMax = row.Cell(columnFlowLimitMax).GetCellValue<double>();
var ropPlan = row.Cell(columnRopPlan).GetCellValue<double>();
var usageSaub = row.Cell(columnUsageSaub).GetCellValue<double>();
var usageSpin = row.Cell(columnUsageSpin).GetCellValue<double>();
var comment = row.Cell(columnComment).GetCellValue<string?>();
var wellSection = sections.FirstOrDefault(s => s.Caption.Trim().ToLower() == wellSectionTypeCaption)
?? throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная секция");
if(string.IsNullOrEmpty(modeName))
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} не указан режим");
var idMode = GetIdMode(modeName)
?? throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректный режим");
if (depthStart is < 0 or > 99999.9)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная стартовая глубина");
if (depthEnd is < 0 or > 99999.9)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная конечная глубина");
if (pressurePlan is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение перепада давления");
if (pressureLimitMax is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение перепада давления");
if (axialLoadPlan is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение нагрузки");
if (axialLoadLimitMax is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение нагрузки");
if (topDriveTorquePlan is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение момента на ВСП");
if (topDriveTorqueLimitMax is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение момента на ВСП");
if (topDriveSpeedPlan is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение оборотов на ВСП");
if (topDriveSpeedLimitMax is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничения оборота на ВСП");
if (flowPlan is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение расхода");
if (flowLimitMax is < 0 or > 50000)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение расхода");
if (ropPlan is < 0 or > 99999.9)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение механической скорости");
if (usageSaub is < 0 or > 100)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректный плановый процент использования АКБ");
if (usageSpin is < 0 or > 100)
throw new FileFormatException(
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректные плановый процент использования spin master");
return new()
{
IdWellSectionType = wellSection.Id,
IdMode = idMode,
DepthStart = depthStart,
LastUpdate = DateTime.UtcNow,
DepthEnd = depthEnd,
Pressure = new()
{
Plan = pressurePlan,
LimitMax = pressureLimitMax
},
AxialLoad = new()
{
Plan = axialLoadPlan,
LimitMax = axialLoadLimitMax
},
TopDriveTorque = new()
{
Plan = topDriveTorquePlan,
LimitMax = topDriveTorqueLimitMax
},
TopDriveSpeed = new()
{
Plan = topDriveSpeedPlan,
LimitMax = topDriveSpeedLimitMax
},
Flow = new()
{
Plan = flowPlan,
LimitMax = flowLimitMax
},
RopPlan = ropPlan,
UsageSaub = usageSaub,
UsageSpin = usageSpin,
Comment = comment
};
}
private async Task<Stream> GenerateExcelFileStreamAsync(ProcessMapPlanWellDrillingDto[] processMapPlanWellDrillings,
CancellationToken cancellationToken)
{
using var excelTemplateStream = (await GetExcelTemplateStreamAsync(cancellationToken)).File;
using var workbook = new XLWorkbook(excelTemplateStream);
AddToWorkbook(workbook, processMapPlanWellDrillings);
MemoryStream memoryStream = new();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
private static int? GetIdMode(string modeName) =>
modeName switch
{
"ручной" => 0,
"ротор" => 1,
"слайд" => 2,
_ => null
};
private static string GetModeCaption(int idMode)
=> idMode switch
{
1 => "Ротор",
2 => "Слайд",
_ => "Ручной",
};
}

View File

@ -1,6 +1,9 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Data.WITS;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Interfaces;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
@ -12,9 +15,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.IntegrationEvents;
using AsbCloudApp.IntegrationEvents.Interfaces;
namespace AsbCloudInfrastructure.Services;
@ -32,7 +32,7 @@ public class WellInfoService
{
var wellService = services.GetRequiredService<IWellService>();
var operationsStatService = services.GetRequiredService<IOperationsStatService>();
var processMapPlanWellDrillingRepository = services.GetRequiredService<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>>();
var processMapPlanWellDrillingRepository = services.GetRequiredService<IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell>>();
var subsystemService = services.GetRequiredService<ISubsystemService>();
var telemetryDataSaubCache = services.GetRequiredService<ITelemetryDataCache<TelemetryDataSaubDto>>();
var messageHub = services.GetRequiredService<IIntegrationEventHandler<UpdateWellInfoEvent>>();
@ -42,8 +42,13 @@ public class WellInfoService
var wellsIds = activeWells.Select(w => w.Id);
var processMapPlanWellDrillingRequests = wellsIds.Select(id => new ProcessMapPlanRequest { IdWell = id });
var processMapPlanWellDrillings = await processMapPlanWellDrillingRepository.GetAsync(processMapPlanWellDrillingRequests, token);
var processMapPlanWellDrillingRequests = wellsIds.Select(id => new ProcessMapPlanBaseRequestWithWell(id));
var processMapPlanWellDrillings = new List<ProcessMapPlanDrillingDto>();
foreach (var processMapPlanWellDrillingRequest in processMapPlanWellDrillingRequests)
{
var processMaps = await processMapPlanWellDrillingRepository.Get(processMapPlanWellDrillingRequest, token);
processMapPlanWellDrillings.AddRange(processMaps);
}
var wellDepthByProcessMap = processMapPlanWellDrillings
.GroupBy(p => p.IdWell)
@ -61,7 +66,8 @@ public class WellInfoService
var count = activeWells.Count();
var i = 0d;
WellMapInfo = activeWells.Select(well => {
WellMapInfo = activeWells.Select(well =>
{
var wellMapInfo = well.Adapt<WellMapInfoWithComanies>();
wellMapInfo.IdState = well.IdState;
onProgressCallback($"Start updating info by well({well.Id}): {well.Caption}", i++ / count);
@ -88,7 +94,7 @@ public class WellInfoService
.OrderBy(p => p.DepthEnd);
int? idSection = wellLastFactSection?.Id;
ProcessMapPlanWellDrillingDto? processMapPlanWellDrilling = null;
ProcessMapPlanDrillingDto? processMapPlanWellDrilling = null;
if (idSection.HasValue)
{
@ -112,25 +118,25 @@ public class WellInfoService
wellMapInfo.AxialLoad = new()
{
Plan = processMapPlanWellDrilling?.AxialLoad.Plan,
Plan = processMapPlanWellDrilling?.AxialLoadPlan,
Fact = lastSaubTelemetry?.AxialLoad
};
wellMapInfo.TopDriveSpeed = new()
{
Plan = processMapPlanWellDrilling?.TopDriveSpeed.Plan,
Plan = processMapPlanWellDrilling?.TopDriveSpeedPlan,
Fact = lastSaubTelemetry?.RotorSpeed
};
wellMapInfo.TopDriveTorque = new()
{
Plan = processMapPlanWellDrilling?.TopDriveTorque.Plan,
Plan = processMapPlanWellDrilling?.TopDriveTorquePlan,
Fact = lastSaubTelemetry?.RotorTorque
};
wellMapInfo.Pressure = new()
{
Plan = processMapPlanWellDrilling?.Pressure.Plan,
Plan = processMapPlanWellDrilling?.DeltaPressurePlan,
Fact = lastSaubTelemetry?.Pressure
};
@ -233,7 +239,7 @@ public class WellInfoService
}
public WellMapInfoWithTelemetryStat? FirstOrDefault(Func<WellMapInfoDto, bool> predicate)
{
{
var first = WellMapInfo.FirstOrDefault(predicate);
if (first is WellMapInfoWithComanies wellMapInfoWithComanies)
return Convert(wellMapInfoWithComanies);

View File

@ -1,8 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
@ -19,6 +14,11 @@ using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.DailyReport;
using NSubstitute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace AsbCloudWebApi.Tests.Services;
@ -110,7 +110,7 @@ public class DailyReportServiceTest
}
};
private readonly ProcessMapReportWellDrillingDto fakeProcessMapReportWellDrilling = new()
private readonly ProcessMapReportDataSaubStatDto fakeProcessMapReportWellDrilling = new()
{
DrillingMode = "Ротор",
DateStart = new DateTime(2023, 10, 26),
@ -120,7 +120,7 @@ public class DailyReportServiceTest
Plan = 300,
Fact = 500
},
MechDrillingHours = 100
DrilledTime = 100
};
private readonly WellSectionTypeDto fakeSectionType = new()
@ -207,7 +207,7 @@ public class DailyReportServiceTest
private readonly IScheduleRepository scheduleRepositoryMock = Substitute.For<IScheduleRepository>();
private readonly IWellOperationRepository wellOperationRepositoryMock = Substitute.For<IWellOperationRepository>();
private readonly ISubsystemService subsystemServiceMock = Substitute.For<ISubsystemService>();
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingServiceMock = Substitute.For<IProcessMapReportWellDrillingService>();
private readonly IProcessMapReportDataSaubStatService processMapReportWellDrillingServiceMock = Substitute.For<IProcessMapReportDataSaubStatService>();
private readonly IDetectedOperationService detectedOperationServiceMock = Substitute.For<IDetectedOperationService>();
private readonly DailyReportService dailyReportService;
@ -215,6 +215,7 @@ public class DailyReportServiceTest
private readonly DailyReportDto fakeDailyReport;
private readonly WellDto fakeWell;
private readonly DatesRangeDto fakeDatesRange;
private readonly DataSaubStatRequest fakeRequest = new DataSaubStatRequest();
public DailyReportServiceTest()
{
@ -284,7 +285,7 @@ public class DailyReportServiceTest
scheduleRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeShedule });
processMapReportWellDrillingServiceMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
processMapReportWellDrillingServiceMock.GetAsync(Arg.Any<int>(), fakeRequest, Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeProcessMapReportWellDrilling });
wellServiceMock.GetTimezone(Arg.Any<int>())
@ -461,7 +462,7 @@ public class DailyReportServiceTest
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Plan, processMapWellDrillingRecord.Rop.Plan);
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Fact, processMapWellDrillingRecord.Rop.Fact);
Assert.Equal(fakeProcessMapReportWellDrilling.DeltaDepth, processMapWellDrillingRecord.WellBoreDepth);
Assert.Equal(fakeProcessMapReportWellDrilling.MechDrillingHours, processMapWellDrillingRecord.MechDrillingHours);
Assert.Equal(fakeProcessMapReportWellDrilling.DrilledTime, processMapWellDrillingRecord.MechDrillingHours);
}
[Fact]

View File

@ -1,13 +1,15 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.ProcessMaps;
using NSubstitute;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.ProcessMaps;
using NSubstitute;
using Xunit;
namespace AsbCloudWebApi.Tests.Services.ProcessMaps;
@ -43,17 +45,17 @@ public class ProcessMapPlanServiceTests
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepositoryMock =
Substitute.For<ICrudRepository<WellSectionTypeDto>>();
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanRepositoryMock =
Substitute.For<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>>();
private readonly IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRepositoryMock =
Substitute.For<IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell>>();
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepositoryMock =
Substitute.For<IRepositoryWellRelated<WellSectionPlanDto>>();
private readonly ProcessMapPlanService<ProcessMapPlanWellDrillingDto> processMapPlanService;
private readonly ProcessMapPlanService<ProcessMapPlanDrillingDto> processMapPlanService;
public ProcessMapPlanServiceTests()
{
processMapPlanService = new ProcessMapPlanService<ProcessMapPlanWellDrillingDto>(wellSectionTypeRepositoryMock,
processMapPlanService = new ProcessMapPlanService<ProcessMapPlanDrillingDto>(wellSectionTypeRepositoryMock,
processMapPlanRepositoryMock, wellSectionPlanRepositoryMock);
wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
@ -71,7 +73,7 @@ public class ProcessMapPlanServiceTests
public async Task GetAsync_ReturnsValidatedCollectionProcessMapPlanWellDrilling(int depthStart, int depthEnd, bool isValidCollection)
{
//arrange
var fakeCollectionProcessMapPlanWellDrilling = new ProcessMapPlanWellDrillingDto[]
var fakeCollectionProcessMapPlanWellDrilling = new ProcessMapPlanDrillingDto[]
{
new()
{
@ -81,8 +83,8 @@ public class ProcessMapPlanServiceTests
}
};
processMapPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeCollectionProcessMapPlanWellDrilling);
processMapPlanRepositoryMock.Get(Arg.Any<ProcessMapPlanBaseRequestWithWell>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeCollectionProcessMapPlanWellDrilling);
//act
var result = (await processMapPlanService.GetAsync(idWell, CancellationToken.None)).ToArray();

View File

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
@ -16,6 +11,11 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers.ProcessMaps;
@ -33,11 +33,11 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
private readonly IWellService wellService;
private readonly IUserRepository userRepository;
private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository;
private readonly IProcessMapPlanRepository<T> repository;
private readonly IChangeLogRepository<T, ProcessMapPlanBaseRequestWithWell> repository;
private readonly IProcessMapPlanService<T> service;
protected ProcessMapBaseController(IWellService wellService,
IProcessMapPlanRepository<T> repository,
IChangeLogRepository<T, ProcessMapPlanBaseRequestWithWell> repository,
IUserRepository userRepository,
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
@ -67,7 +67,7 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
return idUser.Value;
}
}
/// <summary>
/// Создание плановой РТК
/// </summary>
@ -81,14 +81,12 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
public virtual async Task<IActionResult> InsertAsync(T processMap, int idWell, CancellationToken cancellationToken)
{
processMap.IdWell = idWell;
processMap.IdUser = IdUser;
processMap.LastUpdate = DateTime.UtcNow;
await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken);
await AssertUserHasAccessToEditProcessMapAsync(processMap.IdWell, cancellationToken);
var result = await repository.InsertAsync(processMap, cancellationToken);
var result = await repository.InsertRange(IdUser, new T[1] { processMap }, cancellationToken);
await NotifyUsersBySignalR(idWell, cancellationToken);
@ -108,14 +106,12 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
public virtual async Task<IActionResult> UpdateAsync(T processMap, int idWell, CancellationToken cancellationToken)
{
processMap.IdWell = idWell;
processMap.IdUser = IdUser;
processMap.LastUpdate = DateTime.UtcNow;
await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken);
await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken);
var result = await repository.UpdateAsync(processMap, cancellationToken);
var result = await repository.UpdateRange(IdUser, new T[1] { processMap }, cancellationToken);
if (result == ICrudRepository<T>.ErrorIdNotFound)
return this.ValidationBadRequest(nameof(processMap.Id), $"РТК с Id: {processMap.Id} не существует");
@ -138,7 +134,7 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
{
await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken);
var result = await repository.DeleteAsync(id, cancellationToken);
var result = await repository.DeleteRange(IdUser, new int[] { id }, cancellationToken);
await NotifyUsersBySignalR(idWell, cancellationToken);
@ -161,7 +157,7 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
if (!processMaps.Any())
return NoContent();
return Ok(processMaps);
}
@ -183,14 +179,11 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
if (!idWell.HasValue)
return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}");
var requests = new[] { new ProcessMapPlanRequest
{
IdWell = idWell.Value,
UpdateFrom = updateFrom
}
};
var request = new ProcessMapPlanBaseRequestWithWell(idWell.Value) {
UpdateFrom = updateFrom,
};
var processMaps = await repository.GetAsync(requests, cancellationToken);
var processMaps = await repository.Get(request, cancellationToken);
return Ok(processMaps);
}
@ -212,7 +205,8 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
protected async Task NotifyUsersBySignalR(int idWell, CancellationToken cancellationToken)
{
var dtos = await repository.GetByIdWellAsync(idWell, cancellationToken);
var request = new ProcessMapPlanBaseRequestWithWell(idWell);
var dtos = await repository.Get(request, cancellationToken);
await telemetryHubContext.Clients
.Group($"{SignalRGroup}_{idWell}")
@ -222,6 +216,6 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken)
{
_ = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken)
?? throw new ArgumentInvalidException(nameof(ProcessMapPlanWellDrillingDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден");
?? throw new ArgumentInvalidException(nameof(ProcessMapPlanDrillingDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден");
}
}

View File

@ -1,5 +1,5 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.ProcessMapPlan;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
@ -11,10 +11,7 @@ using AsbCloudWebApi.SignalR.Clients;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@ -23,28 +20,25 @@ namespace AsbCloudWebApi.Controllers.ProcessMaps;
/// <summary>
/// РТК бурение
/// </summary>
public class ProcessMapWellDrillingController : ProcessMapBaseController<ProcessMapPlanWellDrillingDto>
public class ProcessMapWellDrillingController : ProcessMapBaseController<ProcessMapPlanDrillingDto>
{
private readonly IProcessMapReportDataSaubStatService processMapReportDataSaubStatService;
private readonly IProcessMapReportDataSaubStatExportService processMapReportDataSaubStatExportService;
private readonly IProcessMapPlanImportService processMapPlanImportService;
protected override string SignalRGroup => "ProcessMapWellDrilling";
public ProcessMapWellDrillingController(IWellService wellService,
IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> repository,
IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> repository,
IUserRepository userRepository,
IProcessMapReportDataSaubStatExportService processMapReportDataSaubStatExportService,
IProcessMapPlanImportService processMapPlanImportService,
IProcessMapReportDataSaubStatService processMapReportDataSaubStatService,
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
ITelemetryService telemetryService,
IProcessMapPlanService<ProcessMapPlanWellDrillingDto> service)
IProcessMapPlanService<ProcessMapPlanDrillingDto> service)
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService, service)
{
this.processMapReportDataSaubStatExportService = processMapReportDataSaubStatExportService;
this.processMapPlanImportService = processMapPlanImportService;
this.processMapReportDataSaubStatService = processMapReportDataSaubStatService;
}
@ -83,75 +77,4 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController<Process
return File(report.Value.File, "application/octet-stream", report.Value.Name);
}
/// <summary>
/// Импорт РТК бурение план
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="options"></param>
/// <param name="file"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete]
[HttpPost("import/{options}")]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> ImportAsync(int idWell,
int options,
[Required] IFormFile file,
CancellationToken cancellationToken)
{
await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken);
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
return this.ValidationBadRequest(nameof(file), "Требуется xlsx файл.");
using Stream stream = file.OpenReadStream();
try
{
await processMapPlanImportService.ImportAsync(idWell,
IdUser,
(options & 1) > 0,
stream,
cancellationToken);
await NotifyUsersBySignalR(idWell, cancellationToken);
}
catch (FileFormatException ex)
{
return this.ValidationBadRequest(nameof(file), ex.Message);
}
return Ok();
}
/// <summary>
/// Экспорт РТК бурение план
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete]
[HttpGet("export")]
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> ExportAsync(int idWell, CancellationToken cancellationToken)
{
var processMapsFile = await processMapPlanImportService.ExportAsync(idWell, cancellationToken);
return File(processMapsFile.File, "application/octet-stream", processMapsFile.Name);
}
/// <summary>
/// Возвращает шаблон файла для импорта
/// </summary>
/// <returns>Запрашиваемый файл</returns>
[Obsolete]
[HttpGet("template")]
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
public async Task<IActionResult> GetTemplateAsync(CancellationToken cancellationToken)
{
var template = await processMapPlanImportService.GetExcelTemplateStreamAsync(cancellationToken);
return File(template.File, "application/octet-stream", template.Name);
}
}

View File

@ -1,6 +1,7 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps;
using AsbCloudWebApi.SignalR;
@ -14,16 +15,16 @@ namespace AsbCloudWebApi.Controllers.ProcessMaps;
/// </summary>
public class ProcessMapWellReamController : ProcessMapBaseController<ProcessMapPlanWellReamDto>
{
public ProcessMapWellReamController(IWellService wellService,
IProcessMapPlanRepository<ProcessMapPlanWellReamDto> repository,
IUserRepository userRepository,
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
ITelemetryService telemetryService,
IProcessMapPlanService<ProcessMapPlanWellReamDto> service)
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService, service)
{
}
public ProcessMapWellReamController(IWellService wellService,
IChangeLogRepository<ProcessMapPlanWellReamDto, ProcessMapPlanBaseRequestWithWell> repository,
IUserRepository userRepository,
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
ITelemetryService telemetryService,
IProcessMapPlanService<ProcessMapPlanWellReamDto> service)
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService, service)
{
}
protected override string SignalRGroup => "ProcessMapWellReam";
protected override string SignalRGroup => "ProcessMapWellReam";
}

View File

@ -7,10 +7,10 @@
}
},
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True",
"DebugConnection": "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True",
"DefaultConnection": "Host=localhost;Database=postgres2;Username=postgres;Password=q;Persist Security Info=True",
"DebugConnection": "Host=localhost;Database=postgres2;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True",
"TestConnection": "Host=localhost;Database=test;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True",
"LocalConnection": "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True"
"LocalConnection": "Host=localhost;Database=postgres2;Username=postgres;Password=q;Persist Security Info=True"
},
"AllowedHosts": "*",
"ContentPath": "../data",