forked from ddrilling/AsbCloudServer
Merge current branch with dev
This commit is contained in:
commit
703bd06c15
@ -32,15 +32,4 @@ namespace AsbCloudApp.Data
|
||||
public string? CompanyTypeCaption { get; set; } = null!;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO компании с пользователями
|
||||
/// </summary>
|
||||
public class CompanyWithUsersDto: CompanyDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Пользователи компании
|
||||
/// </summary>
|
||||
public IEnumerable<UserContactDto> Users { get; set; } = Enumerable.Empty<UserContactDto>();
|
||||
}
|
||||
}
|
||||
|
@ -1,91 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
/// <summary>
|
||||
/// РТК
|
||||
/// </summary>
|
||||
public class ProcessMapPlanDto : IId, IWellRelated
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id пользователя, поле заполнять не нужно, подставляется автоматически
|
||||
/// </summary>
|
||||
public int? IdUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id режима 0-ручной, 1-ротор, 2 - слайд
|
||||
/// </summary>
|
||||
[Range(0, 2, ErrorMessage = "Id режима должен быть либо 0-ручной либо, 1-ротор либо 2-слайд")]
|
||||
public int IdMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции
|
||||
/// </summary>
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата последнего изменения
|
||||
/// </summary>
|
||||
public DateTimeOffset LastUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Стартовая глубина
|
||||
/// </summary>
|
||||
[Range(0, 50000, ErrorMessage = "Глубина не может быть отрицательной")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина окончания интервала
|
||||
/// </summary>
|
||||
[Range(0, 50000, ErrorMessage = "Глубина не может быть отрицательной")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Нагрузка
|
||||
/// </summary>
|
||||
public PlanLimitDto AxialLoad { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Перепад давления
|
||||
/// </summary>
|
||||
public PlanLimitDto Pressure { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Момент на ВСП
|
||||
/// </summary>
|
||||
public PlanLimitDto TopDriveTorque { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Обороты на ВСП
|
||||
/// </summary>
|
||||
public PlanLimitDto TopDriveSpeed { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Расход
|
||||
/// </summary>
|
||||
public PlanLimitDto Flow { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Плановая механическая скорость, м/ч
|
||||
/// </summary>
|
||||
public double RopPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Плановый процент использования АКБ
|
||||
/// </summary>
|
||||
public double UsageSaub { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Плановый процент использования spin master
|
||||
/// </summary>
|
||||
public double UsageSpin { get; set; }
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название секции скважины
|
||||
/// </summary>
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название секции скважины
|
||||
/// </summary>
|
||||
public string WellSectionTypeName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу от, м
|
||||
/// <para>
|
||||
/// на начало интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу до, м
|
||||
/// <para>
|
||||
/// на конец интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата/ время
|
||||
/// <para>
|
||||
/// на начало интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public DateTime DateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Время мех бурения, ч
|
||||
/// </summary>
|
||||
public double MechDrillingHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Режим бурения (Ротор/слайд/ручной)
|
||||
/// </summary>
|
||||
public string DrillingMode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Проходка, м
|
||||
/// </summary>
|
||||
public double? DeltaDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Перепад давления, атм
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto PressureDiff { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Нагрузка, т
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto AxialLoad { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Момент на ВСП, кНхМ
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto TopDriveTorque { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Ограничение скорости, м/ч
|
||||
/// </summary>
|
||||
public ProcessMapReportParamsDto SpeedLimit { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Процент использования системы АПД план, %
|
||||
/// </summary>
|
||||
public double UsagePlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Процент использования системы АПД факт, %
|
||||
/// </summary>
|
||||
public double UsageFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Фактическая механическая скорость, м/ч
|
||||
/// </summary>
|
||||
public double? Rop { get; set; }
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
namespace AsbCloudApp.Data.ProcessMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Параметры РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportParamsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Уставка план
|
||||
/// </summary>
|
||||
public double? SetpointPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка факт
|
||||
/// </summary>
|
||||
public double? SetpointFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Факт
|
||||
/// </summary>
|
||||
public double? Fact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ограничение
|
||||
/// </summary>
|
||||
public double? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Процент бурения по уставке, %
|
||||
/// </summary>
|
||||
public double? SetpointUsage { get; set; }
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMap;
|
||||
|
||||
/// <summary>
|
||||
/// РТК план проработка скважины
|
||||
/// </summary>
|
||||
public class ProcessMapWellboreDevelopmentDto : IId, IWellRelated, IValidatableObject
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id пользователя
|
||||
/// </summary>
|
||||
public int IdUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата последнего изменения
|
||||
/// </summary>
|
||||
public DateTimeOffset LastUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Стартовая глубина, м
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение стартовой глубины должно быть в пределах от 0 до 99999.9")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Окончательная глубина, м
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение окончательной глубины должно быть в пределах от 0 до 99999.9")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Количество повторений
|
||||
/// </summary>
|
||||
[Range(0, 100, ErrorMessage = "Значение количества повторений должно быть в пределах от 0 до 100")]
|
||||
public double Repeats { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Вращение при движении вверх, об/мин
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение количества вращений вверх должно быть в пределах от 0 до 99999.9")]
|
||||
public double SpinUpward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Вращение при движении вниз, об/мин
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение количества вращений вниз должно быть в пределах от 0 до 99999.9")]
|
||||
public double SpinDownward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Скорость подъёма, м/ч
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение скорости подъёма должно быть в пределах от 0 до 99999.9")]
|
||||
public double SpeedUpward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Скорость спуска, м/ч
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение скорости спуска должно быть в пределах от 0 до 99999.9")]
|
||||
public double SpeedDownward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка зятяжки, т
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение затяжек уставки должно быть в пределах от 0 до 99999.9")]
|
||||
public double SetpointDrag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка посадки, т
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение посадки уставки должно быть в пределах от 0 до 99999.9")]
|
||||
public double SetpointTight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Давление, атм
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение давления должно быть в пределах от 0 до 99999.9")]
|
||||
public double Pressure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Момент, кН*м
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение крутящего момента должно быть в пределах от 0 до 99999.9")]
|
||||
public double Torque { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Комментарий
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (DepthEnd < DepthStart)
|
||||
yield return new ValidationResult($"{nameof(DepthEnd)}:{DepthEnd:#0.0} меньше {nameof(DepthStart)}:{DepthStart:#0.0}", new[] { nameof(DepthEnd), nameof(DepthStart) });
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
56
AsbCloudApp/Data/ProcessMaps/ProcessMapPlanBaseDto.cs
Normal file
56
AsbCloudApp/Data/ProcessMaps/ProcessMapPlanBaseDto.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMaps;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract class ProcessMapPlanBaseDto : IId, IWellRelated
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id скважины
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id пользователя
|
||||
/// </summary>
|
||||
public int IdUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id секции скважины не может быть меньше 1")]
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата последнего изменения
|
||||
/// </summary>
|
||||
public DateTimeOffset LastUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу от, м
|
||||
/// <para>
|
||||
/// на начало интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Глубина не может быть отрицательной")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу до, м
|
||||
/// <para>
|
||||
/// на конец интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Глубина не может быть отрицательной")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Комментарий
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMaps;
|
||||
|
||||
/// <summary>
|
||||
/// РТК план бурение скважины
|
||||
/// </summary>
|
||||
public class ProcessMapPlanWellDrillingDto : ProcessMapPlanBaseDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id режима 0-ручной, 1-ротор, 2 - слайд
|
||||
/// </summary>
|
||||
[Range(0, 2, ErrorMessage = "Id режима должен быть либо 0-ручной либо, 1-ротор либо 2-слайд")]
|
||||
public int IdMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Нагрузка
|
||||
/// </summary>
|
||||
public PlanLimitDto AxialLoad { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Перепад давления
|
||||
/// </summary>
|
||||
public PlanLimitDto Pressure { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Момент на ВСП
|
||||
/// </summary>
|
||||
public PlanLimitDto TopDriveTorque { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Обороты на ВСП
|
||||
/// </summary>
|
||||
public PlanLimitDto TopDriveSpeed { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Расход
|
||||
/// </summary>
|
||||
public PlanLimitDto Flow { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Плановая механическая скорость, м/ч
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Плановая механическая скорость должно быть в пределах от 0 до 99999.9")]
|
||||
public double RopPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Плановый процент использования АКБ
|
||||
/// </summary>
|
||||
[Range(0, 100, ErrorMessage = "Процент использования АКБ должен быть в пределах от 0 до 100")]
|
||||
public double UsageSaub { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Плановый процент использования spin master
|
||||
/// </summary>
|
||||
[Range(0, 100, ErrorMessage = "Процент использования spin master должен быть в пределах от 0 до 100")]
|
||||
public double UsageSpin { get; set; }
|
||||
}
|
73
AsbCloudApp/Data/ProcessMaps/ProcessMapPlanWellReamDto.cs
Normal file
73
AsbCloudApp/Data/ProcessMaps/ProcessMapPlanWellReamDto.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMaps;
|
||||
|
||||
/// <summary>
|
||||
/// РТК план проработка скважины
|
||||
/// </summary>
|
||||
public class ProcessMapPlanWellReamDto : ProcessMapPlanBaseDto, IValidatableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Количество повторений
|
||||
/// </summary>
|
||||
[Range(0, 100, ErrorMessage = "Количество повторений должно быть в пределах от 0 до 100")]
|
||||
public double Repeats { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Вращение при движении вверх, об/мин
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Количество вращений вверх должно быть в пределах от 0 до 99999.9")]
|
||||
public double SpinUpward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Вращение при движении вниз, об/мин
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Количество вращений вниз должно быть в пределах от 0 до 99999.9")]
|
||||
public double SpinDownward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Скорость подъёма, м/ч
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Скорость подъёма должна быть в пределах от 0 до 99999.9")]
|
||||
public double SpeedUpward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Скорость спуска, м/ч
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Скорость спуска должна быть в пределах от 0 до 99999.9")]
|
||||
public double SpeedDownward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка зятяжки, т
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение затяжек уставки должно быть в пределах от 0 до 99999.9")]
|
||||
public double SetpointDrag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка посадки, т
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Значение посадки уставки должно быть в пределах от 0 до 99999.9")]
|
||||
public double SetpointTight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Давление, атм
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Давление должно быть в пределах от 0 до 99999.9")]
|
||||
public double Pressure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Момент, кН*м
|
||||
/// </summary>
|
||||
[Range(0, 99999.9, ErrorMessage = "Крутящий момент должен быть в пределах от 0 до 99999.9")]
|
||||
public double Torque { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (DepthEnd < DepthStart)
|
||||
yield return new ValidationResult(
|
||||
$"{nameof(DepthEnd)}:{DepthEnd:#0.0} меньше {nameof(DepthStart)}:{DepthStart:#0.0}",
|
||||
new[] { nameof(DepthEnd), nameof(DepthStart) });
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.ProcessMaps.Report;
|
||||
|
||||
/// <summary>
|
||||
/// Модель РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportWellDrillingDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id секции скважины
|
||||
/// </summary>
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название секции скважины
|
||||
/// </summary>
|
||||
public string WellSectionTypeName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу от, м
|
||||
/// <para>
|
||||
/// на начало интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу до, м
|
||||
/// <para>
|
||||
/// на конец интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата/ время
|
||||
/// <para>
|
||||
/// на начало интервала
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public DateTime DateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Время мех бурения, ч
|
||||
/// </summary>
|
||||
public double MechDrillingHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Режим бурения (Ротор/слайд/ручной)
|
||||
/// </summary>
|
||||
public string DrillingMode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Проходка, м
|
||||
/// </summary>
|
||||
public double? DeltaDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Перепад давления, атм
|
||||
/// </summary>
|
||||
public ProcessMapReportWellDrillingParamsDto PressureDiff { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Нагрузка, т
|
||||
/// </summary>
|
||||
public ProcessMapReportWellDrillingParamsDto AxialLoad { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Момент на ВСП, кНхМ
|
||||
/// </summary>
|
||||
public ProcessMapReportWellDrillingParamsDto TopDriveTorque { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Ограничение скорости, м/ч
|
||||
/// </summary>
|
||||
public ProcessMapReportWellDrillingParamsDto SpeedLimit { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Процент использования системы АПД план, %
|
||||
/// </summary>
|
||||
public double UsagePlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Процент использования системы АПД факт, %
|
||||
/// </summary>
|
||||
public double UsageFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Фактическая механическая скорость, м/ч
|
||||
/// </summary>
|
||||
public double? Rop { get; set; }
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
namespace AsbCloudApp.Data.ProcessMaps.Report;
|
||||
|
||||
/// <summary>
|
||||
/// Параметры РТК
|
||||
/// </summary>
|
||||
public class ProcessMapReportWellDrillingParamsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Уставка план
|
||||
/// </summary>
|
||||
public double? SetpointPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Уставка факт
|
||||
/// </summary>
|
||||
public double? SetpointFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Факт
|
||||
/// </summary>
|
||||
public double? Fact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ограничение
|
||||
/// </summary>
|
||||
public double? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Процент бурения по уставке, %
|
||||
/// </summary>
|
||||
public double? SetpointUsage { get; set; }
|
||||
}
|
63
AsbCloudApp/Data/User/ContactDto.cs
Normal file
63
AsbCloudApp/Data/User/ContactDto.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.User
|
||||
{
|
||||
/// <summary>
|
||||
/// Контакт
|
||||
/// </summary>
|
||||
|
||||
public class ContactDto : IId
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ключ типа компании
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdCompanyType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ключ скважины
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ФИО
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(260, MinimumLength = 0, ErrorMessage = "Допустимая длина ФИО от 1 до 260 символов")]
|
||||
public string FullName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Email
|
||||
/// </summary>
|
||||
[Required]
|
||||
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Некорректный email")]
|
||||
public string Email { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Phone
|
||||
/// </summary>
|
||||
[Required]
|
||||
[RegularExpression(@"^(?:\+7|8)\s?(?:\(\d{3}\)|\d{3})\s?\d{3}-?\d{2}-?\d{2}$", ErrorMessage = "Некорректный номер телефона")]
|
||||
public string Phone { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Должность
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(260, MinimumLength = 1, ErrorMessage = "Допустимая длина должности от 1 до 260 символов")]
|
||||
public string Position { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Компания
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(260, MinimumLength = 3, ErrorMessage = "Допустимая длина должности от 3 до 260 символов")]
|
||||
public string Company { get; set; } = null!;
|
||||
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
namespace AsbCloudApp.Data.User
|
||||
{
|
||||
/// <summary>
|
||||
/// Пользователь - контакт
|
||||
/// </summary>
|
||||
|
||||
public class UserContactDto : UserDto
|
||||
{
|
||||
/// <summary>
|
||||
/// является ли пользователь контактом
|
||||
/// </summary>
|
||||
public bool IsContact { get; set; }
|
||||
}
|
||||
}
|
30
AsbCloudApp/Repositories/IProcessMapPlanRepository.cs
Normal file
30
AsbCloudApp/Repositories/IProcessMapPlanRepository.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
|
||||
namespace AsbCloudApp.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// РТК план
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// РТК-план
|
||||
/// </summary>
|
||||
public interface IProcessMapPlanRepository : IRepositoryWellRelated<ProcessMapPlanDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить РТК-план начиная с даты.
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="updateFrom"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapPlanDto>> GetAllAsync(int idWell,
|
||||
DateTime? updateFrom, CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получить РТК-план
|
||||
/// </summary>
|
||||
/// <param name="requests"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapPlanDto>> GetProcessMapAsync(IEnumerable<ProcessMapRequest> requests,
|
||||
CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить РТК-план по скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> RemoveByWellAsync(int idWell, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Services;
|
||||
|
||||
namespace AsbCloudApp.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Репозиторий для проработки скважины
|
||||
/// </summary>
|
||||
public interface IProcessMapWellboreDevelopmentRepository : IRepositoryWellRelated<ProcessMapWellboreDevelopmentDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить проработку начиная с даты
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="updateFrom"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapWellboreDevelopmentDto>> GetAllAsync(int idWell, DateTime? updateFrom, CancellationToken cancellationToken);
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
|
||||
namespace AsbCloudApp.Repositories
|
||||
{
|
||||
@ -29,11 +29,11 @@ namespace AsbCloudApp.Repositories
|
||||
Task<int> SaveAsync(int idWell, IEnumerable<WellCompositeDto> wellComposites, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение РТК по композитной скважине
|
||||
/// Получение РТК-план бурение по композитной скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapPlanDto>> GetCompositeProcessMap(int idWell, CancellationToken token);
|
||||
Task<IEnumerable<ProcessMapPlanWellDrillingDto>> GetCompositeProcessMap(int idWell, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
24
AsbCloudApp/Requests/ProcessMapPlanRequest.cs
Normal file
24
AsbCloudApp/Requests/ProcessMapPlanRequest.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Запрос для получения РТК план
|
||||
/// </summary>
|
||||
public class ProcessMapPlanRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции
|
||||
/// </summary>
|
||||
public int? IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата обновления
|
||||
/// </summary>
|
||||
public DateTime? UpdateFrom { get; set; }
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Requests
|
||||
{
|
||||
/// <summary>
|
||||
/// Параметры для запроса получения РТК
|
||||
/// </summary>
|
||||
public class ProcessMapRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции
|
||||
/// </summary>
|
||||
public int? IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата обновления
|
||||
/// </summary>
|
||||
public DateTime? UpdateFrom { get; set; }
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис импорта/экспорта для РТК вводимых вручную
|
||||
/// </summary>
|
||||
public interface IProcessMapPlanImportService
|
||||
{
|
||||
/// <summary>
|
||||
/// Загрузить данные из файла
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="deleteProcessMapPlansBeforeImport"></param>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task ImportAsync(int idWell, int idUser, bool deleteProcessMapPlansBeforeImport, Stream stream,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Сформировать файл с данными
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<Stream> ExportAsync(int idWell, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получение шаблона для заполнения
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Сервис формирования РТК.
|
||||
/// </summary>
|
||||
public interface IProcessMapReportMakerService
|
||||
{
|
||||
/// <summary>
|
||||
/// Сформировать.
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<Stream> MakeReportAsync(int idWell, CancellationToken token = default);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Сервис РТК
|
||||
/// </summary>
|
||||
public interface IProcessMapService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение моделей РТК
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapReportDto>> GetProcessMapReportAsync(int idWell, CancellationToken token);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис для проработок скважины
|
||||
/// </summary>
|
||||
public interface IProcessMapWellboreDevelopmentService
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавить запись проработки
|
||||
/// </summary>
|
||||
/// <param name="processMapWellboreDevelopment"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> InsertAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить запись проработки
|
||||
/// </summary>
|
||||
/// <param name="processMapWellboreDevelopment"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получить записи проработок по уникальному ключу телеметрии
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="updateFrom"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ProcessMapWellboreDevelopmentDto>> GetByTelemetryAsync(string uid, DateTime updateFrom,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.User;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -11,30 +12,53 @@ namespace AsbCloudApp.Services
|
||||
public interface IWellContactService
|
||||
{
|
||||
/// <summary>
|
||||
/// Полуение пользователей по ключу скважины и типу контакта
|
||||
/// Получение контактов по ключу скважины и типу контакта
|
||||
/// </summary>
|
||||
/// <param name="wellId">ключ скважины</param>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="contactTypeId">тип контакта</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<CompanyWithUsersDto>> GetAsync(int wellId, int contactTypeId, CancellationToken token);
|
||||
Task<IEnumerable<ContactDto>> GetAllAsync(int idWell, int contactTypeId, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение типов контаков
|
||||
/// Получение контакта по ключу
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="id">ключ пользователя</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<CompanyTypeDto>> GetTypesAsync(int idWell, CancellationToken token);
|
||||
Task<ContactDto?> GetAsync(int idWell, int id, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновление контактов по ключу скважины, типу контакта и ключам пользователей
|
||||
/// Получение типов контактов
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="contactTypeId">ключ типа контакта</param>
|
||||
/// <param name="userIds">ключи пользователей</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateRangeAsync(int idWell, int contactTypeId, IEnumerable<int> userIds, CancellationToken token);
|
||||
Task<IEnumerable<CompanyTypeDto>> GetTypesAsync(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление контакта
|
||||
/// </summary>
|
||||
/// <param name="contactDto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> InsertAsync(ContactDto contactDto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Изменение контакта
|
||||
/// </summary>
|
||||
/// <param name="contactDto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateAsync(ContactDto contactDto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление контакта
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="id">ключ скважины</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteAsync(int idWell, int id, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace AsbCloudApp.Services.ProcessMaps;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис импорта РТК
|
||||
/// </summary>
|
||||
public interface IProcessMapPlanImportService
|
||||
{
|
||||
/// <summary>
|
||||
/// Загрузить данные из файла
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="deleteBeforeImport"></param>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task ImportAsync(int idWell, int idUser, bool deleteBeforeImport, Stream stream,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Сформировать файл с данными
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<(string Name, Stream File)> ExportAsync(int idWell, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Получение шаблона для заполнения
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<(string Name, Stream File)> GetExcelTemplateStreamAsync(CancellationToken cancellationToken);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
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);
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
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);
|
||||
}
|
8731
AsbCloudDb/Migrations/20231012063505_Add_Contacts.Designer.cs
generated
Normal file
8731
AsbCloudDb/Migrations/20231012063505_Add_Contacts.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
49
AsbCloudDb/Migrations/20231012063505_Add_Contacts.cs
Normal file
49
AsbCloudDb/Migrations/20231012063505_Add_Contacts.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_Contacts : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_contact",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
id_company_type = table.Column<int>(type: "integer", maxLength: 255, nullable: false, comment: "вид деятельности"),
|
||||
fio = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false, comment: "ФИО"),
|
||||
email = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false, comment: "email"),
|
||||
phone = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false, comment: "номер телефона"),
|
||||
position = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false, comment: "должность"),
|
||||
company = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false, comment: "компания")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_contact", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_contact_t_company_type_id_company_type",
|
||||
column: x => x.id_company_type,
|
||||
principalTable: "t_company_type",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Контакты");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_contact_id_company_type",
|
||||
table: "t_contact",
|
||||
column: "id_company_type");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_contact");
|
||||
}
|
||||
}
|
||||
}
|
8742
AsbCloudDb/Migrations/20231012063841_Add_Permission_Delete_To_Well_Contact.Designer.cs
generated
Normal file
8742
AsbCloudDb/Migrations/20231012063841_Add_Permission_Delete_To_Well_Contact.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_Permission_Delete_To_Well_Contact : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_permission",
|
||||
columns: new[] { "id", "description", "name" },
|
||||
values: new object[] { 528, "Разрешение на удаление контакта", "WellContact.delete" });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_relation_user_role_permission",
|
||||
columns: new[] { "id_permission", "id_user_role" },
|
||||
values: new object[] { 528, 1 });
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 528, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 528);
|
||||
}
|
||||
}
|
||||
}
|
8760
AsbCloudDb/Migrations/20231012064318_Add_Well_To_Contacts.Designer.cs
generated
Normal file
8760
AsbCloudDb/Migrations/20231012064318_Add_Well_To_Contacts.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
49
AsbCloudDb/Migrations/20231012064318_Add_Well_To_Contacts.cs
Normal file
49
AsbCloudDb/Migrations/20231012064318_Add_Well_To_Contacts.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_Well_To_Contacts : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "id_well",
|
||||
table: "t_contact",
|
||||
type: "integer",
|
||||
maxLength: 255,
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
comment: "ключ скважины");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_contact_id_well",
|
||||
table: "t_contact",
|
||||
column: "id_well");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_contact_t_well_id_well",
|
||||
table: "t_contact",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_contact_t_well_id_well",
|
||||
table: "t_contact");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_t_contact_id_well",
|
||||
table: "t_contact");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "id_well",
|
||||
table: "t_contact");
|
||||
}
|
||||
}
|
||||
}
|
8654
AsbCloudDb/Migrations/20231012070239_Update_Process_Maps.Designer.cs
generated
Normal file
8654
AsbCloudDb/Migrations/20231012070239_Update_Process_Maps.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
428
AsbCloudDb/Migrations/20231012070239_Update_Process_Maps.cs
Normal file
428
AsbCloudDb/Migrations/20231012070239_Update_Process_Maps.cs
Normal file
@ -0,0 +1,428 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Update_Process_Maps : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_t_well_section_type_id_wellsection_type",
|
||||
table: "t_process_map");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_t_well_well_id",
|
||||
table: "t_process_map");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_wellbore_development_t_user_id_user",
|
||||
table: "t_process_map_wellbore_development");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_wellbore_development_t_well_id_well",
|
||||
table: "t_process_map_wellbore_development");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_process_map_wellbore_development",
|
||||
table: "t_process_map_wellbore_development");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_process_map",
|
||||
table: "t_process_map");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 513, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 514, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 515, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 513);
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 514);
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 515);
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_process_map_wellbore_development",
|
||||
newName: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_process_map",
|
||||
newName: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_wellbore_development_id_well",
|
||||
table: "t_process_map_well_ream",
|
||||
newName: "IX_t_process_map_well_ream_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_wellbore_development_id_user",
|
||||
table: "t_process_map_well_ream",
|
||||
newName: "IX_t_process_map_well_ream_id_user");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "well_id",
|
||||
table: "t_process_map_well_drilling",
|
||||
newName: "id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_well_id",
|
||||
table: "t_process_map_well_drilling",
|
||||
newName: "IX_t_process_map_well_drilling_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_id_wellsection_type",
|
||||
table: "t_process_map_well_drilling",
|
||||
newName: "IX_t_process_map_well_drilling_id_wellsection_type");
|
||||
|
||||
migrationBuilder.AlterTable(
|
||||
name: "t_process_map_well_ream",
|
||||
comment: "РТК проработка скважины",
|
||||
oldComment: "РТК план проработка скважины");
|
||||
|
||||
migrationBuilder.AlterTable(
|
||||
name: "t_process_map_well_drilling",
|
||||
comment: "РТК бурение скважины",
|
||||
oldComment: "Операции по скважине – РТК");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_start",
|
||||
table: "t_process_map_well_ream",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Глубина по стволу от, м",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Стартовая глубина, м");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_end",
|
||||
table: "t_process_map_well_ream",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Глубина по стволу до, м",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Окончательная глубина, м");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "id_wellsection_type",
|
||||
table: "t_process_map_well_ream",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
comment: "Тип секции");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_start",
|
||||
table: "t_process_map_well_drilling",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Глубина по стволу от, м",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Стартовая глубина");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_end",
|
||||
table: "t_process_map_well_drilling",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Глубина по стволу до, м",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Глубина окончания интервала");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "comment",
|
||||
table: "t_process_map_well_drilling",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
comment: "Комментарий");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_process_map_well_ream",
|
||||
table: "t_process_map_well_ream",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_process_map_well_drilling",
|
||||
table: "t_process_map_well_drilling",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_process_map_well_ream_id_wellsection_type",
|
||||
table: "t_process_map_well_ream",
|
||||
column: "id_wellsection_type");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_process_map_well_drilling_id_user",
|
||||
table: "t_process_map_well_drilling",
|
||||
column: "id_user");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_well_drilling_t_user_id_user",
|
||||
table: "t_process_map_well_drilling",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_well_drilling_t_well_id_well",
|
||||
table: "t_process_map_well_drilling",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_well_drilling_t_well_section_type_id_wellsect~",
|
||||
table: "t_process_map_well_drilling",
|
||||
column: "id_wellsection_type",
|
||||
principalTable: "t_well_section_type",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_well_ream_t_user_id_user",
|
||||
table: "t_process_map_well_ream",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_well_ream_t_well_id_well",
|
||||
table: "t_process_map_well_ream",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_well_ream_t_well_section_type_id_wellsection_~",
|
||||
table: "t_process_map_well_ream",
|
||||
column: "id_wellsection_type",
|
||||
principalTable: "t_well_section_type",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_well_drilling_t_user_id_user",
|
||||
table: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_well_drilling_t_well_id_well",
|
||||
table: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_well_drilling_t_well_section_type_id_wellsect~",
|
||||
table: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_well_ream_t_user_id_user",
|
||||
table: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_well_ream_t_well_id_well",
|
||||
table: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_process_map_well_ream_t_well_section_type_id_wellsection_~",
|
||||
table: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_process_map_well_ream",
|
||||
table: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_t_process_map_well_ream_id_wellsection_type",
|
||||
table: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_process_map_well_drilling",
|
||||
table: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_t_process_map_well_drilling_id_user",
|
||||
table: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "id_wellsection_type",
|
||||
table: "t_process_map_well_ream");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "comment",
|
||||
table: "t_process_map_well_drilling");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_process_map_well_ream",
|
||||
newName: "t_process_map_wellbore_development");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_process_map_well_drilling",
|
||||
newName: "t_process_map");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_well_ream_id_well",
|
||||
table: "t_process_map_wellbore_development",
|
||||
newName: "IX_t_process_map_wellbore_development_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_well_ream_id_user",
|
||||
table: "t_process_map_wellbore_development",
|
||||
newName: "IX_t_process_map_wellbore_development_id_user");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "id_well",
|
||||
table: "t_process_map",
|
||||
newName: "well_id");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_well_drilling_id_wellsection_type",
|
||||
table: "t_process_map",
|
||||
newName: "IX_t_process_map_id_wellsection_type");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_process_map_well_drilling_id_well",
|
||||
table: "t_process_map",
|
||||
newName: "IX_t_process_map_well_id");
|
||||
|
||||
migrationBuilder.AlterTable(
|
||||
name: "t_process_map_wellbore_development",
|
||||
comment: "РТК план проработка скважины",
|
||||
oldComment: "РТК проработка скважины");
|
||||
|
||||
migrationBuilder.AlterTable(
|
||||
name: "t_process_map",
|
||||
comment: "Операции по скважине – РТК",
|
||||
oldComment: "РТК бурение скважины");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_start",
|
||||
table: "t_process_map_wellbore_development",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Стартовая глубина, м",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Глубина по стволу от, м");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_end",
|
||||
table: "t_process_map_wellbore_development",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Окончательная глубина, м",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Глубина по стволу до, м");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_start",
|
||||
table: "t_process_map",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Стартовая глубина",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Глубина по стволу от, м");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "depth_end",
|
||||
table: "t_process_map",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
comment: "Глубина окончания интервала",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double precision",
|
||||
oldComment: "Глубина по стволу до, м");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_process_map_wellbore_development",
|
||||
table: "t_process_map_wellbore_development",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_process_map",
|
||||
table: "t_process_map",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_permission",
|
||||
columns: new[] { "id", "description", "name" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ 513, "Разрешение просматривать РТК", "ProcessMap.get" },
|
||||
{ 514, "Разрешение редактировать РТК", "ProcessMap.edit" },
|
||||
{ 515, "Разрешение удалять РТК", "ProcessMap.delete" }
|
||||
});
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_relation_user_role_permission",
|
||||
columns: new[] { "id_permission", "id_user_role" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ 513, 1 },
|
||||
{ 514, 1 },
|
||||
{ 515, 1 }
|
||||
});
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_t_well_section_type_id_wellsection_type",
|
||||
table: "t_process_map",
|
||||
column: "id_wellsection_type",
|
||||
principalTable: "t_well_section_type",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_t_well_well_id",
|
||||
table: "t_process_map",
|
||||
column: "well_id",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_wellbore_development_t_user_id_user",
|
||||
table: "t_process_map_wellbore_development",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_process_map_wellbore_development_t_well_id_well",
|
||||
table: "t_process_map_wellbore_development",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
8760
AsbCloudDb/Migrations/20231013103735_Update_WellContacts_Set_FullName.Designer.cs
generated
Normal file
8760
AsbCloudDb/Migrations/20231013103735_Update_WellContacts_Set_FullName.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Update_WellContacts_Set_FullName : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "fio",
|
||||
table: "t_contact",
|
||||
newName: "full_name");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "full_name",
|
||||
table: "t_contact",
|
||||
newName: "fio");
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ namespace AsbCloudDb.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.UseCollation("Russian_Russia.1251")
|
||||
.HasAnnotation("ProductVersion", "6.0.7")
|
||||
.HasAnnotation("ProductVersion", "6.0.22")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||
@ -154,6 +154,73 @@ namespace AsbCloudDb.Migrations
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Contact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Company")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("company")
|
||||
.HasComment("компания");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("email")
|
||||
.HasComment("email");
|
||||
|
||||
b.Property<string>("FullName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("full_name")
|
||||
.HasComment("ФИО");
|
||||
|
||||
b.Property<int>("IdCompanyType")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_company_type")
|
||||
.HasComment("вид деятельности");
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ключ скважины");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)")
|
||||
.HasColumnName("phone")
|
||||
.HasComment("номер телефона");
|
||||
|
||||
b.Property<string>("Position")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)")
|
||||
.HasColumnName("position")
|
||||
.HasComment("должность");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdCompanyType");
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_contact");
|
||||
|
||||
b.HasComment("Контакты");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b =>
|
||||
{
|
||||
b.Property<int>("IdWell")
|
||||
@ -2272,24 +2339,6 @@ namespace AsbCloudDb.Migrations
|
||||
Name = "PlannedTrajectory.delete"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 513,
|
||||
Description = "Разрешение просматривать РТК",
|
||||
Name = "ProcessMap.get"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 514,
|
||||
Description = "Разрешение редактировать РТК",
|
||||
Name = "ProcessMap.edit"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 515,
|
||||
Description = "Разрешение удалять РТК",
|
||||
Name = "ProcessMap.delete"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 516,
|
||||
Description = "Разрешение просматривать статистику вопросов",
|
||||
@ -2360,6 +2409,12 @@ namespace AsbCloudDb.Migrations
|
||||
Id = 527,
|
||||
Description = "Разрешение на удаление инструкций",
|
||||
Name = "Manual.delete"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 528,
|
||||
Description = "Разрешение на удаление контакта",
|
||||
Name = "WellContact.delete"
|
||||
});
|
||||
});
|
||||
|
||||
@ -2433,7 +2488,7 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasComment("Загрузка плановой траектории");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMap", b =>
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
@ -2452,15 +2507,20 @@ namespace AsbCloudDb.Migrations
|
||||
.HasColumnName("axial_load_plan")
|
||||
.HasComment("Нагрузка, план");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("comment")
|
||||
.HasComment("Комментарий");
|
||||
|
||||
b.Property<double>("DepthEnd")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_end")
|
||||
.HasComment("Глубина окончания интервала");
|
||||
.HasComment("Глубина по стволу до, м");
|
||||
|
||||
b.Property<double>("DepthStart")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_start")
|
||||
.HasComment("Стартовая глубина");
|
||||
.HasComment("Глубина по стволу от, м");
|
||||
|
||||
b.Property<double>("FlowLimitMax")
|
||||
.HasColumnType("double precision")
|
||||
@ -2484,7 +2544,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("well_id")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("Id скважины");
|
||||
|
||||
b.Property<int>("IdWellSectionType")
|
||||
@ -2544,16 +2604,18 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.HasIndex("IdWellSectionType");
|
||||
|
||||
b.ToTable("t_process_map");
|
||||
b.ToTable("t_process_map_well_drilling");
|
||||
|
||||
b.HasComment("Операции по скважине – РТК");
|
||||
b.HasComment("РТК бурение скважины");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMapWellboreDevelopment", b =>
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellReam", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
@ -2570,12 +2632,12 @@ namespace AsbCloudDb.Migrations
|
||||
b.Property<double>("DepthEnd")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_end")
|
||||
.HasComment("Окончательная глубина, м");
|
||||
.HasComment("Глубина по стволу до, м");
|
||||
|
||||
b.Property<double>("DepthStart")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("depth_start")
|
||||
.HasComment("Стартовая глубина, м");
|
||||
.HasComment("Глубина по стволу от, м");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
@ -2587,6 +2649,11 @@ namespace AsbCloudDb.Migrations
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("Id скважины");
|
||||
|
||||
b.Property<int>("IdWellSectionType")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_wellsection_type")
|
||||
.HasComment("Тип секции");
|
||||
|
||||
b.Property<DateTimeOffset>("LastUpdate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("last_update")
|
||||
@ -2643,9 +2710,11 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_process_map_wellbore_development");
|
||||
b.HasIndex("IdWellSectionType");
|
||||
|
||||
b.HasComment("РТК план проработка скважины");
|
||||
b.ToTable("t_process_map_well_ream");
|
||||
|
||||
b.HasComment("РТК проработка скважины");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b =>
|
||||
@ -3949,21 +4018,6 @@ namespace AsbCloudDb.Migrations
|
||||
IdPermission = 512
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 513
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 514
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 515
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 516
|
||||
@ -4022,6 +4076,11 @@ namespace AsbCloudDb.Migrations
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 527
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 528
|
||||
});
|
||||
});
|
||||
|
||||
@ -7799,6 +7858,25 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("CompanyType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Contact", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.CompanyType", "CompanyType")
|
||||
.WithMany("Contacts")
|
||||
.HasForeignKey("IdCompanyType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany("Contacts")
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CompanyType");
|
||||
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
@ -8101,26 +8179,7 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMap", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany("ProcessMaps")
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWellSectionType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Well");
|
||||
|
||||
b.Navigation("WellSectionType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMapWellboreDevelopment", b =>
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "User")
|
||||
.WithMany()
|
||||
@ -8134,9 +8193,44 @@ namespace AsbCloudDb.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWellSectionType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
|
||||
b.Navigation("Well");
|
||||
|
||||
b.Navigation("WellSectionType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellReam", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdUser")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWellSectionType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
|
||||
b.Navigation("Well");
|
||||
|
||||
b.Navigation("WellSectionType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b =>
|
||||
@ -8648,6 +8742,8 @@ namespace AsbCloudDb.Migrations
|
||||
modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b =>
|
||||
{
|
||||
b.Navigation("Companies");
|
||||
|
||||
b.Navigation("Contacts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Deposit", b =>
|
||||
@ -8734,9 +8830,9 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Well", b =>
|
||||
{
|
||||
b.Navigation("DrillingProgramParts");
|
||||
b.Navigation("Contacts");
|
||||
|
||||
b.Navigation("ProcessMaps");
|
||||
b.Navigation("DrillingProgramParts");
|
||||
|
||||
b.Navigation("RelationCompaniesWells");
|
||||
|
||||
|
@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
@ -16,8 +17,8 @@ namespace AsbCloudDb.Model
|
||||
public virtual DbSet<Deposit> Deposits => Set<Deposit>();
|
||||
public virtual DbSet<DetectedOperation> DetectedOperations => Set<DetectedOperation>();
|
||||
public virtual DbSet<PlannedTrajectory> PlannedTrajectories => Set<PlannedTrajectory>();
|
||||
public virtual DbSet<ProcessMap> ProcessMap => Set<ProcessMap>();
|
||||
public virtual DbSet<ProcessMapWellboreDevelopment> ProcessMapWellboreDevelopments => Set<ProcessMapWellboreDevelopment>();
|
||||
public virtual DbSet<ProcessMapWellDrilling> ProcessMapWellDrillings => Set<ProcessMapWellDrilling>();
|
||||
public virtual DbSet<ProcessMapWellReam> ProcessMapWellReams => Set<ProcessMapWellReam>();
|
||||
public virtual DbSet<DrillingProgramPart> DrillingProgramParts => Set<DrillingProgramPart>();
|
||||
public virtual DbSet<FileCategory> FileCategories => Set<FileCategory>();
|
||||
public virtual DbSet<FileInfo> Files => Set<FileInfo>();
|
||||
@ -81,6 +82,8 @@ namespace AsbCloudDb.Model
|
||||
public DbSet<NotificationCategory> NotificationCategories => Set<NotificationCategory>();
|
||||
public DbSet<Manual> Manuals => Set<Manual>();
|
||||
public DbSet<ManualDirectory> ManualDirectories => Set<ManualDirectory>();
|
||||
public DbSet<Contact> Contacts => Set<Contact>();
|
||||
|
||||
public DbSet<DrillTest> DrillTests => Set<DrillTest>();
|
||||
public DbSet<DrillTestParameter> DrillTestParameters => Set<DrillTestParameter>();
|
||||
public AsbCloudDbContext() : base()
|
||||
|
@ -21,5 +21,8 @@ namespace AsbCloudDb.Model
|
||||
|
||||
[InverseProperty(nameof(Company.CompanyType))]
|
||||
public virtual ICollection<Company> Companies { get; set; } = null!;
|
||||
|
||||
[InverseProperty(nameof(Contact.CompanyType))]
|
||||
public virtual ICollection<Contact> Contacts { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
51
AsbCloudDb/Model/Contact.cs
Normal file
51
AsbCloudDb/Model/Contact.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_contact"), Comment("Контакты")]
|
||||
public partial class Contact : IId
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("id_company_type"), Comment("вид деятельности")]
|
||||
[StringLength(255)]
|
||||
public int IdCompanyType { get; set; }
|
||||
|
||||
[Column("id_well"), Comment("ключ скважины")]
|
||||
[StringLength(255)]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
[Column("full_name"), Comment("ФИО")]
|
||||
[StringLength(255)]
|
||||
public string FullName { get; set; } = string.Empty;
|
||||
|
||||
[Column("email"), Comment("email")]
|
||||
[StringLength(255)]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[Column("phone"), Comment("номер телефона")]
|
||||
[StringLength(50)]
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
|
||||
[Column("position"), Comment("должность")]
|
||||
[StringLength(255)]
|
||||
public string Position { get; set; } = string.Empty;
|
||||
|
||||
[Column("company"), Comment("компания")]
|
||||
[StringLength(255)]
|
||||
public string Company { get; set; } = string.Empty;
|
||||
|
||||
[ForeignKey(nameof(IdCompanyType))]
|
||||
[InverseProperty(nameof(Model.CompanyType.Contacts))]
|
||||
public virtual CompanyType CompanyType { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
[InverseProperty(nameof(Model.Well.Contacts))]
|
||||
public virtual Well Well { get; set; } = null!;
|
||||
}
|
||||
}
|
@ -142,10 +142,6 @@
|
||||
new (){ Id = 511, Name="PlannedTrajectory.edit", Description="Разрешение редактировать плановая траектория"},
|
||||
new (){ Id = 512, Name="PlannedTrajectory.delete", Description="Разрешение удалять плановая траектория"},
|
||||
|
||||
new (){ Id = 513, Name="ProcessMap.get", Description="Разрешение просматривать РТК"},
|
||||
new (){ Id = 514, Name="ProcessMap.edit", Description="Разрешение редактировать РТК"},
|
||||
new (){ Id = 515, Name="ProcessMap.delete", Description="Разрешение удалять РТК"},
|
||||
|
||||
new (){ Id = 516, Name="FaqStatistics.get", Description="Разрешение просматривать статистику вопросов"},
|
||||
new (){ Id = 517, Name="FaqStatistics.edit", Description="Разрешение редактировать вопрос"},
|
||||
new (){ Id = 518, Name="FaqStatistics.delete", Description="Разрешение удалять вопрос"},
|
||||
@ -163,7 +159,8 @@
|
||||
new (){ Id = 525, Name = "ProcessMap.editCompletedWell", Description = "Разрешение на редактирование РТК у завершенной скважины"},
|
||||
new (){ Id = 526, Name = "WellOperation.editCompletedWell", Description = "Разрешение на редактирование операций у завершенной скважины"},
|
||||
|
||||
new() { Id = 527, Name = "Manual.delete", Description = "Разрешение на удаление инструкций"}
|
||||
new() { Id = 527, Name = "Manual.delete", Description = "Разрешение на удаление инструкций"},
|
||||
new (){ Id = 528, Name="WellContact.delete", Description="Разрешение на удаление контакта"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
@ -20,8 +21,8 @@ namespace AsbCloudDb.Model
|
||||
DbSet<Deposit> Deposits { get; }
|
||||
DbSet<DetectedOperation> DetectedOperations { get; }
|
||||
DbSet<PlannedTrajectory> PlannedTrajectories { get; }
|
||||
DbSet<ProcessMap> ProcessMap { get; }
|
||||
DbSet<ProcessMapWellboreDevelopment> ProcessMapWellboreDevelopments { get; }
|
||||
DbSet<ProcessMapWellDrilling> ProcessMapWellDrillings { get; }
|
||||
DbSet<ProcessMapWellReam> ProcessMapWellReams { get; }
|
||||
DbSet<DrillingProgramPart> DrillingProgramParts { get; }
|
||||
DbSet<FileCategory> FileCategories { get; }
|
||||
DbSet<FileInfo> Files { get; }
|
||||
@ -74,6 +75,7 @@ namespace AsbCloudDb.Model
|
||||
DbSet<NotificationCategory> NotificationCategories { get; }
|
||||
DbSet<Manual> Manuals { get; }
|
||||
DbSet<ManualDirectory> ManualDirectories { get; }
|
||||
DbSet<Contact> Contacts { get; }
|
||||
DbSet<DrillTest> DrillTests { get; }
|
||||
DbSet<DrillTestParameter> DrillTestParameters { get; }
|
||||
DatabaseFacade Database { get; }
|
||||
|
@ -1,84 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_process_map"), Comment("Операции по скважине – РТК")]
|
||||
public class ProcessMap : IId, IWellRelated
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("well_id"), Comment("Id скважины")]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
[Column("id_user"), Comment("Id пользователя")]
|
||||
public int IdUser { get; set; }
|
||||
|
||||
[Column("id_mode"), Comment("Id режима (1- ротор, 2 слайд)")]
|
||||
public int IdMode { get; set; }
|
||||
|
||||
[Column("id_wellsection_type"), Comment("Тип секции")]
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
[Column("last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего изменения")]
|
||||
public DateTimeOffset LastUpdate { get; set; }
|
||||
|
||||
[Column("depth_start"), Comment("Стартовая глубина")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
[Column("depth_end"), Comment("Глубина окончания интервала")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
[Column("axial_load_plan"), Comment("Нагрузка, план")]
|
||||
public double AxialLoadPlan { get; set; }
|
||||
|
||||
[Column("axial_load_limit_max"), Comment("Нагрузка, допустимый максимум")]
|
||||
public double AxialLoadLimitMax { get; set; }
|
||||
|
||||
[Column("pressure_plan"), Comment("Перепад давления, план")]
|
||||
public double PressurePlan { get; set; }
|
||||
|
||||
[Column("pressure_limit_max"), Comment("Перепад давления, допустимый максимум")]
|
||||
public double PressureLimitMax { get; set; }
|
||||
|
||||
[Column("top_drive_torque_plan"), Comment("Момент на ВСП, план")]
|
||||
public double TopDriveTorquePlan { get; set; }
|
||||
|
||||
[Column("top_drive_torque_limit_max"), Comment("Момент на ВСП, допустимый максимум")]
|
||||
public double TopDriveTorqueLimitMax { get; set; }
|
||||
|
||||
[Column("top_drive_speed_plan"), Comment("Обороты на ВСП, план")]
|
||||
public double TopDriveSpeedPlan { get; set; }
|
||||
|
||||
[Column("top_drive_speed_limit_max"), Comment("Обороты на ВСП, допустимый максимум")]
|
||||
public double TopDriveSpeedLimitMax { get; set; }
|
||||
|
||||
[Column("flow_plan"), Comment("Расход, план")]
|
||||
public double FlowPlan { get; set; }
|
||||
|
||||
[Column("flow_limit_max"), Comment("Расход, допустимый максимум")]
|
||||
public double FlowLimitMax { get; set; }
|
||||
|
||||
[Column("rop_plan"), Comment("Плановая механическая скорость, м/ч")]
|
||||
public double RopPlan { get; set; }
|
||||
|
||||
[Column("usage_saub"), Comment("Плановый процент использования АКБ")]
|
||||
public double UsageSaub { get; set; }
|
||||
|
||||
[Column("usage_spin"), Comment("Плановый процент использования spin master")]
|
||||
public double UsageSpin { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
public virtual Well Well { get; set; } = null!;
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey(nameof(IdWellSectionType))]
|
||||
public virtual WellSectionType WellSectionType { get; set; } = null!;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudDb.Model;
|
||||
|
||||
[Table("t_process_map_wellbore_development"), Comment("РТК план проработка скважины")]
|
||||
public class ProcessMapWellboreDevelopment : IId, IWellRelated
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("id_well"), Comment("Id скважины")]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
[Column("id_user"), Comment("Id пользователя")]
|
||||
public int IdUser { get; set; }
|
||||
|
||||
[Column("last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего изменения")]
|
||||
public DateTimeOffset LastUpdate { get; set; }
|
||||
|
||||
[Column("depth_start"), Comment("Стартовая глубина, м")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
[Column("depth_end"), Comment("Окончательная глубина, м")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
[Column("repeats"), Comment("Количество повторений")]
|
||||
public double Repeats { get; set; }
|
||||
|
||||
[Column("spin_upward"), Comment("Вращение при движении вверх, об/мин")]
|
||||
public double SpinUpward { get; set; }
|
||||
|
||||
[Column("spin_downward"), Comment("Вращение при движении вниз, об/мин")]
|
||||
public double SpinDownward { get; set; }
|
||||
|
||||
[Column("speed_upward"), Comment("Скорость подъёма, м/ч")]
|
||||
public double SpeedUpward { get; set; }
|
||||
|
||||
[Column("speed_downward"), Comment("Скорость спуска, м/ч")]
|
||||
public double SpeedDownward { get; set; }
|
||||
|
||||
[Column("setpoint_drag"), Comment("Уставка зятяжки, т")]
|
||||
public double SetpointDrag { get; set; }
|
||||
|
||||
[Column("setpoint_tight"), Comment("Уставка посадки, т")]
|
||||
public double SetpointTight { get; set; }
|
||||
|
||||
[Column("pressure"), Comment("Давление, атм")]
|
||||
public double Pressure { get; set; }
|
||||
|
||||
[Column("torque"), Comment("Момент, кН*м")]
|
||||
public double Torque { get; set; }
|
||||
|
||||
[Column("comment"), Comment("Комментарий")]
|
||||
public string? Comment { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
public virtual Well Well { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(IdUser))]
|
||||
public virtual User User { get; set; } = null!;
|
||||
}
|
43
AsbCloudDb/Model/ProcessMaps/ProcessMapBase.cs
Normal file
43
AsbCloudDb/Model/ProcessMaps/ProcessMapBase.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model.ProcessMaps;
|
||||
|
||||
public abstract class ProcessMapBase : IId, IWellRelated
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("id_well"), Comment("Id скважины")]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
[Column("id_wellsection_type"), Comment("Тип секции")]
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
[Column("id_user"), Comment("Id пользователя")]
|
||||
public int IdUser { get; set; }
|
||||
|
||||
[Column("last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего изменения")]
|
||||
public DateTimeOffset LastUpdate { get; set; }
|
||||
|
||||
[Column("depth_start"), Comment("Глубина по стволу от, м")]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
[Column("depth_end"), Comment("Глубина по стволу до, м")]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
[Column("comment"), Comment("Комментарий")]
|
||||
public string? Comment { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
public virtual Well Well { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(IdUser))]
|
||||
public virtual User User { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(IdWellSectionType))]
|
||||
public virtual WellSectionType WellSectionType { get; set; } = null!;
|
||||
}
|
50
AsbCloudDb/Model/ProcessMaps/ProcessMapWellDrilling.cs
Normal file
50
AsbCloudDb/Model/ProcessMaps/ProcessMapWellDrilling.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model.ProcessMaps;
|
||||
|
||||
[Table("t_process_map_well_drilling"), Comment("РТК бурение скважины")]
|
||||
public class ProcessMapWellDrilling : ProcessMapBase
|
||||
{
|
||||
[Column("id_mode"), Comment("Id режима (1- ротор, 2 слайд)")]
|
||||
public int IdMode { get; set; }
|
||||
|
||||
[Column("axial_load_plan"), Comment("Нагрузка, план")]
|
||||
public double AxialLoadPlan { get; set; }
|
||||
|
||||
[Column("axial_load_limit_max"), Comment("Нагрузка, допустимый максимум")]
|
||||
public double AxialLoadLimitMax { get; set; }
|
||||
|
||||
[Column("pressure_plan"), Comment("Перепад давления, план")]
|
||||
public double PressurePlan { get; set; }
|
||||
|
||||
[Column("pressure_limit_max"), Comment("Перепад давления, допустимый максимум")]
|
||||
public double PressureLimitMax { get; set; }
|
||||
|
||||
[Column("top_drive_torque_plan"), Comment("Момент на ВСП, план")]
|
||||
public double TopDriveTorquePlan { get; set; }
|
||||
|
||||
[Column("top_drive_torque_limit_max"), Comment("Момент на ВСП, допустимый максимум")]
|
||||
public double TopDriveTorqueLimitMax { get; set; }
|
||||
|
||||
[Column("top_drive_speed_plan"), Comment("Обороты на ВСП, план")]
|
||||
public double TopDriveSpeedPlan { get; set; }
|
||||
|
||||
[Column("top_drive_speed_limit_max"), Comment("Обороты на ВСП, допустимый максимум")]
|
||||
public double TopDriveSpeedLimitMax { get; set; }
|
||||
|
||||
[Column("flow_plan"), Comment("Расход, план")]
|
||||
public double FlowPlan { get; set; }
|
||||
|
||||
[Column("flow_limit_max"), Comment("Расход, допустимый максимум")]
|
||||
public double FlowLimitMax { get; set; }
|
||||
|
||||
[Column("rop_plan"), Comment("Плановая механическая скорость, м/ч")]
|
||||
public double RopPlan { get; set; }
|
||||
|
||||
[Column("usage_saub"), Comment("Плановый процент использования АКБ")]
|
||||
public double UsageSaub { get; set; }
|
||||
|
||||
[Column("usage_spin"), Comment("Плановый процент использования spin master")]
|
||||
public double UsageSpin { get; set; }
|
||||
}
|
35
AsbCloudDb/Model/ProcessMaps/ProcessMapWellReam.cs
Normal file
35
AsbCloudDb/Model/ProcessMaps/ProcessMapWellReam.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudDb.Model.ProcessMaps;
|
||||
|
||||
[Table("t_process_map_well_ream"), Comment("РТК проработка скважины")]
|
||||
public class ProcessMapWellReam : ProcessMapBase
|
||||
{
|
||||
[Column("repeats"), Comment("Количество повторений")]
|
||||
public double Repeats { get; set; }
|
||||
|
||||
[Column("spin_upward"), Comment("Вращение при движении вверх, об/мин")]
|
||||
public double SpinUpward { get; set; }
|
||||
|
||||
[Column("spin_downward"), Comment("Вращение при движении вниз, об/мин")]
|
||||
public double SpinDownward { get; set; }
|
||||
|
||||
[Column("speed_upward"), Comment("Скорость подъёма, м/ч")]
|
||||
public double SpeedUpward { get; set; }
|
||||
|
||||
[Column("speed_downward"), Comment("Скорость спуска, м/ч")]
|
||||
public double SpeedDownward { get; set; }
|
||||
|
||||
[Column("setpoint_drag"), Comment("Уставка зятяжки, т")]
|
||||
public double SetpointDrag { get; set; }
|
||||
|
||||
[Column("setpoint_tight"), Comment("Уставка посадки, т")]
|
||||
public double SetpointTight { get; set; }
|
||||
|
||||
[Column("pressure"), Comment("Давление, атм")]
|
||||
public double Pressure { get; set; }
|
||||
|
||||
[Column("torque"), Comment("Момент, кН*м")]
|
||||
public double Torque { get; set; }
|
||||
}
|
@ -66,7 +66,7 @@ namespace AsbCloudDb.Model
|
||||
[InverseProperty(nameof(DrillingProgramPart.Well))]
|
||||
public virtual ICollection<DrillingProgramPart> DrillingProgramParts { get; set; } = null!;
|
||||
|
||||
[InverseProperty(nameof(ProcessMap.Well))]
|
||||
public virtual ICollection<ProcessMap> ProcessMaps { get; set; } = null!;
|
||||
[InverseProperty(nameof(Contact.Well))]
|
||||
public virtual ICollection<Contact> Contacts { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,6 @@
|
||||
<None Remove="CommonLibs\Readme.md" />
|
||||
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||
<None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||
<None Remove="Services\ProcessMap\ProcessMapReportTemplate.xlsx" />
|
||||
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
|
||||
<None Remove="Services\DailyReport\DailyReportBlocks\" />
|
||||
@ -32,14 +31,14 @@
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\ProcessMap\ProcessMapReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\ProcessMap\ProcessMapPlanTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\AutoGeneratedDailyReports\AutogeneratedDailyReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
|
||||
<EmbeddedResource Include="Services\ProcessMaps\Report\ProcessMapReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\ProcessMaps\WellDrilling\ProcessMapPlanImportWellDrillingTemplate.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,165 +1,209 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
||||
using AsbCloudApp.Services.Notifications;
|
||||
using AsbCloudApp.Services.ProcessMaps;
|
||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudApp.Services.Subsystems;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
using AsbCloudDb.Model.Subsystems;
|
||||
using AsbCloudInfrastructure.Background;
|
||||
using AsbCloudInfrastructure.Repository;
|
||||
using AsbCloudInfrastructure.Services;
|
||||
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
||||
using AsbCloudInfrastructure.Services.DailyReport;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
using AsbCloudInfrastructure.Services.DrillingProgram;
|
||||
using AsbCloudInfrastructure.Services.ProcessMap;
|
||||
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.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||
using AsbCloudInfrastructure.Services.WellOperationService;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
||||
using AsbCloudApp.Services.Notifications;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment;
|
||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||
|
||||
namespace AsbCloudInfrastructure
|
||||
{
|
||||
|
||||
public static class DependencyInjection
|
||||
{
|
||||
public static IAsbCloudDbContext MakeContext(string connectionString)
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
||||
.UseNpgsql(connectionString)
|
||||
.Options;
|
||||
var context = new AsbCloudDbContext(options);
|
||||
return context;
|
||||
}
|
||||
public static IAsbCloudDbContext MakeContext(string connectionString)
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
||||
.UseNpgsql(connectionString)
|
||||
.Options;
|
||||
var context = new AsbCloudDbContext(options);
|
||||
return context;
|
||||
}
|
||||
|
||||
public static void MapsterSetup()
|
||||
{
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<DateTimeOffset, DateTime>()
|
||||
.MapWith((source) => source.DateTime);
|
||||
public static void MapsterSetup()
|
||||
{
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<DateTimeOffset, DateTime>()
|
||||
.MapWith((source) => source.DateTime);
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<DateTime, DateTimeOffset>()
|
||||
.MapWith((source) => source == default ? new DateTime(0, DateTimeKind.Utc) : source);
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<DateTime, DateTimeOffset>()
|
||||
.MapWith((source) => source == default ? new DateTime(0, DateTimeKind.Utc) : source);
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TimeDto, TimeOnly>()
|
||||
.MapWith((source) => source.MakeTimeOnly());
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TimeDto, TimeOnly>()
|
||||
.MapWith((source) => source.MakeTimeOnly());
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TimeOnly, TimeDto>()
|
||||
.MapWith((source) => new(source));
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TimeOnly, TimeDto>()
|
||||
.MapWith((source) => new(source));
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TimeOnly, TimeDto>()
|
||||
.MapWith((source) => new(source));
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<TimeOnly, TimeDto>()
|
||||
.MapWith((source) => new(source));
|
||||
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<WellDto, Well>()
|
||||
.Ignore(dst => dst.Cluster,
|
||||
dst => dst.RelationCompaniesWells,
|
||||
dst => dst.Telemetry,
|
||||
dst => dst.WellComposites,
|
||||
dst => dst.WellCompositeSrcs,
|
||||
dst => dst.WellOperations,
|
||||
dst => dst.WellType);
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<WellDto, Well>()
|
||||
.Ignore(dst => dst.Cluster,
|
||||
dst => dst.RelationCompaniesWells,
|
||||
dst => dst.Telemetry,
|
||||
dst => dst.WellComposites,
|
||||
dst => dst.WellCompositeSrcs,
|
||||
dst => dst.WellOperations,
|
||||
dst => dst.WellType);
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<ClusterDto, Cluster>()
|
||||
.Ignore(dst => dst.Deposit,
|
||||
dst => dst.Wells);
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<ClusterDto, Cluster>()
|
||||
.Ignore(dst => dst.Deposit,
|
||||
dst => dst.Wells);
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<FileCategoryDto, FileCategory>();
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<FileCategoryDto, FileCategory>();
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<WellFinalDocumentDto, WellFinalDocument>();
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<WellFinalDocumentDto, WellFinalDocument>();
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<NotificationDto, Notification>()
|
||||
.Ignore(dst => dst.NotificationCategory,
|
||||
dst => dst.User);
|
||||
}
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<NotificationDto, Notification>()
|
||||
.Ignore(dst => dst.NotificationCategory,
|
||||
dst => dst.User);
|
||||
|
||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
MapsterSetup();
|
||||
var connectionStringName = "DefaultConnection";
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<ProcessMapWellDrilling, ProcessMapPlanWellDrillingDto>()
|
||||
.Map(dest => dest.AxialLoad, src => new PlanLimitDto
|
||||
{
|
||||
LimitMax = src.AxialLoadLimitMax,
|
||||
Plan = src.AxialLoadPlan
|
||||
})
|
||||
.Map(dest => dest.Flow, src => new PlanLimitDto
|
||||
{
|
||||
LimitMax = src.FlowLimitMax,
|
||||
Plan = src.FlowPlan
|
||||
})
|
||||
.Map(dest => dest.Pressure, src => new PlanLimitDto
|
||||
{
|
||||
LimitMax = src.PressureLimitMax,
|
||||
Plan = src.PressurePlan
|
||||
})
|
||||
.Map(dest => dest.TopDriveSpeed, src => new PlanLimitDto
|
||||
{
|
||||
LimitMax = src.TopDriveSpeedLimitMax,
|
||||
Plan = src.TopDriveSpeedPlan
|
||||
})
|
||||
.Map(dest => dest.TopDriveTorque, src => new PlanLimitDto
|
||||
{
|
||||
LimitMax = src.TopDriveTorqueLimitMax,
|
||||
Plan = src.TopDriveTorquePlan
|
||||
});
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<ProcessMapPlanWellDrillingDto, ProcessMapWellDrilling>()
|
||||
.Map(dest => dest.AxialLoadPlan, src => src.AxialLoad.Plan)
|
||||
.Map(dest => dest.AxialLoadLimitMax, src => src.AxialLoad.LimitMax)
|
||||
.Map(dest => dest.FlowPlan, src => src.Flow.Plan)
|
||||
.Map(dest => dest.FlowLimitMax, src => src.Flow.LimitMax)
|
||||
.Map(dest => dest.PressurePlan, src => src.Pressure.Plan)
|
||||
.Map(dest => dest.PressureLimitMax, src => src.Pressure.LimitMax)
|
||||
.Map(dest => dest.TopDriveSpeedPlan, src => src.TopDriveSpeed.Plan)
|
||||
.Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax)
|
||||
.Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan)
|
||||
.Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax);
|
||||
}
|
||||
|
||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
MapsterSetup();
|
||||
string connectionStringName = "DefaultConnection";
|
||||
#if DEBUG
|
||||
connectionStringName = "DebugConnection";
|
||||
connectionStringName = "DebugConnection";
|
||||
#endif
|
||||
services.AddDbContext<AsbCloudDbContext>(options =>
|
||||
options.UseNpgsql(configuration.GetConnectionString(connectionStringName)));
|
||||
|
||||
services.AddDbContext<AsbCloudDbContext>(options =>
|
||||
options.UseNpgsql(configuration.GetConnectionString(connectionStringName)));
|
||||
|
||||
services.AddMemoryCache();
|
||||
services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>());
|
||||
|
||||
services.AddSingleton(new WitsInfoService());
|
||||
services.AddSingleton(provider => TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider));
|
||||
services.AddSingleton(provider => TelemetryDataCache<TelemetryDataSpinDto>.GetInstance<TelemetryDataSpin>(provider));
|
||||
services.AddSingleton<IRequerstTrackerService, RequestTrackerService>();
|
||||
services.AddSingleton<BackgroundWorker>();
|
||||
services.AddSingleton<NotificationBackgroundWorker>();
|
||||
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
||||
services.AddMemoryCache();
|
||||
services.AddScoped<IAsbCloudDbContext>(provider => provider.GetRequiredService<AsbCloudDbContext>());
|
||||
|
||||
services.AddTransient<IAuthService, AuthService>();
|
||||
services.AddTransient<IProcessMapWellboreDevelopmentRepository, ProcessMapWellboreDevelopmentRepository>();
|
||||
services.AddTransient<IProcessMapWellboreDevelopmentService, ProcessMapWellboreDevelopmentService>();
|
||||
services.AddTransient<IDepositRepository, DepositRepository>();
|
||||
services.AddTransient<IProcessMapPlanRepository, ProcessMapRepository>();
|
||||
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
||||
services.AddTransient<IEventService, EventService>();
|
||||
services.AddTransient<FileService>();
|
||||
services.AddTransient<IMeasureService, MeasureService>();
|
||||
services.AddTransient<IMessageService, MessageService>();
|
||||
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
||||
services.AddTransient<IReportService, ReportService>();
|
||||
services.AddTransient<ISetpointsService, SetpointsService>();
|
||||
services.AddTransient<ITelemetryService, TelemetryService>();
|
||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||
services.AddTransient<ITimezoneService, TimezoneService>();
|
||||
services.AddTransient<IWellService, WellService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IProcessMapPlanImportService, ProcessMapPlanImportService>();
|
||||
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
|
||||
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
||||
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
|
||||
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
|
||||
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
|
||||
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
||||
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
||||
services.AddTransient<IProcessMapReportMakerService, ProcessMapReportMakerService>();
|
||||
services.AddTransient<IProcessMapService, ProcessMapService>();
|
||||
services.AddTransient<WellInfoService>();
|
||||
services.AddTransient<IHelpPageService, HelpPageService>();
|
||||
services.AddSingleton(new WitsInfoService());
|
||||
services.AddSingleton(provider => TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider));
|
||||
services.AddSingleton(provider => TelemetryDataCache<TelemetryDataSpinDto>.GetInstance<TelemetryDataSpin>(provider));
|
||||
services.AddSingleton<IRequerstTrackerService, RequestTrackerService>();
|
||||
services.AddSingleton<BackgroundWorker>();
|
||||
services.AddSingleton<NotificationBackgroundWorker>();
|
||||
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
||||
|
||||
services.AddTransient<TrajectoryService>();
|
||||
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>();
|
||||
services.AddTransient<FileService>();
|
||||
services.AddTransient<IMeasureService, MeasureService>();
|
||||
services.AddTransient<IMessageService, MessageService>();
|
||||
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
||||
services.AddTransient<IReportService, ReportService>();
|
||||
services.AddTransient<ISetpointsService, SetpointsService>();
|
||||
services.AddTransient<ITelemetryService, TelemetryService>();
|
||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||
services.AddTransient<ITimezoneService, TimezoneService>();
|
||||
services.AddTransient<IWellService, WellService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
|
||||
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
|
||||
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
||||
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
|
||||
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
|
||||
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<IGtrRepository, GtrWitsRepository>();
|
||||
services.AddTransient<TrajectoryService>();
|
||||
|
||||
services.AddTransient<IGtrRepository, GtrWitsRepository>();
|
||||
|
||||
services.AddTransient<NotificationService>();
|
||||
services.AddTransient<INotificationRepository, NotificationRepository>();
|
||||
@ -167,99 +211,99 @@ namespace AsbCloudInfrastructure
|
||||
NotificationCategory>>();
|
||||
services.AddTransient<IDrillTestRepository, DrillTestRepository>();
|
||||
|
||||
// admin crud services:
|
||||
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
|
||||
new CrudCacheRepositoryBase<TelemetryDto, Telemetry>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet.Include(t => t.Well))); // может быть включен в сервис TelemetryService
|
||||
services.AddTransient<ICrudRepository<DepositDto>, CrudCacheRepositoryBase<DepositDto, Deposit>>(s =>
|
||||
new CrudCacheRepositoryBase<DepositDto, Deposit>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet.Include(d => d.Clusters)));
|
||||
services.AddTransient<ICrudRepository<CompanyDto>, CrudCacheRepositoryBase<CompanyDto, Company>>(s =>
|
||||
new CrudCacheRepositoryBase<CompanyDto, Company>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet.Include(c => c.CompanyType)));
|
||||
// admin crud services:
|
||||
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
|
||||
new CrudCacheRepositoryBase<TelemetryDto, Telemetry>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet.Include(t => t.Well))); // может быть включен в сервис TelemetryService
|
||||
services.AddTransient<ICrudRepository<DepositDto>, CrudCacheRepositoryBase<DepositDto, Deposit>>(s =>
|
||||
new CrudCacheRepositoryBase<DepositDto, Deposit>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet.Include(d => d.Clusters)));
|
||||
services.AddTransient<ICrudRepository<CompanyDto>, CrudCacheRepositoryBase<CompanyDto, Company>>(s =>
|
||||
new CrudCacheRepositoryBase<CompanyDto, Company>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet.Include(c => c.CompanyType)));
|
||||
|
||||
services.AddTransient<ICrudRepository<CompanyTypeDto>, CrudCacheRepositoryBase<CompanyTypeDto, CompanyType>>();
|
||||
services.AddTransient<ICrudRepository<ClusterDto>, CrudCacheRepositoryBase<ClusterDto, Cluster>>(s =>
|
||||
new CrudCacheRepositoryBase<ClusterDto, Cluster>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet
|
||||
.Include(c => c.Wells)
|
||||
.Include(c => c.Deposit))); // может быть включен в сервис ClusterService
|
||||
services.AddTransient<ICrudRepository<CompanyTypeDto>, CrudCacheRepositoryBase<CompanyTypeDto, CompanyType>>();
|
||||
services.AddTransient<ICrudRepository<ClusterDto>, CrudCacheRepositoryBase<ClusterDto, Cluster>>(s =>
|
||||
new CrudCacheRepositoryBase<ClusterDto, Cluster>(
|
||||
s.GetRequiredService<IAsbCloudDbContext>(),
|
||||
s.GetRequiredService<IMemoryCache>(),
|
||||
dbSet => dbSet
|
||||
.Include(c => c.Wells)
|
||||
.Include(c => c.Deposit))); // может быть включен в сервис ClusterService
|
||||
|
||||
services.AddTransient<ICrudRepository<DrillerDto>, CrudCacheRepositoryBase<DrillerDto, Driller>>();
|
||||
services.AddTransient<ICrudRepository<DrillerDto>, CrudCacheRepositoryBase<DrillerDto, Driller>>();
|
||||
|
||||
services.AddTransient<IHelpPageRepository, HelpPageRepository>();
|
||||
services.AddTransient<IFileRepository, FileRepository>();
|
||||
services.AddTransient<IFileStorageRepository, FileStorageRepository>();
|
||||
services.AddTransient<IWellCompositeRepository, WellCompositeRepository>();
|
||||
services.AddTransient<IUserRoleRepository, UserRoleRepository>();
|
||||
services.AddTransient<IUserRepository, UserRepository>();
|
||||
services.AddTransient<ILimitingParameterRepository, LimitingParameterRepository>();
|
||||
services.AddTransient<ITelemetryWirelineRunOutRepository, TelemetryWirelineRunOutRepository>();
|
||||
services.AddTransient<IWellFinalDocumentsRepository, WellFinalDocumentsRepository>();
|
||||
services.AddTransient<ITrajectoryPlanRepository, TrajectoryPlanRepository>();
|
||||
services.AddTransient<ITrajectoryFactRepository, TrajectoryFactRepository>();
|
||||
services.AddTransient<IFaqRepository, FaqRepository>();
|
||||
services.AddTransient<ISlipsStatService, SlipsStatService>();
|
||||
services.AddTransient<IWellContactService, WellContactService>();
|
||||
services.AddTransient<ICrudRepository<WellSectionTypeDto>, CrudCacheRepositoryBase<WellSectionTypeDto,
|
||||
WellSectionType>>();
|
||||
services.AddTransient<IHelpPageRepository, HelpPageRepository>();
|
||||
services.AddTransient<IFileRepository, FileRepository>();
|
||||
services.AddTransient<IFileStorageRepository, FileStorageRepository>();
|
||||
services.AddTransient<IWellCompositeRepository, WellCompositeRepository>();
|
||||
services.AddTransient<IUserRoleRepository, UserRoleRepository>();
|
||||
services.AddTransient<IUserRepository, UserRepository>();
|
||||
services.AddTransient<ILimitingParameterRepository, LimitingParameterRepository>();
|
||||
services.AddTransient<ITelemetryWirelineRunOutRepository, TelemetryWirelineRunOutRepository>();
|
||||
services.AddTransient<IWellFinalDocumentsRepository, WellFinalDocumentsRepository>();
|
||||
services.AddTransient<ITrajectoryPlanRepository, TrajectoryPlanRepository>();
|
||||
services.AddTransient<ITrajectoryFactRepository, TrajectoryFactRepository>();
|
||||
services.AddTransient<IFaqRepository, FaqRepository>();
|
||||
services.AddTransient<ISlipsStatService, SlipsStatService>();
|
||||
services.AddTransient<IWellContactService, WellContactService>();
|
||||
services.AddTransient<ICrudRepository<WellSectionTypeDto>, CrudCacheRepositoryBase<WellSectionTypeDto,
|
||||
WellSectionType>>();
|
||||
|
||||
// Subsystem service
|
||||
services.AddTransient<ICrudRepository<SubsystemDto>, CrudCacheRepositoryBase<SubsystemDto, Subsystem>>();
|
||||
services.AddTransient<ISubsystemService, SubsystemService>();
|
||||
// Subsystem service
|
||||
services.AddTransient<ICrudRepository<SubsystemDto>, CrudCacheRepositoryBase<SubsystemDto, Subsystem>>();
|
||||
services.AddTransient<ISubsystemService, SubsystemService>();
|
||||
|
||||
services.AddTransient<ICrudRepository<PermissionDto>, CrudCacheRepositoryBase<PermissionDto, Permission>>();
|
||||
services.AddTransient<ICrudRepository<PermissionDto>, CrudCacheRepositoryBase<PermissionDto, Permission>>();
|
||||
|
||||
// TelemetryData services
|
||||
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
|
||||
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
|
||||
// TelemetryData services
|
||||
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
|
||||
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
|
||||
|
||||
// Wits
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto, AsbCloudDb.Model.WITS.Record8>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto, AsbCloudDb.Model.WITS.Record50>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.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>>();
|
||||
// Wits
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record8Dto, AsbCloudDb.Model.WITS.Record8>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record50Dto, AsbCloudDb.Model.WITS.Record50>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.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<IAutoGeneratedDailyReportService, AutoGeneratedDailyReportService>();
|
||||
services.AddTransient<IAutoGeneratedDailyReportMakerService, AutoGeneratedDailyReportMakerService>();
|
||||
|
||||
services.AddTransient<IManualDirectoryRepository, ManualDirectoryRepository>();
|
||||
services.AddTransient<IManualCatalogService, ManualCatalogService>();
|
||||
services.AddTransient<ICrudRepository<ManualDto>, CrudRepositoryBase<ManualDto, Manual>>();
|
||||
services.AddTransient<IAutoGeneratedDailyReportService, AutoGeneratedDailyReportService>();
|
||||
services.AddTransient<IAutoGeneratedDailyReportMakerService, AutoGeneratedDailyReportMakerService>();
|
||||
|
||||
services.AddTransient<IWellboreService, WellboreService>();
|
||||
services.AddTransient<IManualDirectoryRepository, ManualDirectoryRepository>();
|
||||
services.AddTransient<IManualCatalogService, ManualCatalogService>();
|
||||
services.AddTransient<ICrudRepository<ManualDto>, CrudRepositoryBase<ManualDto, Manual>>();
|
||||
|
||||
services.AddTransient<IWellOperationExportService, WellOperationExportService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IWellOperationImportTemplateService, WellOperationImportTemplateService>();
|
||||
services.AddTransient<IWellboreService, WellboreService>();
|
||||
|
||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
|
||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
|
||||
services.AddTransient<IWellOperationExportService, WellOperationExportService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IWellOperationImportTemplateService, WellOperationImportTemplateService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
|
||||
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
|
||||
|
||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
=> services.AddTransient<TService, TImplementation>()
|
||||
.AddTransient(provider => new Lazy<TService>(provider.GetRequiredService<TService>));
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
=> services.AddTransient<TService, TImplementation>(implementationFactory)
|
||||
.AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider)));
|
||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
=> services.AddTransient<TService, TImplementation>()
|
||||
.AddTransient(provider => new Lazy<TService>(provider.GetRequiredService<TService>));
|
||||
|
||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
=> services.AddTransient<TService, TImplementation>(implementationFactory)
|
||||
.AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider)));
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
protected readonly IMemoryCache memoryCache;
|
||||
protected string CacheTag = typeof(TEntity).Name;
|
||||
protected TimeSpan CacheOlescence = TimeSpan.FromMinutes(5);
|
||||
protected TimeSpan CacheObsolescence = TimeSpan.FromMinutes(5);
|
||||
|
||||
public CacheBase(IAsbCloudDbContext context, IMemoryCache memoryCache)
|
||||
: base(context)
|
||||
@ -36,10 +36,11 @@ namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
var cache = memoryCache.GetOrCreate(CacheTag, cacheEntry =>
|
||||
{
|
||||
cacheEntry.AbsoluteExpirationRelativeToNow = CacheOlescence;
|
||||
cacheEntry.SlidingExpiration = CacheOlescence;
|
||||
cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence;
|
||||
cacheEntry.SlidingExpiration = CacheObsolescence;
|
||||
|
||||
var entities = this.GetQuery().ToArray();
|
||||
cacheEntry.Value = entities;
|
||||
return entities;
|
||||
});
|
||||
return cache;
|
||||
@ -49,10 +50,11 @@ namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
var cache = memoryCache.GetOrCreateAsync(CacheTag, async (cacheEntry) =>
|
||||
{
|
||||
cacheEntry.AbsoluteExpirationRelativeToNow = CacheOlescence;
|
||||
cacheEntry.SlidingExpiration = CacheOlescence;
|
||||
cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence;
|
||||
cacheEntry.SlidingExpiration = CacheObsolescence;
|
||||
|
||||
var entities = await this.GetQuery().ToArrayAsync(token);
|
||||
cacheEntry.Value = entities;
|
||||
return entities.AsEnumerable();
|
||||
});
|
||||
return cache;
|
||||
|
@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
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 query = GetQuery();
|
||||
|
||||
foreach (var request in requests)
|
||||
{
|
||||
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.OrderBy(e => e.DepthStart)
|
||||
.ThenBy(e => e.Id)
|
||||
.AsNoTracking();
|
||||
}
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
|
||||
public class ProcessMapRepository : CrudWellRelatedRepositoryBase<ProcessMapPlanDto, ProcessMap>,
|
||||
IProcessMapPlanRepository
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
|
||||
public ProcessMapRepository(IAsbCloudDbContext context, IWellService wellService)
|
||||
: base(context, dbSet =>
|
||||
dbSet.Include(x => x.Well)
|
||||
.Include(x => x.WellSectionType)
|
||||
)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProcessMapPlanDto>> GetAllAsync(int idWell,
|
||||
DateTime? updateFrom, CancellationToken token)
|
||||
{
|
||||
var requests = new[]
|
||||
{
|
||||
new ProcessMapRequest {
|
||||
IdWell = idWell,
|
||||
UpdateFrom = updateFrom
|
||||
}
|
||||
};
|
||||
|
||||
var entities = await BuildQuery(requests)
|
||||
.OrderBy(e => e.DepthStart)
|
||||
.ThenBy(e => e.Id)
|
||||
.ToListAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var dtos = entities.Select(Convert);
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProcessMapPlanDto>> GetProcessMapAsync(IEnumerable<ProcessMapRequest> requests, CancellationToken token)
|
||||
{
|
||||
var entities = await BuildQuery(requests)
|
||||
.ToListAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
var dtos = entities.Select(Convert).ToList();
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public Task<int> RemoveByWellAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var query = dbContext.ProcessMap.Where(x => x.IdWell == idWell);
|
||||
|
||||
dbContext.ProcessMap.RemoveRange(query);
|
||||
|
||||
return dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public override async Task<int> InsertAsync(ProcessMapPlanDto dto,
|
||||
CancellationToken token)
|
||||
{
|
||||
dto.LastUpdate = DateTime.UtcNow;
|
||||
var result = await base.InsertAsync(dto, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override async Task<int> UpdateAsync(ProcessMapPlanDto dto,
|
||||
CancellationToken token)
|
||||
{
|
||||
dto.LastUpdate = DateTime.UtcNow;
|
||||
var result = await base.UpdateAsync(dto, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
private IQueryable<ProcessMap> BuildQuery(IEnumerable<ProcessMapRequest> requests)
|
||||
{
|
||||
var query = GetQuery();
|
||||
if (requests.Any())
|
||||
{
|
||||
Expression<Func<ProcessMap, bool>> predicate = map => false;
|
||||
foreach (var request in requests)
|
||||
{
|
||||
Expression<Func<ProcessMap, bool>> predicate2 = map => map.IdWell == request.IdWell;
|
||||
|
||||
if (request.IdWellSectionType is not null)
|
||||
predicate2 = predicate2.And(map => map.IdWellSectionType == request.IdWellSectionType);
|
||||
|
||||
if (request.UpdateFrom is not null)
|
||||
{
|
||||
var timezone = wellService.GetTimezone(request.IdWell);
|
||||
var updateFromUtc = request.UpdateFrom?.ToUtcDateTimeOffset(timezone.Hours);
|
||||
predicate2 = predicate2.And(map => map.LastUpdate >= updateFromUtc);
|
||||
}
|
||||
|
||||
predicate = predicate.Or(predicate2);
|
||||
}
|
||||
query = query.Where(predicate);
|
||||
|
||||
}
|
||||
return query;
|
||||
}
|
||||
protected override ProcessMapPlanDto Convert(ProcessMap entity)
|
||||
{
|
||||
var dto = entity.Adapt<ProcessMapPlanDto>();
|
||||
dto.LastUpdate = entity.LastUpdate.ToRemoteDateTime(entity.Well.Timezone.Hours);
|
||||
dto.AxialLoad = new PlanLimitDto
|
||||
{
|
||||
LimitMax = entity.AxialLoadLimitMax,
|
||||
Plan = entity.AxialLoadPlan
|
||||
};
|
||||
dto.Flow = new PlanLimitDto
|
||||
{
|
||||
LimitMax = entity.FlowLimitMax,
|
||||
Plan = entity.FlowPlan
|
||||
};
|
||||
dto.Pressure = new PlanLimitDto
|
||||
{
|
||||
LimitMax = entity.PressureLimitMax,
|
||||
Plan = entity.PressurePlan
|
||||
};
|
||||
dto.TopDriveSpeed = new PlanLimitDto
|
||||
{
|
||||
LimitMax = entity.TopDriveSpeedLimitMax,
|
||||
Plan = entity.TopDriveSpeedPlan
|
||||
};
|
||||
dto.TopDriveTorque = new PlanLimitDto
|
||||
{
|
||||
LimitMax = entity.TopDriveTorqueLimitMax,
|
||||
Plan = entity.TopDriveTorquePlan
|
||||
};
|
||||
return dto;
|
||||
}
|
||||
|
||||
protected override ProcessMap Convert(ProcessMapPlanDto dto)
|
||||
{
|
||||
var entity = dto.Adapt<ProcessMap>();
|
||||
entity.AxialLoadPlan = dto.AxialLoad.Plan;
|
||||
entity.AxialLoadLimitMax = dto.AxialLoad.LimitMax;
|
||||
|
||||
entity.FlowPlan = dto.Flow.Plan;
|
||||
entity.FlowLimitMax = dto.Flow.LimitMax;
|
||||
|
||||
entity.PressurePlan = dto.Pressure.Plan;
|
||||
entity.PressureLimitMax = dto.Pressure.LimitMax;
|
||||
|
||||
entity.TopDriveSpeedPlan = dto.TopDriveSpeed.Plan;
|
||||
entity.TopDriveSpeedLimitMax = dto.TopDriveSpeed.LimitMax;
|
||||
|
||||
entity.TopDriveTorquePlan = dto.TopDriveTorque.Plan;
|
||||
entity.TopDriveTorqueLimitMax = dto.TopDriveTorque.LimitMax;
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository;
|
||||
|
||||
public class ProcessMapWellboreDevelopmentRepository :
|
||||
CrudWellRelatedRepositoryBase<ProcessMapWellboreDevelopmentDto, ProcessMapWellboreDevelopment>,
|
||||
IProcessMapWellboreDevelopmentRepository
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
|
||||
public ProcessMapWellboreDevelopmentRepository(IAsbCloudDbContext context, IWellService wellService) : base(context)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProcessMapWellboreDevelopmentDto>> GetAllAsync(int idWell, DateTime? updateFrom,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var query = dbContext.ProcessMapWellboreDevelopments
|
||||
.Where(p => p.IdWell == idWell);
|
||||
|
||||
if (updateFrom.HasValue)
|
||||
{
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
var updateFromUtc = updateFrom.Value.ToUtcDateTimeOffset(timezone.Hours);
|
||||
query = query.Where(p => p.LastUpdate >= updateFromUtc);
|
||||
}
|
||||
|
||||
var entities = await query
|
||||
.OrderBy(p => p.DepthStart)
|
||||
.ThenBy(p => p.Id)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
return entities.Select(Convert);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
@ -17,12 +17,12 @@ namespace AsbCloudInfrastructure.Repository
|
||||
public class WellCompositeRepository : IWellCompositeRepository
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly IProcessMapPlanRepository processMapRepository;
|
||||
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository;
|
||||
|
||||
public WellCompositeRepository(IAsbCloudDbContext db, IProcessMapPlanRepository processMapRepository)
|
||||
public WellCompositeRepository(IAsbCloudDbContext db, IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanWellDrillingRepository)
|
||||
{
|
||||
this.db = db;
|
||||
this.processMapRepository = processMapRepository;
|
||||
this.processMapPlanWellDrillingRepository = processMapPlanWellDrillingRepository;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@ -50,16 +50,16 @@ namespace AsbCloudInfrastructure.Repository
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<ProcessMapPlanDto>> GetCompositeProcessMap(int idWell, CancellationToken token)
|
||||
public async Task<IEnumerable<ProcessMapPlanWellDrillingDto>> GetCompositeProcessMap(int idWell, CancellationToken token)
|
||||
{
|
||||
var dtos = await GetAsync(idWell, token);
|
||||
|
||||
var requests = dtos.Select(x => new ProcessMapRequest {
|
||||
var requests = dtos.Select(x => new ProcessMapPlanRequest {
|
||||
IdWell = x.IdWellSrc,
|
||||
IdWellSectionType = x.IdWellSectionType
|
||||
});
|
||||
|
||||
var result = await processMapRepository.GetProcessMapAsync(requests, token);
|
||||
var result = await processMapPlanWellDrillingRepository.GetAsync(requests, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -75,5 +75,5 @@ namespace AsbCloudInfrastructure.Repository
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,345 +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.ProcessMap;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
using System;
|
||||
using AsbCloudApp.Data;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap;
|
||||
|
||||
/*
|
||||
* password for ProcessMapImportTemplate.xlsx is ASB2020!
|
||||
*/
|
||||
public class ProcessMapPlanImportService : IProcessMapPlanImportService
|
||||
{
|
||||
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
||||
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
|
||||
|
||||
private const string sheetNamePlan = "План";
|
||||
|
||||
private const int headerRowsCount = 2;
|
||||
|
||||
private const int columnWellSectionType = 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 WellSectionTypeDto[] sections = null!;
|
||||
|
||||
public ProcessMapPlanImportService(IProcessMapPlanRepository processMapPlanRepository,
|
||||
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository)
|
||||
{
|
||||
this.processMapPlanRepository = processMapPlanRepository;
|
||||
this.wellSectionTypeRepository = wellSectionTypeRepository;
|
||||
}
|
||||
|
||||
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 processPlanMaps = ParseWorkBook(workBook);
|
||||
|
||||
if (deleteProcessMapPlansBeforeImport)
|
||||
await processMapPlanRepository.RemoveByWellAsync(idWell, cancellationToken);
|
||||
|
||||
foreach (var processPlanMap in processPlanMaps)
|
||||
{
|
||||
processPlanMap.IdWell = idWell;
|
||||
processPlanMap.IdUser = idUser;
|
||||
}
|
||||
|
||||
await processMapPlanRepository.InsertRangeAsync(processPlanMaps, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Stream> ExportAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
sections = (await wellSectionTypeRepository.GetAllAsync(cancellationToken)).ToArray();
|
||||
|
||||
var processMapPlans = (await processMapPlanRepository.GetByIdWellAsync(idWell,
|
||||
cancellationToken)).ToArray();
|
||||
|
||||
return await GenerateExcelFileStreamAsync(processMapPlans,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var resourceName = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceNames()
|
||||
.FirstOrDefault(n => n.EndsWith("ProcessMapPlanTemplate.xlsx"))!;
|
||||
|
||||
using var stream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream(resourceName)!;
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await stream.CopyToAsync(memoryStream, cancellationToken);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private void AddToWorkbook(XLWorkbook workbook, ProcessMapPlanDto[] processMapPlans)
|
||||
{
|
||||
if (!processMapPlans.Any())
|
||||
return;
|
||||
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlan}.");
|
||||
|
||||
AddToSheet(sheet, processMapPlans);
|
||||
}
|
||||
|
||||
private void AddToSheet(IXLWorksheet sheet, ProcessMapPlanDto[] processMapPlans)
|
||||
{
|
||||
for (int i = 0; i < processMapPlans.Length; i++)
|
||||
{
|
||||
var row = sheet.Row(1 + i + headerRowsCount);
|
||||
AddToRow(row, processMapPlans[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddToRow(IXLRow row, ProcessMapPlanDto processMap)
|
||||
{
|
||||
row.Cell(columnWellSectionType).Value = sections.First(x => x.Id == processMap.IdWellSectionType).Caption;
|
||||
row.Cell(columnMode).Value = GetModeCaption(processMap.IdMode);
|
||||
row.Cell(columnDepthStart).Value = processMap.DepthStart;
|
||||
row.Cell(columnDepthEnd).Value = processMap.DepthEnd;
|
||||
row.Cell(columnPressurePlan).Value = processMap.Pressure.Plan;
|
||||
row.Cell(columnPressureLimitMax).Value = processMap.Pressure.LimitMax;
|
||||
row.Cell(columnAxialLoadPlan).Value = processMap.AxialLoad.Plan;
|
||||
row.Cell(columnAxialLoadLimitMax).Value = processMap.AxialLoad.LimitMax;
|
||||
row.Cell(columnTopDriveTorquePlan).Value = processMap.TopDriveTorque.Plan;
|
||||
row.Cell(columnTopDriveTorqueLimitMax).Value = processMap.TopDriveTorque.LimitMax;
|
||||
row.Cell(columnTopDriveSpeedPlan).Value = processMap.TopDriveSpeed.Plan;
|
||||
row.Cell(columnTopDriveSpeedLimitMax).Value = processMap.TopDriveSpeed.LimitMax;
|
||||
row.Cell(columnFlowPlan).Value = processMap.Flow.Plan;
|
||||
row.Cell(columnFlowLimitMax).Value = processMap.Flow.LimitMax;
|
||||
row.Cell(columnRopPlan).Value = processMap.RopPlan;
|
||||
row.Cell(columnUsageSaub).Value = processMap.UsageSaub;
|
||||
row.Cell(columnUsageSpin).Value = processMap.UsageSpin;
|
||||
}
|
||||
|
||||
private ProcessMapPlanDto[] ParseWorkBook(IXLWorkbook workbook)
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlan}.");
|
||||
|
||||
return ParseSheet(sheet);
|
||||
}
|
||||
|
||||
private ProcessMapPlanDto[] 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<ProcessMapPlanDto>();
|
||||
|
||||
var processMapPlans = new ProcessMapPlanDto[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 ProcessMapPlanDto ParseRow(IXLRow row)
|
||||
{
|
||||
var wellSectionTypeCaption = row.Cell(columnWellSectionType).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 wellSection = sections.FirstOrDefault(s => s.Caption.Trim().ToLower() == wellSectionTypeCaption)
|
||||
?? 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 > 50000)
|
||||
throw new FileFormatException(
|
||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная стартовая глубина");
|
||||
|
||||
if (depthEnd is < 0 or > 50000)
|
||||
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 > 50000)
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<Stream> GenerateExcelFileStreamAsync(ProcessMapPlanDto[] processMapPlans,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
||||
|
||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
||||
|
||||
AddToWorkbook(workbook, processMapPlans);
|
||||
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
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 => "Слайд",
|
||||
_ => "Ручной",
|
||||
};
|
||||
}
|
@ -1,209 +0,0 @@
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
{
|
||||
|
||||
public class ProcessMapReportMakerService : IProcessMapReportMakerService
|
||||
{
|
||||
const int firstColumn = 2;
|
||||
const int lastColumn = 42;
|
||||
|
||||
const int headerRowsCount = 5;
|
||||
|
||||
private readonly IProcessMapService processMapService;
|
||||
|
||||
public ProcessMapReportMakerService(IProcessMapService processMapService)
|
||||
{
|
||||
this.processMapService = processMapService;
|
||||
}
|
||||
|
||||
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var stream = GetExcelTemplateStream();
|
||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||
|
||||
var data = await processMapService.GetProcessMapReportAsync(idWell, token);
|
||||
|
||||
FillProcessMapToWorkbook(workbook, data);
|
||||
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> data)
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
||||
if (sheet is null)
|
||||
return;
|
||||
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
||||
FillSheet(sheet, dataBySections);
|
||||
}
|
||||
|
||||
private static void FillSheet(IXLWorksheet sheet, IEnumerable<IGrouping<int, ProcessMapReportDto>> 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, ProcessMapReportDto> sectionData, int row)
|
||||
{
|
||||
var rowStart = row;
|
||||
|
||||
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
|
||||
?? sectionData.Key.ToString();
|
||||
|
||||
sheet.Range(row, firstColumn, row, lastColumn)
|
||||
.Merge()
|
||||
.FirstCell()
|
||||
.SetVal(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, ProcessMapReportDto 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)
|
||||
.SetVal(interval.DepthStart, "0.0");
|
||||
|
||||
sheet.Cell(row, columnDepth)
|
||||
.SetVal(interval.DepthEnd, "0.0");
|
||||
|
||||
sheet.Cell(row, columnDate)
|
||||
.SetVal(interval.DateStart);
|
||||
|
||||
sheet.Cell(row, columnRopTime)
|
||||
.SetVal(interval.MechDrillingHours);
|
||||
|
||||
row = FillIntervalModeData(sheet, interval, columnMode, row);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
private static int FillIntervalModeData(IXLWorksheet sheet, ProcessMapReportDto 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)
|
||||
.SetVal(modeData.DrillingMode);
|
||||
|
||||
sheet.Cell(row, columnDeltaDepth)
|
||||
.SetVal(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)
|
||||
.SetVal(modeData.UsagePlan);
|
||||
|
||||
sheet.Cell(row, columnUsageFact)
|
||||
.SetVal(modeData.UsageFact);
|
||||
|
||||
sheet.Cell(row, columnRop)
|
||||
.SetVal(modeData.Rop);
|
||||
|
||||
return row + 1;
|
||||
}
|
||||
|
||||
private static void FillIntervalModeDataParam(IXLWorksheet sheet, ProcessMapReportParamsDto 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)
|
||||
.SetVal(dataParam.SetpointPlan);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetSpFact)
|
||||
.SetVal(dataParam.SetpointFact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetFact)
|
||||
.SetVal(dataParam.Fact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetLimit)
|
||||
.SetVal(dataParam.Limit);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetPercent)
|
||||
.SetVal(dataParam.SetpointUsage, format: "0.0");
|
||||
}
|
||||
|
||||
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto 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)
|
||||
.SetVal(dataParam.SetpointPlan);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetSpFact)
|
||||
.SetVal(dataParam.SetpointFact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetFact)
|
||||
.SetVal(dataParam.Fact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetLimit)
|
||||
.SetVal(dataParam.Limit);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetPercent)
|
||||
.SetVal(dataParam.SetpointUsage, format: "0.0");
|
||||
}
|
||||
|
||||
private static Stream GetExcelTemplateStream()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
||||
return stream!;
|
||||
}
|
||||
|
||||
private static IXLStyle 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 ;
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,399 +0,0 @@
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||
{
|
||||
|
||||
public partial class ProcessMapService : IProcessMapService
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||
|
||||
public ProcessMapService(
|
||||
IWellService wellService,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
IProcessMapPlanRepository processMapPlanRepository,
|
||||
ITelemetryDataSaubService telemetryDataSaubService)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
this.processMapPlanRepository = processMapPlanRepository;
|
||||
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapReportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var well = wellService.GetOrDefault(idWell)
|
||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell not found");
|
||||
|
||||
var idTelemetry = well.IdTelemetry
|
||||
?? throw new ArgumentInvalidException(nameof(idWell), "telemetry by well not found");
|
||||
|
||||
var processMapPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, token);
|
||||
|
||||
if (!processMapPlan.Any())
|
||||
return Enumerable.Empty<ProcessMapReportDto>();
|
||||
|
||||
var telemetryDataStat = (await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token)).ToArray();
|
||||
if (!telemetryDataStat.Any())
|
||||
return Enumerable.Empty<ProcessMapReportDto>();
|
||||
|
||||
var result = CalcByIntervals(processMapPlan, telemetryDataStat);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private IEnumerable<ProcessMapReportDto> CalcByIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan, TelemetryDataSaubStatDto[] telemetryDataStat)
|
||||
{
|
||||
var processMapIntervals = CalcDepthIntervals(processMapPlan);
|
||||
|
||||
var result = new List<ProcessMapReportDto>(processMapIntervals.Count() * 4);
|
||||
|
||||
var telemetryIndexStart = Array.FindIndex(telemetryDataStat, t => t.WellDepthMin >= processMapIntervals.First().DepthStart);
|
||||
if (telemetryIndexStart < 0)
|
||||
return Enumerable.Empty<ProcessMapReportDto>();
|
||||
|
||||
IDictionary<int, string> sectionTypes = wellOperationRepository
|
||||
.GetSectionTypes()
|
||||
.ToDictionary(s => s.Id, s => s.Caption);
|
||||
|
||||
foreach (var interval in processMapIntervals)
|
||||
{
|
||||
// plans [ ][ ]
|
||||
// interval [ ]
|
||||
var processMapPlanInterval = processMapPlan
|
||||
.Where(p => p.DepthStart <= interval.DepthEnd && p.DepthEnd >= interval.DepthStart);
|
||||
|
||||
if (!processMapPlanInterval.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<ProcessMapReportDto> subIntervalsResult = CalcSubIntervals(interval, processMapPlanInterval, telemetryDataInterval, sectionTypes);
|
||||
|
||||
result.AddRange(subIntervalsResult);
|
||||
telemetryIndexStart = telemetryIndexEnd;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<(double DepthStart, double DepthEnd)> CalcDepthIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan)
|
||||
{
|
||||
if(!processMapPlan.Any())
|
||||
yield break;
|
||||
|
||||
var intervalStarts = processMapPlan
|
||||
.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], processMapPlan.Max(p=>p.DepthEnd));
|
||||
}
|
||||
|
||||
private static IEnumerable<ProcessMapReportDto> CalcSubIntervals(
|
||||
(double DepthStart, double DepthEnd) interval,
|
||||
IEnumerable<ProcessMapPlanDto> processMapPlanInterval,
|
||||
Span<TelemetryDataSaubStatDto> telemetryDataInterval,
|
||||
IDictionary<int, string> sectionTypes)
|
||||
{
|
||||
var telemetryDataIntervalLength = telemetryDataInterval.Length;
|
||||
if (telemetryDataInterval.Length == 0)
|
||||
return Enumerable.Empty<ProcessMapReportDto>();
|
||||
|
||||
var result = new List<ProcessMapReportDto>();
|
||||
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, processMapPlanInterval, telemetryRowSpan, sectionTypes);
|
||||
result.Add(intervalReportRow);
|
||||
}
|
||||
telemetryIndexStart = i;
|
||||
subInterval.DepthStart = subInterval.DepthEnd;
|
||||
}
|
||||
}
|
||||
|
||||
subInterval.DepthEnd = interval.DepthEnd;
|
||||
var intervalReportRowLast = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryDataInterval[telemetryIndexStart..telemetryDataIntervalLength], sectionTypes);
|
||||
result.Add(intervalReportRowLast);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ProcessMapReportDto CalcSubIntervalReportRow(
|
||||
(double DepthStart, double DepthEnd) subInterval,
|
||||
IEnumerable<ProcessMapPlanDto> processMap,
|
||||
Span<TelemetryDataSaubStatDto> telemetryRowSpan,
|
||||
IDictionary<int, string> sectionTypes)
|
||||
{
|
||||
var telemetryStat = new TelemetryStat(telemetryRowSpan);
|
||||
var processMapByMode = processMap.FirstOrDefault(p => p.IdMode == telemetryStat.IdMode);
|
||||
var processMapFirst = processMap.First();
|
||||
var idWellSectionType = processMapByMode?.IdWellSectionType ?? processMapFirst.IdWellSectionType;
|
||||
|
||||
var result = new ProcessMapReportDto
|
||||
{
|
||||
IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell,
|
||||
IdWellSectionType = idWellSectionType,
|
||||
WellSectionTypeName = sectionTypes[idWellSectionType],
|
||||
|
||||
DepthStart = subInterval.DepthStart,
|
||||
DepthEnd = subInterval.DepthEnd,
|
||||
DateStart = telemetryStat.DateStart,
|
||||
|
||||
MechDrillingHours = telemetryStat.MechDrillingHours,
|
||||
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 = 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)
|
||||
{
|
||||
if (intervalStart.BlockSpeedSp <= 30)
|
||||
return true;
|
||||
else if (intervalStart.BlockSpeedSp > 30 && blockSpeedSpDiff > 15d)
|
||||
return true;
|
||||
else if (intervalStart.BlockSpeedSp > 80 && blockSpeedSpDiff > 20d)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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 ProcessMapReportParamsDto MakeParams(double? spPlan)
|
||||
{
|
||||
var result = new ProcessMapReportParamsDto
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
class TelemetryStat {
|
||||
public ParamStat Pressure { get; }
|
||||
public ParamStat AxialLoad {get; }
|
||||
public ParamStat RotorTorque {get; }
|
||||
public ParamStat BlockSpeed {get; }
|
||||
|
||||
private TelemetryDataSaubStatDto? previous;
|
||||
private double depthSum = 0d;
|
||||
private double hoursSum = 0d;
|
||||
|
||||
public double? Rop => hoursSum == 0d ? null : depthSum / hoursSum;
|
||||
|
||||
private double depthWithSaub = 0d;
|
||||
public double UsageSaub { get; }
|
||||
public double UsagePredictPlan { get; }
|
||||
public DateTime DateStart { get; }
|
||||
public float DeltaDepth { get; }
|
||||
public int IdMode { get; }
|
||||
public string ModeName { get; }
|
||||
public double MechDrillingHours { get; }
|
||||
|
||||
public TelemetryStat(Span<TelemetryDataSaubStatDto> telemetry)
|
||||
{
|
||||
var telemetryFirst = telemetry[0];
|
||||
var telemetryLast = telemetry[^1];
|
||||
|
||||
IdMode = telemetryFirst.IdMode;
|
||||
ModeName = GetModeName(IdMode);
|
||||
DateStart = telemetryFirst.DateMin;
|
||||
DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin;
|
||||
MechDrillingHours = (telemetryLast.DateMax - telemetryFirst.DateMin).TotalHours;
|
||||
|
||||
BlockSpeed = new(t => t.BlockSpeedSp, t => t.BlockSpeed, null, 1, IdMode);
|
||||
Pressure = new(t => t.PressureSpDelta, t => t.PressureDelta, t=>t.PressureDeltaLimitMax, 2, IdMode);
|
||||
RotorTorque = new(t => t.RotorTorqueSp, t => t.RotorTorque, t=>t.RotorTorqueLimitMax, 3, IdMode);
|
||||
AxialLoad = new(t => t.AxialLoadSp, t => t.AxialLoad, t=>t.AxialLoadLimitMax, 4, IdMode);
|
||||
|
||||
for (int i = 0; i < telemetry.Length; i++)
|
||||
UpdateStat(telemetry[i]);
|
||||
|
||||
UsageSaub = 100d * depthWithSaub / depthSum;
|
||||
UsagePredictPlan = IdMode != 0 ? 100d : 0d;
|
||||
}
|
||||
|
||||
private void UpdateStat(TelemetryDataSaubStatDto current)
|
||||
{
|
||||
if(previous is not null)
|
||||
{
|
||||
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
|
||||
if(deltaDepth > 0)
|
||||
{
|
||||
var deltaHours = (current.DateMin - previous.DateMax).TotalHours;
|
||||
depthSum += deltaDepth;
|
||||
hoursSum += deltaHours;
|
||||
|
||||
if(current.IdMode == 1 || current.IdMode == 3)
|
||||
depthWithSaub += deltaDepth;
|
||||
}
|
||||
}
|
||||
|
||||
previous = current;
|
||||
Pressure.UpdateStat(current);
|
||||
AxialLoad.UpdateStat(current);
|
||||
RotorTorque.UpdateStat(current);
|
||||
BlockSpeed.UpdateStat(current);
|
||||
}
|
||||
|
||||
private static string GetModeName(int idMode)
|
||||
=> idMode switch
|
||||
{
|
||||
1 => "Ротор",
|
||||
3 => "Слайд",
|
||||
_ => "Ручной",
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment;
|
||||
|
||||
public class ProcessMapWellboreDevelopmentService : IProcessMapWellboreDevelopmentService
|
||||
{
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository;
|
||||
|
||||
public ProcessMapWellboreDevelopmentService(ITelemetryService telemetryService,
|
||||
IWellService wellService,
|
||||
IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository)
|
||||
{
|
||||
this.telemetryService = telemetryService;
|
||||
this.wellService = wellService;
|
||||
this.processMapWellboreDevelopmentRepository = processMapWellboreDevelopmentRepository;
|
||||
}
|
||||
|
||||
public async Task<int> InsertAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken)
|
||||
?? throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.IdWell),
|
||||
$"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует");
|
||||
|
||||
processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow;
|
||||
|
||||
return await processMapWellboreDevelopmentRepository.InsertAsync(processMapWellboreDevelopment, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> UpdateAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken);
|
||||
|
||||
if (well is null)
|
||||
throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.IdWell),
|
||||
$"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует");
|
||||
|
||||
processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow;
|
||||
|
||||
var result = await processMapWellboreDevelopmentRepository.UpdateAsync(processMapWellboreDevelopment, cancellationToken);
|
||||
|
||||
if (result == ICrudRepository<ProcessMapWellboreDevelopmentDto>.ErrorIdNotFound)
|
||||
throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.Id),
|
||||
$"Проработки с Id: {processMapWellboreDevelopment.Id} не существует");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProcessMapWellboreDevelopmentDto>> GetByTelemetryAsync(string uid, DateTime updateFrom,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
|
||||
|
||||
if (!idWell.HasValue)
|
||||
throw new ArgumentInvalidException(nameof(uid), $"Неправильный телеметрии. Uid: {uid}");
|
||||
|
||||
return await processMapWellboreDevelopmentRepository.GetAllAsync(idWell.Value, updateFrom, cancellationToken);
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
using ClosedXML.Excel;
|
||||
using System;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMap;
|
||||
|
||||
internal static class XLExtentions
|
||||
{
|
||||
|
||||
public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false)
|
||||
{
|
||||
cell.Value = value;
|
||||
if (adaptRowHeight)
|
||||
{
|
||||
var colWidth = cell.WorksheetColumn().Width;
|
||||
var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize);
|
||||
if (value.Length > maxCharsToWrap)
|
||||
{
|
||||
var row = cell.WorksheetRow();
|
||||
var baseHeight = row.Height;
|
||||
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap);
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
public static IXLCell SetVal(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS")
|
||||
{
|
||||
cell.Value = value;
|
||||
cell.DataType = XLDataType.DateTime;
|
||||
cell.Style.DateFormat.Format = dateFormat;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
public static IXLCell SetVal(this IXLCell cell, int? value, string format = "0.00")
|
||||
{
|
||||
cell.Value = value;
|
||||
cell.DataType = XLDataType.Number;
|
||||
cell.Style.NumberFormat.Format = format;
|
||||
return cell;
|
||||
}
|
||||
|
||||
public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00")
|
||||
{
|
||||
cell.Value = (value is not null && double.IsFinite(value.Value)) ? value : null;
|
||||
cell.DataType = XLDataType.Number;
|
||||
cell.Style.NumberFormat.Format = format;
|
||||
return cell;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMaps.Report.Data;
|
||||
|
||||
internal class TelemetryStat
|
||||
{
|
||||
public ParamStat Pressure { get; }
|
||||
public ParamStat AxialLoad { get; }
|
||||
public ParamStat RotorTorque { get; }
|
||||
public ParamStat BlockSpeed { get; }
|
||||
|
||||
private TelemetryDataSaubStatDto? previous;
|
||||
private double depthSum = 0d;
|
||||
private double hoursSum = 0d;
|
||||
|
||||
public double? Rop => hoursSum == 0d ? null : depthSum / hoursSum;
|
||||
|
||||
private double depthWithSaub = 0d;
|
||||
public double UsageSaub { get; }
|
||||
public double UsagePredictPlan { get; }
|
||||
public DateTime DateStart { get; }
|
||||
public float DeltaDepth { get; }
|
||||
public int IdMode { get; }
|
||||
public string ModeName { get; }
|
||||
public double DrillingHours { get; }
|
||||
|
||||
public TelemetryStat(Span<TelemetryDataSaubStatDto> telemetry)
|
||||
{
|
||||
var telemetryFirst = telemetry[0];
|
||||
var telemetryLast = telemetry[^1];
|
||||
|
||||
IdMode = telemetryFirst.IdMode;
|
||||
ModeName = GetModeName(IdMode);
|
||||
DateStart = telemetryFirst.DateMin;
|
||||
DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin;
|
||||
DrillingHours = (telemetryLast.DateMax - telemetryFirst.DateMin).TotalHours;
|
||||
|
||||
BlockSpeed = new(t => t.BlockSpeedSp, t => t.BlockSpeed, null, 1, IdMode);
|
||||
Pressure = new(t => t.PressureSpDelta, t => t.PressureDelta, t => t.PressureDeltaLimitMax, 2, IdMode);
|
||||
RotorTorque = new(t => t.RotorTorqueSp, t => t.RotorTorque, t => t.RotorTorqueLimitMax, 3, IdMode);
|
||||
AxialLoad = new(t => t.AxialLoadSp, t => t.AxialLoad, t => t.AxialLoadLimitMax, 4, IdMode);
|
||||
|
||||
foreach (var t in telemetry)
|
||||
UpdateStat(t);
|
||||
|
||||
UsageSaub = 100d * depthWithSaub / depthSum;
|
||||
UsagePredictPlan = IdMode != 0 ? 100d : 0d;
|
||||
}
|
||||
|
||||
private void UpdateStat(TelemetryDataSaubStatDto current)
|
||||
{
|
||||
if (previous is not null)
|
||||
{
|
||||
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
|
||||
|
||||
if (deltaDepth > 0)
|
||||
{
|
||||
var deltaHours = (current.DateMin - previous.DateMax).TotalHours;
|
||||
depthSum += deltaDepth;
|
||||
hoursSum += deltaHours;
|
||||
|
||||
if (current.IdMode == 1 || current.IdMode == 3)
|
||||
depthWithSaub += deltaDepth;
|
||||
}
|
||||
}
|
||||
|
||||
previous = current;
|
||||
Pressure.UpdateStat(current);
|
||||
AxialLoad.UpdateStat(current);
|
||||
RotorTorque.UpdateStat(current);
|
||||
BlockSpeed.UpdateStat(current);
|
||||
}
|
||||
|
||||
private static string GetModeName(int idMode)
|
||||
=> idMode switch
|
||||
{
|
||||
1 => "Ротор",
|
||||
3 => "Слайд",
|
||||
_ => "Ручной",
|
||||
};
|
||||
}
|
@ -0,0 +1,224 @@
|
||||
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, XLEventTracking.Disabled);
|
||||
|
||||
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)
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
||||
if (sheet is null)
|
||||
return;
|
||||
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()
|
||||
.SetVal(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)
|
||||
.SetVal(interval.DepthStart, "0.0");
|
||||
|
||||
sheet.Cell(row, columnDepth)
|
||||
.SetVal(interval.DepthEnd, "0.0");
|
||||
|
||||
sheet.Cell(row, columnDate)
|
||||
.SetVal(interval.DateStart);
|
||||
|
||||
sheet.Cell(row, columnRopTime)
|
||||
.SetVal(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)
|
||||
.SetVal(modeData.DrillingMode);
|
||||
|
||||
sheet.Cell(row, columnDeltaDepth)
|
||||
.SetVal(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)
|
||||
.SetVal(modeData.UsagePlan);
|
||||
|
||||
sheet.Cell(row, columnUsageFact)
|
||||
.SetVal(modeData.UsageFact);
|
||||
|
||||
sheet.Cell(row, columnRop)
|
||||
.SetVal(modeData.Rop);
|
||||
|
||||
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)
|
||||
.SetVal(dataParam.SetpointPlan);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetSpFact)
|
||||
.SetVal(dataParam.SetpointFact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetFact)
|
||||
.SetVal(dataParam.Fact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetLimit)
|
||||
.SetVal(dataParam.Limit);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetPercent)
|
||||
.SetVal(dataParam.SetpointUsage, format: "0.0");
|
||||
}
|
||||
|
||||
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)
|
||||
.SetVal(dataParam.SetpointPlan);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetSpFact)
|
||||
.SetVal(dataParam.SetpointFact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetFact)
|
||||
.SetVal(dataParam.Fact);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetLimit)
|
||||
.SetVal(dataParam.Limit);
|
||||
|
||||
sheet.Cell(row, column + columnOffsetPercent)
|
||||
.SetVal(dataParam.SetpointUsage, format: "0.0");
|
||||
}
|
||||
|
||||
private static Stream GetExcelTemplateStream()
|
||||
{
|
||||
var stream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream(
|
||||
"AsbCloudInfrastructure.Services.ProcessMaps.Report.ProcessMapReportTemplate.xlsx");
|
||||
|
||||
return stream!;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
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)
|
||||
throw new ArgumentInvalidException(nameof(idWell), $"Скважина с Id: {idWell} не имеет телеметрии");
|
||||
|
||||
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 = 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,366 @@
|
||||
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!
|
||||
*/
|
||||
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 columnWellSectionType = 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.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
||||
?? throw new FileFormatException($"Книга excel не содержит листа {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)
|
||||
{
|
||||
row.Cell(columnWellSectionType).Value = sections.First(x => x.Id == processMapPlanWellDrillings.IdWellSectionType).Caption;
|
||||
row.Cell(columnMode).Value = GetModeCaption(processMapPlanWellDrillings.IdMode);
|
||||
row.Cell(columnDepthStart).Value = processMapPlanWellDrillings.DepthStart;
|
||||
row.Cell(columnDepthEnd).Value = processMapPlanWellDrillings.DepthEnd;
|
||||
row.Cell(columnPressurePlan).Value = processMapPlanWellDrillings.Pressure.Plan;
|
||||
row.Cell(columnPressureLimitMax).Value = processMapPlanWellDrillings.Pressure.LimitMax;
|
||||
row.Cell(columnAxialLoadPlan).Value = processMapPlanWellDrillings.AxialLoad.Plan;
|
||||
row.Cell(columnAxialLoadLimitMax).Value = processMapPlanWellDrillings.AxialLoad.LimitMax;
|
||||
row.Cell(columnTopDriveTorquePlan).Value = processMapPlanWellDrillings.TopDriveTorque.Plan;
|
||||
row.Cell(columnTopDriveTorqueLimitMax).Value = processMapPlanWellDrillings.TopDriveTorque.LimitMax;
|
||||
row.Cell(columnTopDriveSpeedPlan).Value = processMapPlanWellDrillings.TopDriveSpeed.Plan;
|
||||
row.Cell(columnTopDriveSpeedLimitMax).Value = processMapPlanWellDrillings.TopDriveSpeed.LimitMax;
|
||||
row.Cell(columnFlowPlan).Value = processMapPlanWellDrillings.Flow.Plan;
|
||||
row.Cell(columnFlowLimitMax).Value = processMapPlanWellDrillings.Flow.LimitMax;
|
||||
row.Cell(columnRopPlan).Value = processMapPlanWellDrillings.RopPlan;
|
||||
row.Cell(columnUsageSaub).Value = processMapPlanWellDrillings.UsageSaub;
|
||||
row.Cell(columnUsageSpin).Value = processMapPlanWellDrillings.UsageSpin;
|
||||
row.Cell(columnComment).Value = processMapPlanWellDrillings.Comment;
|
||||
}
|
||||
|
||||
private IEnumerable<ProcessMapPlanWellDrillingDto> ParseWorkBook(IXLWorkbook workbook)
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
||||
?? throw new FileFormatException($"Книга excel не содержит листа {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(columnWellSectionType).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, XLEventTracking.Disabled);
|
||||
|
||||
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 => "Слайд",
|
||||
_ => "Ручной",
|
||||
};
|
||||
}
|
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.User;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Mapster;
|
||||
@ -20,71 +21,84 @@ namespace AsbCloudInfrastructure.Services
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CompanyWithUsersDto>> GetAsync(int wellId, int contactTypeId, CancellationToken token)
|
||||
public async Task<IEnumerable<ContactDto>> GetAllAsync(int wellId, int contactTypeId, CancellationToken token)
|
||||
{
|
||||
var query = db.Companies
|
||||
var query = db.Contacts
|
||||
.Where(c => c.IdCompanyType == contactTypeId)
|
||||
.Where(c => c.RelationCompaniesWells.Any(rc => rc.IdWell == wellId))
|
||||
.Select(c => new CompanyWithUsersDto()
|
||||
{
|
||||
Caption = c.Caption,
|
||||
Id = c.Id,
|
||||
Users = c.Users
|
||||
.Where(u => u.IdState == 1)
|
||||
.OrderBy(u => u.Surname)
|
||||
.Select(u => new UserContactDto()
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.Name,
|
||||
Patronymic = u.Patronymic,
|
||||
Surname = u.Surname,
|
||||
Company = u.Company.Adapt<CompanyDto>(),
|
||||
Email = u.Email,
|
||||
Phone = u.Phone,
|
||||
Position = u.Position,
|
||||
IsContact = u.RelationContactsWells.Any(rel => rel.IdWell == wellId)
|
||||
})
|
||||
});
|
||||
.Where(c => c.IdWell == wellId)
|
||||
.Select(c => c.Adapt<ContactDto>());
|
||||
|
||||
var entities = await query.AsNoTracking()
|
||||
.ToArrayAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
.ToArrayAsync(token);
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CompanyTypeDto>> GetTypesAsync(int idWell, CancellationToken token)
|
||||
public async Task<ContactDto?> GetAsync(int idWell, int id, CancellationToken token)
|
||||
{
|
||||
var dbContact = await GetContact(idWell, id, token);
|
||||
|
||||
var result = dbContact?.Adapt<ContactDto>();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CompanyTypeDto>> GetTypesAsync(CancellationToken token)
|
||||
{
|
||||
var query = db.CompaniesTypes
|
||||
.Where(t => t.IsContact)
|
||||
.Where(t => t.Companies.Any(c => c.Users.Any() && c.RelationCompaniesWells.Any(w => w.IdWell == idWell)))
|
||||
.OrderBy(t => t.Order);
|
||||
|
||||
var entities = await query.AsNoTracking()
|
||||
.ToArrayAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var dtos = entities.Adapt<IEnumerable<CompanyTypeDto>>();
|
||||
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<int> UpdateRangeAsync(int idWell, int contactTypeId, IEnumerable<int> userIds, CancellationToken token)
|
||||
public async Task<int> InsertAsync(ContactDto contactDto, CancellationToken token)
|
||||
{
|
||||
var items = db.RelationContactsWells
|
||||
.Where(x => x.IdWell == idWell && x.User.Company.IdCompanyType == contactTypeId);
|
||||
var entity = contactDto.Adapt<Contact>();
|
||||
|
||||
var wellContacts = userIds.Select(userId => new RelationContactWell()
|
||||
{
|
||||
IdWell = idWell,
|
||||
IdUser = userId,
|
||||
});
|
||||
db.Contacts.Add(entity);
|
||||
|
||||
db.RelationContactsWells.RemoveRange(items);
|
||||
db.RelationContactsWells.AddRange(wellContacts);
|
||||
await db.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
return entity.Id;
|
||||
}
|
||||
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
public async Task<int> UpdateAsync(ContactDto contactDto, CancellationToken token)
|
||||
{
|
||||
var dbContact = await GetContact(contactDto.IdWell, contactDto.Id, token);
|
||||
if (dbContact is null)
|
||||
throw new ForbidException("Contact doesn't exist");
|
||||
|
||||
var entity = contactDto.Adapt<Contact>();
|
||||
db.Contacts.Update(entity);
|
||||
|
||||
return await db.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteAsync(int idWell, int id, CancellationToken token)
|
||||
{
|
||||
var dbContact = await GetContact(idWell, id, token);
|
||||
if (dbContact is null)
|
||||
throw new ForbidException("Contact doesn't exist");
|
||||
|
||||
db.Contacts.Remove(dbContact);
|
||||
return await db.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
private async Task<Contact?> GetContact(int idWell, int idContact, CancellationToken token)
|
||||
{
|
||||
var contact = await db.Contacts
|
||||
.Where(c => c.IdWell == idWell)
|
||||
.Where(c => c.Id == idContact)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(token);
|
||||
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Data.WITS;
|
||||
using AsbCloudApp.Repositories;
|
||||
@ -15,6 +14,7 @@ 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;
|
||||
|
||||
@ -34,7 +34,7 @@ public class WellInfoService
|
||||
{
|
||||
var wellService = services.GetRequiredService<IWellService>();
|
||||
var operationsStatService = services.GetRequiredService<IOperationsStatService>();
|
||||
var processMapRepository = services.GetRequiredService<IProcessMapPlanRepository>();
|
||||
var processMapPlanWellDrillingRepository = services.GetRequiredService<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>>();
|
||||
var subsystemOperationTimeService = services.GetRequiredService<ISubsystemOperationTimeService>();
|
||||
var telemetryDataSaubCache = services.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
|
||||
var messageHub = services.GetRequiredService<IIntegrationEventHandler<UpdateWellInfoEvent>>();
|
||||
@ -44,10 +44,10 @@ public class WellInfoService
|
||||
|
||||
var wellsIds = activeWells.Select(w => w.Id);
|
||||
|
||||
var processMapRequests = wellsIds.Select(id => new ProcessMapRequest { IdWell = id });
|
||||
var processMaps = await processMapRepository.GetProcessMapAsync(processMapRequests, token);
|
||||
var processMapPlanWellDrillingRequests = wellsIds.Select(id => new ProcessMapPlanRequest { IdWell = id });
|
||||
var processMapPlanWellDrillings = await processMapPlanWellDrillingRepository.GetAsync(processMapPlanWellDrillingRequests, token);
|
||||
|
||||
var wellDepthByProcessMap = processMaps
|
||||
var wellDepthByProcessMap = processMapPlanWellDrillings
|
||||
.GroupBy(p => p.IdWell)
|
||||
.Select(g => new
|
||||
{
|
||||
@ -85,20 +85,20 @@ public class WellInfoService
|
||||
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
|
||||
currentDepth ??= wellLastFactSection?.Fact?.WellDepthEnd;
|
||||
|
||||
var wellProcessMaps = processMaps
|
||||
var wellProcessMaps = processMapPlanWellDrillings
|
||||
.Where(p => p.IdWell == well.Id)
|
||||
.OrderBy(p => p.DepthEnd);
|
||||
|
||||
int? idSection = wellLastFactSection?.Id;
|
||||
ProcessMapPlanDto? wellProcessMap = null;
|
||||
ProcessMapPlanWellDrillingDto? processMapPlanWellDrilling = null;
|
||||
|
||||
if (idSection.HasValue)
|
||||
{
|
||||
wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
||||
processMapPlanWellDrilling = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
||||
}
|
||||
else if (currentDepth.HasValue)
|
||||
{
|
||||
wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
|
||||
processMapPlanWellDrilling = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
|
||||
}
|
||||
|
||||
double? planTotalDepth = null;
|
||||
@ -114,25 +114,25 @@ public class WellInfoService
|
||||
|
||||
wellMapInfo.AxialLoad = new()
|
||||
{
|
||||
Plan = wellProcessMap?.AxialLoad.Plan,
|
||||
Plan = processMapPlanWellDrilling?.AxialLoad.Plan,
|
||||
Fact = lastSaubTelemetry?.AxialLoad
|
||||
};
|
||||
|
||||
wellMapInfo.TopDriveSpeed = new()
|
||||
{
|
||||
Plan = wellProcessMap?.TopDriveSpeed.Plan,
|
||||
Plan = processMapPlanWellDrilling?.TopDriveSpeed.Plan,
|
||||
Fact = lastSaubTelemetry?.RotorSpeed
|
||||
};
|
||||
|
||||
wellMapInfo.TopDriveTorque = new()
|
||||
{
|
||||
Plan = wellProcessMap?.TopDriveTorque.Plan,
|
||||
Plan = processMapPlanWellDrilling?.TopDriveTorque.Plan,
|
||||
Fact = lastSaubTelemetry?.RotorTorque
|
||||
};
|
||||
|
||||
wellMapInfo.Pressure = new()
|
||||
{
|
||||
Plan = wellProcessMap?.Pressure.Plan,
|
||||
Plan = processMapPlanWellDrilling?.Pressure.Plan,
|
||||
Fact = lastSaubTelemetry?.Pressure
|
||||
};
|
||||
|
||||
@ -146,7 +146,7 @@ public class WellInfoService
|
||||
|
||||
wellMapInfo.ROP = new()
|
||||
{
|
||||
Plan = wellProcessMap?.RopPlan,
|
||||
Plan = processMapPlanWellDrilling?.RopPlan,
|
||||
Fact = wellOperationsStat?.Total.Fact?.Rop,
|
||||
};
|
||||
|
||||
|
@ -122,7 +122,42 @@ internal static class XLExtentions
|
||||
return cell;
|
||||
}
|
||||
|
||||
internal static IXLStyle SetAllBorders(this IXLStyle style, XLBorderStyleValues borderStyle = XLBorderStyleValues.Thin)
|
||||
public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00")
|
||||
{
|
||||
cell.Value = (value is not null && double.IsFinite(value.Value)) ? value : null;
|
||||
cell.DataType = XLDataType.Number;
|
||||
cell.Style.NumberFormat.Format = format;
|
||||
return cell;
|
||||
}
|
||||
|
||||
public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false)
|
||||
{
|
||||
cell.Value = value;
|
||||
if (adaptRowHeight)
|
||||
{
|
||||
var colWidth = cell.WorksheetColumn().Width;
|
||||
var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize);
|
||||
if (value.Length > maxCharsToWrap)
|
||||
{
|
||||
var row = cell.WorksheetRow();
|
||||
var baseHeight = row.Height;
|
||||
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap);
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
public static IXLCell SetVal(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS")
|
||||
{
|
||||
cell.Value = value;
|
||||
cell.DataType = XLDataType.DateTime;
|
||||
cell.Style.DateFormat.Format = dateFormat;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
internal static IXLStyle SetAllBorders(this IXLStyle style, XLBorderStyleValues borderStyle = XLBorderStyleValues.Thin)
|
||||
{
|
||||
style.Border.RightBorder = borderStyle;
|
||||
style.Border.LeftBorder = borderStyle;
|
||||
|
@ -1,284 +0,0 @@
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// РТК
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
public class ProcessMapController : CrudWellRelatedController<ProcessMapPlanDto, IProcessMapPlanRepository>
|
||||
{
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly IHubContext<TelemetryHub> telemetryHubContext;
|
||||
private readonly IProcessMapReportMakerService processMapReportService;
|
||||
private readonly IProcessMapService processMapService;
|
||||
private readonly IProcessMapPlanImportService processMapPlanImportService;
|
||||
private readonly IUserRepository userRepository;
|
||||
|
||||
private const string SirnalRMethodGetDataName = "UpdateProcessMap";
|
||||
|
||||
public ProcessMapController(
|
||||
IWellService wellService,
|
||||
IProcessMapPlanRepository repository,
|
||||
IProcessMapReportMakerService processMapReportService,
|
||||
IProcessMapService processMapService,
|
||||
ITelemetryService telemetryService,
|
||||
IHubContext<TelemetryHub> telemetryHubContext,
|
||||
IProcessMapPlanImportService processMapPlanImportService,
|
||||
IUserRepository userRepository)
|
||||
: base(wellService, repository)
|
||||
{
|
||||
this.telemetryService = telemetryService;
|
||||
this.telemetryHubContext = telemetryHubContext;
|
||||
this.processMapReportService = processMapReportService;
|
||||
this.processMapService = processMapService;
|
||||
this.processMapPlanImportService = processMapPlanImportService;
|
||||
this.userRepository = userRepository;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает все значения для коридоров бурения по uid панели
|
||||
/// </summary>
|
||||
/// <param name="uid"> uid панели </param>
|
||||
/// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns> Список параметров для коридоров бурения </returns>
|
||||
[HttpGet("/api/telemetry/{uid}/drillFlowChart")]
|
||||
[Obsolete("use GetByUidAsync(..) instead")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
||||
public IActionResult GetByTelemetry(string uid, DateTime updateFrom, CancellationToken token)
|
||||
{
|
||||
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
|
||||
if (idWell is null)
|
||||
return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}");
|
||||
return Ok(Enumerable.Empty<ProcessMapPlanDto>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает РТК по uid телеметрии
|
||||
/// </summary>
|
||||
/// <param name="uid"> uid телеметрии </param>
|
||||
/// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns> Список параметров для коридоров бурения </returns>
|
||||
[HttpGet("/api/telemetry/{uid}/processMap")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
||||
public async Task<IActionResult> GetByUidAsync(string uid, DateTime updateFrom, CancellationToken token)
|
||||
{
|
||||
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
|
||||
if (idWell is null)
|
||||
return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}");
|
||||
|
||||
var dto = await service.GetAllAsync((int)idWell,
|
||||
updateFrom, token);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выгрузка расширенной РТК
|
||||
/// </summary>
|
||||
/// <param name="wellId"></param>
|
||||
/// /// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("report/{wellId}")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> GetReportFileAsync(int wellId, CancellationToken token)
|
||||
{
|
||||
var stream = await processMapReportService.MakeReportAsync(wellId, token);
|
||||
if (stream != null)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(wellId, token);
|
||||
if (well is null)
|
||||
return NoContent();
|
||||
|
||||
var fileName = $"РТК по скважине {well.Caption} куст {well.Cluster}.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выгрузка режимной карты по бурению скважины
|
||||
/// </summary>
|
||||
/// <param name="wellId"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("report/{wellId}/data")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapReportDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetDrillProcessMap(int wellId, CancellationToken token)
|
||||
{
|
||||
var data = await processMapService.GetProcessMapReportAsync(wellId, token);
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить запись плановой РТК
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<ActionResult<int>> InsertAsync([FromBody] ProcessMapPlanDto value, CancellationToken token)
|
||||
{
|
||||
value.IdUser = User.GetUserId()
|
||||
?? throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToProcessMapAsync(value.IdWell, token);
|
||||
|
||||
var result = await base.InsertAsync(value, token);
|
||||
await NotifyUsersBySignalR(value.IdWell, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Редактировать запись по id плановой РТК
|
||||
/// </summary>
|
||||
/// <param name="value">запись</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>1 - успешно отредактировано, 0 - нет</returns>
|
||||
public override async Task<ActionResult<int>> UpdateAsync([FromBody] ProcessMapPlanDto value, CancellationToken token)
|
||||
{
|
||||
value.IdUser = User.GetUserId()
|
||||
?? throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToProcessMapAsync(value.IdWell, token);
|
||||
|
||||
var result = await base.UpdateAsync(value, token);
|
||||
await NotifyUsersBySignalR(value.IdWell, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override async Task<ActionResult<int>> DeleteAsync(int id, CancellationToken token)
|
||||
{
|
||||
await AssertUserHasAccessToProcessMapAsync(id, token);
|
||||
|
||||
return await base.DeleteAsync(id, token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает шаблон файла импорта плановой РТК
|
||||
/// </summary>
|
||||
/// <returns>Запрашиваемый файл</returns>
|
||||
[HttpGet("template")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
public async Task<IActionResult> GetTemplateAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var stream = await processMapPlanImportService.GetExcelTemplateStreamAsync(cancellationToken);
|
||||
var fileName = "ЕЦП_шаблон_файла_РТК.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Импортирует плановой РТК из excel (xlsx) файла
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="options">Удалить РТК перед импортом = 1, если файл валидный</param>
|
||||
/// <param name="file">Загружаемый файл</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("import/{idWell}/{options}")]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
||||
public async Task<IActionResult> ImportAsync(int idWell,
|
||||
int options,
|
||||
[Required] IFormFile file,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToProcessMapAsync(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.Value,
|
||||
(options & 1) > 0,
|
||||
stream,
|
||||
cancellationToken);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
{
|
||||
return this.ValidationBadRequest(nameof(file), ex.Message);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Экспорт плановой РТК в excel
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("export/{idWell}")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> ExportAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken);
|
||||
|
||||
if (well is null)
|
||||
return NoContent();
|
||||
|
||||
var stream = await processMapPlanImportService.ExportAsync(idWell, cancellationToken);
|
||||
var fileName = $"РТК-план по скважине {well.Caption} куст {well.Cluster}.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
private async Task AssertUserHasAccessToProcessMapAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
var idCompany = User.GetCompanyId();
|
||||
|
||||
if (!idCompany.HasValue || !idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
|
||||
?? throw new ForbidException($"Скважины с {idWell} не существует");
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
if (well.IdState == 2 && !userRepository.HasPermission(idUser.Value, "ProcessMap.editCompletedWell"))
|
||||
throw new ForbidException("Недостаточно прав для редактирования РТК завершённой скважины");
|
||||
}
|
||||
|
||||
private async Task NotifyUsersBySignalR(int idWell, CancellationToken token)
|
||||
{
|
||||
var dtos = await service.GetAllAsync(idWell, null, token);
|
||||
_ = Task.Run(() => telemetryHubContext.Clients.Group($"well_{idWell}")
|
||||
.SendAsync(SirnalRMethodGetDataName, dtos), CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Проработка скважины
|
||||
/// </summary>
|
||||
public class ProcessMapWellboreDevelopmentController : CrudWellRelatedController<ProcessMapWellboreDevelopmentDto,
|
||||
IProcessMapWellboreDevelopmentRepository>
|
||||
{
|
||||
private readonly IUserRepository userRepository;
|
||||
private readonly IProcessMapWellboreDevelopmentService processMapWellboreDevelopmentService;
|
||||
|
||||
public ProcessMapWellboreDevelopmentController(IWellService wellService,
|
||||
IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository,
|
||||
IUserRepository userRepository,
|
||||
IProcessMapWellboreDevelopmentService processMapWellboreDevelopmentService)
|
||||
: base(wellService, processMapWellboreDevelopmentRepository)
|
||||
{
|
||||
this.userRepository = userRepository;
|
||||
this.processMapWellboreDevelopmentService = processMapWellboreDevelopmentService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить запись проработки
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<ActionResult<int>> InsertAsync(ProcessMapWellboreDevelopmentDto value, CancellationToken token)
|
||||
{
|
||||
value.IdUser = User.GetUserId()
|
||||
?? throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(value.IdWell, token);
|
||||
|
||||
return await processMapWellboreDevelopmentService.InsertAsync(value, token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновить запись проработки
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<ActionResult<int>> UpdateAsync(ProcessMapWellboreDevelopmentDto value, CancellationToken token)
|
||||
{
|
||||
value.IdUser = User.GetUserId()
|
||||
?? throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(value.IdWell, token);
|
||||
|
||||
return await processMapWellboreDevelopmentService.UpdateAsync(value, token);
|
||||
}
|
||||
|
||||
public override async Task<ActionResult<int>> DeleteAsync(int id, CancellationToken token)
|
||||
{
|
||||
await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(id, token);
|
||||
|
||||
return await base.DeleteAsync(id, token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает проработки по uid телеметрии
|
||||
/// </summary>
|
||||
/// <param name="uid">Уникальный ключ телеметрии</param>
|
||||
/// <param name="updateFrom">Необязательный параметр. Начальная дата</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("telemetry/{uid}")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapWellboreDevelopmentDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetByUidAsync(string uid, DateTime updateFrom, CancellationToken cancellationToken)
|
||||
{
|
||||
var dto = await processMapWellboreDevelopmentService.GetByTelemetryAsync(uid, updateFrom,
|
||||
cancellationToken);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
private async Task AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
var idCompany = User.GetCompanyId();
|
||||
|
||||
if (!idCompany.HasValue || !idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
|
||||
?? throw new ForbidException($"Скважины с {idWell} не существует");
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
if (well.IdState == 2 && !userRepository.HasPermission(idUser.Value, "ProcessMap.editCompletedWell"))
|
||||
throw new ForbidException("Недостаточно прав для редактирования РТК завершённой скважины");
|
||||
}
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.ProcessMaps;
|
||||
|
||||
/// <summary>
|
||||
/// РТК
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
[Authorize]
|
||||
public abstract class ProcessMapBaseController<T> : ControllerBase
|
||||
where T : ProcessMapPlanBaseDto
|
||||
{
|
||||
private readonly IHubContext<TelemetryHub> telemetryHubContext;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
|
||||
public abstract string SignalRMethod { get; }
|
||||
|
||||
protected int IdUser
|
||||
{
|
||||
get
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
return idUser.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IWellService wellService;
|
||||
private readonly IUserRepository userRepository;
|
||||
private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository;
|
||||
|
||||
protected readonly IProcessMapPlanRepository<T> repository;
|
||||
|
||||
protected ProcessMapBaseController(IWellService wellService,
|
||||
IProcessMapPlanRepository<T> repository,
|
||||
IUserRepository userRepository,
|
||||
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
||||
IHubContext<TelemetryHub> telemetryHubContext,
|
||||
ITelemetryService telemetryService)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.repository = repository;
|
||||
this.userRepository = userRepository;
|
||||
this.wellSectionRepository = wellSectionRepository;
|
||||
this.telemetryHubContext = telemetryHubContext;
|
||||
this.telemetryService = telemetryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание плановой РТК
|
||||
/// </summary>
|
||||
/// <param name="processMap">Тело запроса</param>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
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);
|
||||
|
||||
await NotifyUsersBySignalR(idWell, cancellationToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновление плановой РТК
|
||||
/// </summary>
|
||||
/// <param name="processMap">Тело запроса</param>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
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);
|
||||
|
||||
if (result == ICrudRepository<T>.ErrorIdNotFound)
|
||||
return this.ValidationBadRequest(nameof(processMap.Id), $"РТК с Id: {processMap.Id} не существует");
|
||||
|
||||
await NotifyUsersBySignalR(idWell, cancellationToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удаление плановой РТК
|
||||
/// </summary>
|
||||
/// <param name="id">Id удаляемой РТК</param>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
public virtual async Task<IActionResult> DeleteAsync(int id, int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken);
|
||||
|
||||
var result = await repository.DeleteAsync(id, cancellationToken);
|
||||
|
||||
await NotifyUsersBySignalR(idWell, cancellationToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение РТК по Id скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var processMaps = await repository.GetByIdWellAsync(idWell, cancellationToken);
|
||||
|
||||
return Ok(processMaps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение РТК по телеметрии
|
||||
/// </summary>
|
||||
/// <param name="uid">Уникальный ключ телеметрии</param>
|
||||
/// <param name="updateFrom">Дата с которой требуется получить РТК</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("/api/telemetry/{uid}/[controller]")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<IEnumerable<T>>> GetProcessMapPlanByTelemetry(string uid, DateTime updateFrom, CancellationToken cancellationToken)
|
||||
{
|
||||
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
|
||||
|
||||
if (!idWell.HasValue)
|
||||
return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}");
|
||||
|
||||
var requests = new[] { new ProcessMapPlanRequest
|
||||
{
|
||||
IdWell = idWell.Value,
|
||||
UpdateFrom = updateFrom
|
||||
}
|
||||
};
|
||||
|
||||
var processMaps = await repository.GetAsync(requests, cancellationToken);
|
||||
|
||||
return Ok(processMaps);
|
||||
}
|
||||
|
||||
protected async Task AssertUserHasAccessToEditProcessMapAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
|
||||
?? throw new ArgumentInvalidException(nameof(idWell), $"Скважины с {idWell} не существует");
|
||||
|
||||
var idCompany = User.GetCompanyId();
|
||||
|
||||
if (!idCompany.HasValue ||
|
||||
!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
if (well.IdState == 2 && !userRepository.HasPermission(IdUser, "ProcessMap.editCompletedWell"))
|
||||
throw new ForbidException("Недостаточно прав для редактирования РТК завершенной скважины");
|
||||
}
|
||||
|
||||
protected async Task NotifyUsersBySignalR(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var dtos = await repository.GetByIdWellAsync(idWell, cancellationToken);
|
||||
|
||||
await telemetryHubContext.Clients
|
||||
.Group($"{SignalRMethod}_{idWell}")
|
||||
.SendAsync("UpdateProcessMap", dtos, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken)
|
||||
{
|
||||
_ = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken)
|
||||
?? throw new ArgumentInvalidException(nameof(ProcessMapPlanWellDrillingDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден");
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Services.ProcessMaps;
|
||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.ProcessMaps;
|
||||
|
||||
public class ProcessMapWellDrillingController : ProcessMapBaseController<ProcessMapPlanWellDrillingDto>
|
||||
{
|
||||
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService;
|
||||
private readonly IProcessMapReportWellDrillingExportService processMapReportWellDrillingExportService;
|
||||
private readonly IProcessMapPlanImportService processMapPlanImportService;
|
||||
|
||||
public override string SignalRMethod => "ProcessMapWellDrilling";
|
||||
|
||||
public ProcessMapWellDrillingController(IWellService wellService,
|
||||
IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> repository,
|
||||
IUserRepository userRepository,
|
||||
IProcessMapReportWellDrillingExportService processMapReportWellDrillingExportService,
|
||||
IProcessMapPlanImportService processMapPlanImportService,
|
||||
IProcessMapReportWellDrillingService processMapReportWellDrillingService,
|
||||
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
||||
IHubContext<TelemetryHub> telemetryHubContext,
|
||||
ITelemetryService telemetryService)
|
||||
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService)
|
||||
{
|
||||
this.processMapReportWellDrillingExportService = processMapReportWellDrillingExportService;
|
||||
this.processMapPlanImportService = processMapPlanImportService;
|
||||
this.processMapReportWellDrillingService = processMapReportWellDrillingService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение отчета РТК бурение
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("report")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanWellDrillingDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetReportAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var report = await processMapReportWellDrillingService.GetAsync(idWell, cancellationToken);
|
||||
|
||||
return Ok(report);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Экспорт отчета РТК бурение
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("report/export")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> ExportReportAsync(int idWell, CancellationToken cancellationToken)
|
||||
{
|
||||
var report = await processMapReportWellDrillingExportService.ExportAsync(idWell, cancellationToken);
|
||||
|
||||
if (report is null)
|
||||
return NoContent();
|
||||
|
||||
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>
|
||||
[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>
|
||||
[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>
|
||||
[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);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.ProcessMaps;
|
||||
|
||||
public class ProcessMapWellReamController : ProcessMapBaseController<ProcessMapPlanWellReamDto>
|
||||
{
|
||||
public ProcessMapWellReamController(IWellService wellService,
|
||||
IProcessMapPlanRepository<ProcessMapPlanWellReamDto> repository,
|
||||
IUserRepository userRepository,
|
||||
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
||||
IHubContext<TelemetryHub> telemetryHubContext,
|
||||
ITelemetryService telemetryService)
|
||||
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService)
|
||||
{
|
||||
}
|
||||
|
||||
public override string SignalRMethod => "ProccessMapWellReam";
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMap;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -7,6 +6,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
@ -73,7 +73,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <returns></returns>
|
||||
[HttpGet("compositeProcessMap")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanWellDrillingDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetCompositeProcessMap(int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
|
@ -1,10 +1,10 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.User;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -13,6 +13,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <summary>
|
||||
/// контроллер с контактной информацией по скважине
|
||||
/// </summary>
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class WellContactController : ControllerBase
|
||||
@ -29,66 +30,119 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <summary>
|
||||
/// получение списка типов контактов
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("api/well/{idWell}/contacts/types")]
|
||||
[HttpGet("type")]
|
||||
[ProducesResponseType(typeof(IEnumerable<CompanyTypeDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetTypesAsync(int idWell, CancellationToken token)
|
||||
public async Task<IActionResult> GetTypesAsync(CancellationToken token)
|
||||
{
|
||||
var result = await wellContactsRepository.GetTypesAsync(idWell, token).ConfigureAwait(false);
|
||||
var result = await wellContactsRepository.GetTypesAsync(token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение пользователей по типу контакта и ключу скважины
|
||||
/// Получение контактов по типу контакта и ключу скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="contactTypeId">тип контакта</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("api/well/{idWell}/contactType/{contactTypeId}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<CompanyWithUsersDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetAsync(int idWell, int contactTypeId, CancellationToken token)
|
||||
[HttpGet("type/{contactTypeId}")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ContactDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetAllAsync(int idWell, int contactTypeId, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await wellContactsRepository.GetAsync(idWell, contactTypeId, token).ConfigureAwait(false);
|
||||
var result = await wellContactsRepository.GetAllAsync(idWell, contactTypeId, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение контакта по ключу
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="id">ключ контакта</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(typeof(ContactDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetAsync(int idWell, int id, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await wellContactsRepository.GetAsync(idWell, id, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// добавление нового контакта
|
||||
/// </summary>
|
||||
/// <param name="contactDto">контакт</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> InsertAsync(
|
||||
[FromBody] ContactDto contactDto,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(contactDto.IdWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await wellContactsRepository.InsertAsync(contactDto, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// изменение контакта
|
||||
/// </summary>
|
||||
/// <param name="contactDto">контакт</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> UpdateAsync(
|
||||
[FromBody] ContactDto contactDto,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(contactDto.IdWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await wellContactsRepository.UpdateAsync(contactDto, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Создание контактов по ключу скважины, типу контакта и ключам пользователей
|
||||
/// Удаление контакта
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="contactTypeId">ключ типа контакта</param>
|
||||
/// <param name="userIds">ключи пользователей</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("api/well/{idWell}/contactType/{contactTypeId}")]
|
||||
/// <param name="id">id контакта</param>
|
||||
/// <param name="token">Токен отмены задачи</param>
|
||||
/// <returns>Количество удаленных из БД строк</returns>
|
||||
[HttpDelete("{id}")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> UpdateRangeAsync(
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")] int idWell,
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id типа контакта не может быть меньше 1")] int contactTypeId,
|
||||
[FromBody] IEnumerable<int> userIds,
|
||||
CancellationToken token)
|
||||
public async Task<IActionResult> DeleteAsync(int idWell, int id, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await wellContactsRepository.UpdateRangeAsync(idWell, contactTypeId, userIds, token).ConfigureAwait(false);
|
||||
var result = await wellContactsRepository.DeleteAsync(idWell, id, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
67
AsbCloudWebApi/Rest/WellContact.http
Normal file
67
AsbCloudWebApi/Rest/WellContact.http
Normal file
@ -0,0 +1,67 @@
|
||||
@baseUrl = http://127.0.0.1:5000
|
||||
@contentType = application/json
|
||||
@auth = Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2OTc0MzcwMzEsImV4cCI6MTcyODk5NDYzMSwiaXNzIjoiYSIsImF1ZCI6ImEifQ.vB7Qb3K9gG77iP8y25zB3RcZIQk9cHkq3I1SkcooYJs
|
||||
|
||||
@uid = 20210101_000000000
|
||||
@id = 1
|
||||
@idWell = 1
|
||||
@contactTypeId = 1
|
||||
|
||||
### ïîëó÷åíèå ñïèñêà òèïîâ êîíòàêòîâ
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/WellContact/type
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### Ïîëó÷åíèå êîíòàêòîâ ïî òèïó êîíòàêòà è êëþ÷ó ñêâàæèíû
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/WellContact/type/{{contactTypeId}}
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### Ïîëó÷åíèå êîíòàêòà ïî êëþ÷ó
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/WellContact/{{id}}
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### äîáàâëåíèå íîâîãî êîíòàêòà
|
||||
POST {{baseUrl}}/api/well/{{idWell}}/WellContact
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
{
|
||||
"id" : 2,
|
||||
"IdCompanyType" : 1,
|
||||
"IdWell": 1,
|
||||
"FullName": "batman",
|
||||
"Email": "aa@aa.aa",
|
||||
"Phone": "80000000000",
|
||||
"Position": "Ïîâàð",
|
||||
"Company": "Ìèøëåí ëòä"
|
||||
}
|
||||
|
||||
### èçìåíåíèå êîíòàêòà
|
||||
PUT {{baseUrl}}/api/well/{{idWell}}/WellContact
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
{
|
||||
"id" : 2,
|
||||
"IdCompanyType" : 1,
|
||||
"IdWell": 1,
|
||||
"FullName": "Áýòìàí Ñóïåðìåíîâè÷",
|
||||
"Email": "bb@bb.bb",
|
||||
"Phone": "80000000001",
|
||||
"Position": "Ïîâàð",
|
||||
"Company": "Ìèøëåí ëòä"
|
||||
}
|
||||
|
||||
### Óäàëåíèå êîíòàêòà
|
||||
DELETE {{baseUrl}}/api/well/{{idWell}}/WellContact/{{id}}
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
Loading…
Reference in New Issue
Block a user