Merge branch 'dev' into gtr

This commit is contained in:
ngfrolov 2023-03-31 11:13:35 +05:00
commit 7d83a0a93d
Signed by untrusted user who does not match committer: ng.frolov
GPG Key ID: E99907A0357B29A7
49 changed files with 8102 additions and 759 deletions

View File

@ -3,8 +3,8 @@
/// <summary>
/// блок КНБК
/// </summary>
public class BhaDto
{
public class BhaDto : ItemInfoDto
{
/// <summary>
/// КНБК описание
/// </summary>

View File

@ -1,10 +1,17 @@
namespace AsbCloudApp.Data.DailyReport
using System;
namespace AsbCloudApp.Data.DailyReport
{
/// <summary>
/// Блоки для формирования суточного рапорта
/// </summary>
public class DailyReportDto
{
/// <summary>
/// дата отчёта
/// </summary>
public DateOnly StartDate { get; set; }
/// <summary>
/// блок заголовка
/// </summary>

View File

@ -4,8 +4,8 @@ namespace AsbCloudApp.Data.DailyReport
/// <summary>
/// блок заголовка
/// </summary>
public class HeadDto
{
public class HeadDto : ItemInfoDto
{
/// <summary>
/// название скважины
/// </summary>
@ -29,7 +29,7 @@ namespace AsbCloudApp.Data.DailyReport
/// <summary>
/// дата рапорта
/// </summary>
public DateTime ReportDate { get; set; }
public DateOnly ReportDate { get; set; }
/// <summary>
/// глубина забоя на дату начала интервала

View File

@ -0,0 +1,26 @@
using System;
namespace AsbCloudApp.Data.DailyReport
{
/// <summary>
/// хранение дополнительной информации о записи
/// запись формируется на сервере автоматически
/// </summary>
public class ItemInfoDto
{
/// <summary>
/// пользователь, внесший изменения (запись формируется на сервере автоматически)
/// </summary>
public int? IdUser { get; set; }
/// <summary>
/// имя пользователя, внесшего изменения (запись формируется на сервере автоматически)
/// </summary>
public string? UserName { get; set; }
/// <summary>
/// дата последнего обновления (запись формируется на сервере автоматически)
/// </summary>
public DateTimeOffset? LastUpdateDate { get; set; }
}
}

View File

@ -3,7 +3,7 @@
/// <summary>
/// блок безметражные работы
/// </summary>
public class NoDrillingDto
public class NoDrillingDto : ItemInfoDto
{
/// <summary>
/// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию

View File

@ -5,7 +5,7 @@ namespace AsbCloudApp.Data.DailyReport
/// <summary>
/// блок САУБ
/// </summary>
public class SaubDto
public class SaubDto : ItemInfoDto
{
/// <summary>
/// Режимы бурения в роторе

View File

@ -3,8 +3,8 @@
/// <summary>
/// блок подписи
/// </summary>
public class SignDto
{
public class SignDto : ItemInfoDto
{
/// <summary>
/// ФИО Мастера буровой
/// </summary>

View File

@ -1,119 +1,18 @@
namespace AsbCloudApp.Data.DailyReport
using System.Collections.Generic;
namespace AsbCloudApp.Data.DailyReport
{
/// <summary>
/// блок баланса времени
/// </summary>
public class TimeBalanceDto
{
/// <summary>
/// Бурение
/// </summary>
public string Drilling { get; set; } = string.Empty;
/// <summary>
/// Промывка
/// </summary>
public string Flushing { get; set; } = string.Empty;
/// <summary>
/// Блок баланса времени
/// </summary>
public class TimeBalanceDto : ItemInfoDto
{
/// <summary>
/// Наращивание
/// Статистика по операциям
/// </summary>
public string Building { get; set; } = string.Empty;
public Dictionary<int, double> OperationsStat { get; set; } = new Dictionary<int, double>();
/// <summary>
/// Проработка
/// </summary>
public string Elaboration { get; set; } = string.Empty;
/// <summary>
/// Расширка
/// </summary>
public string Extension { get; set; } = string.Empty;
/// <summary>
/// Ремонт
/// </summary>
public string Repair { get; set; } = string.Empty;
/// <summary>
/// КНБК
/// </summary>
public string Knbk { get; set; } = string.Empty;
/// <summary>
/// СПО
/// </summary>
public string Spo { get; set; } = string.Empty;
/// <summary>
/// ПЗР
/// </summary>
public string Pzr { get; set; } = string.Empty;
/// <summary>
/// ПВО
/// </summary>
public string Pvo { get; set; } = string.Empty;
/// <summary>
/// ПГР
/// </summary>
public string Pgr { get; set; } = string.Empty;
/// <summary>
/// ГИС
/// </summary>
public string Gis { get; set; } = string.Empty;
/// <summary>
/// ОЗЦ
/// </summary>
public string Ozc { get; set; } = string.Empty;
/// <summary>
/// Тех. работы
/// </summary>
public string EngineeringWorks { get; set; } = string.Empty;
/// <summary>
/// Снятие замера
/// </summary>
public string TakingMeasure { get; set; } = string.Empty;
/// <summary>
/// Цементирование
/// </summary>
public string Cementing { get; set; } = string.Empty;
/// <summary>
/// Простой
/// </summary>
public string Simple { get; set; } = string.Empty;
/// <summary>
/// НПВ
/// </summary>
public string Npv { get; set; } = string.Empty;
/// <summary>
/// Проработка перед наращиванием
/// </summary>
public string ElaborationBeforeBuilding { get; set; } = string.Empty;
/// <summary>
/// Шаблонировка перед наращиванием
/// </summary>
public string TemplatingBeforeBuilding { get; set; } = string.Empty;
/// <summary>
/// Промывка перед наращиванием
/// </summary>
public string FlushingBeforeBuilding { get; set; } = string.Empty;
/// <summary>
/// Статический замер телесистемы
/// </summary>
public string StaticSurveying { get; set; } = string.Empty;
}
}

View File

@ -22,10 +22,6 @@ namespace AsbCloudApp.Data
[Range(1, int.MaxValue, ErrorMessage = "Id категории не может быть ниже 1")]
public int CategoryId { get; set; }
//TODO: в модели дто сообщения отсутствует поле Id скважины
// скорее всего опечатка т.к. используется глубина в правиле валидатора
//в других валидаторах парамтр глубины идет рэнжированный от...до
/// <summary>
/// глубина забоя, при котором событие возникло
/// </summary>

View File

@ -45,6 +45,11 @@ namespace AsbCloudApp.Data
/// </summary>
public string? CategoryName { get; set; }
/// <summary>
/// ключ родителя у категории
/// </summary>
public int? IdParentCategory { get; set; }
/// <summary>
/// дополнительная информация по операции
/// </summary>

View File

@ -16,7 +16,7 @@ namespace AsbCloudApp.Requests
/// <summary>
/// фильтр по дате окончания операции
/// </summary>
public DateTime? LeDate { get; set; }
public DateTime? LtDate { get; set; }
/// <summary>
/// фильтр по максимальной глубине скважины
@ -71,7 +71,7 @@ namespace AsbCloudApp.Requests
this.GeDepth = request.GeDepth;
this.LeDepth = request.LeDepth;
this.GeDate = request.GeDate;
this.LeDate = request.LeDate;
this.LtDate = request.LtDate;
this.OperationCategoryIds = request.OperationCategoryIds;
this.OperationType = request.OperationType;

View File

@ -16,40 +16,22 @@ namespace AsbCloudApp.Services
/// получить список сформированных рапортов по скважине за период времени
/// </summary>
/// <param name="idWell"></param>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateTime? v1, DateTime? v2, CancellationToken cancellationToken);
/// <summary>
/// получить из БД или генерировать данные для суточного рапорта за указанную дату
/// </summary>
/// <param name="idWell"></param>
/// <param name="date"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<DailyReportDto> GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token);
Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken cancellationToken);
/// <summary>
/// Добавить новый рапорт
/// </summary>
/// <param name="idWell"></param>
/// <param name="dto"></param>
/// <param name="startDate"></param>
/// <param name="idUser"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default);
Task<int> AddAsync(int idWell, DateOnly startDate, int idUser, CancellationToken token);
/// <summary>
/// изменить данные для суточного рапорта
/// </summary>
/// <param name="idWell"></param>
/// <param name="date"></param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token = default);
/// <summary>
/// Сформировать файл рапорта
/// </summary>
@ -57,6 +39,16 @@ namespace AsbCloudApp.Services
/// <param name="date"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<Stream?> MakeReportAsync(int idWell, DateTime date, CancellationToken token = default);
Task<Stream?> MakeReportAsync(int idWell, DateOnly date, CancellationToken token);
/// <summary>
/// изменить блок данных для суточного рапорта
/// </summary>
/// <param name="idWell"></param>
/// <param name="startDate"></param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> UpdateBlockAsync(int idWell, DateOnly startDate, ItemInfoDto dto, CancellationToken token);
}
}

View File

@ -10,7 +10,6 @@ namespace AsbCloudApp.Services
/// </summary>
public interface IScheduleRepository : IRepositoryWellRelated<ScheduleDto>
{
// TODO: this should be nullable.
/// <summary>
/// получить бурильщика по idWell и времени
/// </summary>
@ -18,6 +17,6 @@ namespace AsbCloudApp.Services
/// <param name="workTime"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<DrillerDto?> GetDrillerAsync(int idWell, DateTime workTime, CancellationToken token);
Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token);
}
}

View File

@ -22,7 +22,7 @@ namespace AsbCloudApp.Services
/// <param name="approxPointsCount">кол-во элементов до которых эти данные прореживаются</param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<TDto>?> GetOrDefaultAsync(int idWell,
Task<IEnumerable<TDto>> GetAsync(int idWell,
DateTime dateBegin = default, double intervalSec = 600d,
int approxPointsCount = 1024, CancellationToken token = default);

View File

@ -0,0 +1,80 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.ValidationAttributes
{
/// <summary>
/// Атрибут валидации даты-времени
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class DateValidationAttribute : ValidationAttribute
{
private DateTime? gtDate;
/// <summary>
/// null разрешен
/// </summary>
public bool AllowNull { get; set; } = true;
/// <summary>
/// Разрешена только дат.
/// При наличии времени в DateTime инвалидирует.
/// При наличии UTC тоже инвалидирует.
/// </summary>
public bool IsDateOnly { get; set; } = false;
/// <summary>
/// Допустима дата-время в UTC
/// </summary>
public bool AllowUtc { get; set; } = true;
/// <summary>
/// Дата больше которой должно быть проверяемое значение.
/// Формат строки - любой поддерживаемый DateTime.Parse.
/// Желательно использовать ISO 8601 формат
/// </summary>
public string? GtDate {
get => gtDate.ToString();
set
{
if(value is null)
gtDate = null;
else
gtDate = DateTime.Parse(value);
}
}
/// <summary>
/// Проверка значения
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object? value)
{
if (value is null)
return AllowNull;
if (value is not DateTime dateTime)
return false;
if (IsDateOnly)
{
if (dateTime.Hour > 0 ||
dateTime.Minute > 0 ||
dateTime.Second > 0 ||
dateTime.Millisecond > 0 ||
dateTime.Kind == DateTimeKind.Utc)
return false;
}
if (!AllowUtc && dateTime.Kind == DateTimeKind.Utc)
return false;
if (gtDate.HasValue && dateTime <= gtDate)
return false;
return true;
}
}
}

View File

@ -5,6 +5,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@ -258,4 +260,17 @@ namespace AsbCloudDb
}
}
public class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateOnly.FromDateTime(reader.GetDateTime());
}
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
{
var isoDate = value.ToString("O");
writer.WriteStringValue(isoDate);
}
}
}

View File

@ -0,0 +1,36 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class UpdateTable_t_daily_report_UpdateType_startDate_toDateOnly : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateOnly>(
name: "start_date",
table: "t_daily_report",
type: "date",
nullable: false,
comment: "Дата отчёта",
oldClrType: typeof(DateTimeOffset),
oldType: "timestamp with time zone",
oldComment: "Дата отчёта");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTimeOffset>(
name: "start_date",
table: "t_daily_report",
type: "timestamp with time zone",
nullable: false,
comment: "Дата отчёта",
oldClrType: typeof(DateOnly),
oldType: "date",
oldComment: "Дата отчёта");
}
}
}

View File

@ -148,8 +148,8 @@ namespace AsbCloudDb.Migrations
.HasColumnName("id_well")
.HasComment("ID скважины");
b.Property<DateTimeOffset>("StartDate")
.HasColumnType("timestamp with time zone")
b.Property<DateOnly>("StartDate")
.HasColumnType("date")
.HasColumnName("start_date")
.HasComment("Дата отчёта");

View File

@ -1,6 +1,6 @@
namespace AsbCloudDb.Model.DailyReport
{
public class Bha
public class Bha : ItemInfo
{
/// <summary>
/// КНБК описание

View File

@ -10,8 +10,8 @@ namespace AsbCloudDb.Model.DailyReport
[Column("id_well"), Comment("ID скважины")]
public int IdWell { get; set; }
[Column("start_date", TypeName = "timestamp with time zone"), Comment("Дата отчёта")]
public DateTimeOffset StartDate { get; set; }
[Column("start_date", TypeName = "date"), Comment("Дата отчёта")]
public DateOnly StartDate { get; set; }
[Column("info", TypeName = "jsonb"), Comment("Список параметров для отчёта")]
public DailyReportInfo Info { get; set; } = null!;

View File

@ -7,7 +7,6 @@ namespace AsbCloudDb.Model
public Head Head { get; set; } = null!;
public Bha Bha { get; set; } = new();
public NoDrilling NoDrilling { get; set; } = new();
public TimeBalance TimeBalance { get; set; } = new();
public Saub Saub { get; set; } = new();
public Sign Sign { get; set; } = new();
}

View File

@ -1,7 +1,9 @@
using System;
using System.Text.Json.Serialization;
namespace AsbCloudDb.Model.DailyReport
{
public class Head
public class Head : ItemInfo
{
/// <summary>
/// название скважины
@ -26,7 +28,8 @@ namespace AsbCloudDb.Model.DailyReport
/// <summary>
/// дата рапорта
/// </summary>
public DateTime ReportDate { get; set; }
[JsonConverter(typeof(DateOnlyJsonConverter))]
public DateOnly ReportDate { get; set; }
/// <summary>
/// глубина забоя на дату начала интервала

View File

@ -0,0 +1,17 @@
using System;
namespace AsbCloudDb.Model
{
public class ItemInfo
{
/// <summary>
/// пользователь, внесший изменения
/// </summary>
public int? IdUser { get; set; }
/// <summary>
/// дата последнего обновления блока
/// </summary>
public DateTimeOffset LastUpdateDate { get; set; } = DateTimeOffset.Now;
}
}

View File

@ -1,6 +1,6 @@
namespace AsbCloudDb.Model.DailyReport
{
public class NoDrilling
public class NoDrilling : ItemInfo
{
/// <summary>
/// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию

View File

@ -1,8 +1,6 @@
using System.Collections.Generic;
namespace AsbCloudDb.Model.DailyReport
namespace AsbCloudDb.Model.DailyReport
{
public class Saub
public class Saub : ItemInfo
{
/// <summary>
/// Режимы бурения в роторе
@ -98,7 +96,6 @@ namespace AsbCloudDb.Model.DailyReport
/// МСП
/// </summary>
public string MspSection { get; set; } = string.Empty;
}
}

View File

@ -1,6 +1,6 @@
namespace AsbCloudDb.Model.DailyReport
{
public class Sign
public class Sign : ItemInfo
{
/// <summary>
/// ФИО Мастера буровой

View File

@ -1,96 +0,0 @@
namespace AsbCloudDb.Model.DailyReport
{
public class TimeBalance
{
/// <summary>
/// Бурение
/// </summary>
public string Drilling { get; set; } = string.Empty;
/// <summary>
/// Промывка
/// </summary>
public string Flushing { get; set; } = string.Empty;
/// <summary>
/// Наращивание
/// </summary>
public string Building { get; set; } = string.Empty;
/// <summary>
/// Проработка
/// </summary>
public string Elaboration { get; set; } = string.Empty;
/// <summary>
/// Расширка
/// </summary>
public string Extension { get; set; } = string.Empty;
/// <summary>
/// Ремонт
/// </summary>
public string Repair { get; set; } = string.Empty;
/// <summary>
/// КНБК
/// </summary>
public string Knbk { get; set; } = string.Empty;
/// <summary>
/// СПО
/// </summary>
public string Spo { get; set; } = string.Empty;
/// <summary>
/// ПЗР
/// </summary>
public string Pzr { get; set; } = string.Empty;
/// <summary>
/// ПВО
/// </summary>
public string Pvo { get; set; } = string.Empty;
/// <summary>
/// ПГР
/// </summary>
public string Pgr { get; set; } = string.Empty;
/// <summary>
/// ГИС
/// </summary>
public string Gis { get; set; } = string.Empty;
/// <summary>
/// ОЗЦ
/// </summary>
public string Ozc { get; set; } = string.Empty;
/// <summary>
/// Тех. работы
/// </summary>
public string EngineeringWorks { get; set; } = string.Empty;
/// <summary>
/// Снятие замера
/// </summary>
public string TakingMeasure { get; set; } = string.Empty;
/// <summary>
/// Цементирование
/// </summary>
public string Cementing { get; set; } = string.Empty;
/// <summary>
/// Простой
/// </summary>
public string Simple { get; set; } = string.Empty;
/// <summary>
/// НПВ
/// </summary>
public string Npv { get; set; } = string.Empty;
}
}

View File

@ -1,138 +1,16 @@
namespace AsbCloudDb.Model.DefaultData
using System;
using System.Linq;
namespace AsbCloudDb.Model.DefaultData
{
internal class EntityFillerWellOperationCategory : EntityFiller<WellOperationCategory>
{
public override WellOperationCategory[] GetData() => new WellOperationCategory[]{
// Этап работ
new () {Id = WellOperationCategory.IdDrilling, Name = "БУРЕНИЕ", KeyValueName = "dT", KeyValueUnits = "м/ч" },
new () {Id = 3001, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 3002, Name = "КРЕПЛЕНИЕ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 3003, Name = "ГФР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 3004, Name = "Вспомогательные операции", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdNonProductiveTime, Name = "Непроизводительное время (НПВ)", KeyValueName = "dT", KeyValueUnits = "мин" },
// Виды работ
new () {Id = 4000, IdParent = 3000, Name = "КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdMechanicalDrilling, IdParent = 3000, Name = "Механическое. бурение", KeyValueName = "dT", KeyValueUnits = "м/ч" },
new () {Id = 4002, IdParent = 3000, Name = "Статический замер", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4003, IdParent = 3000, Name = "Нормализация диаметра скважины", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4004, IdParent = 3000, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4005, IdParent = 3001, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4006, IdParent = 3002, Name = "Спуск обсадной колонны", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4007, IdParent = 3002, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4008, IdParent = 3002, Name = "Вспомогательные работы при креплении", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4009, IdParent = 3003, Name = "Сборка/разборка приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4010, IdParent = 3003, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4011, IdParent = 3003, Name = "ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4012, IdParent = 3004, Name = "Промывка, ОБР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4013, IdParent = 3004, Name = "Вспомогательные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4014, IdParent = 3005, Name = "Ремонт оборудования", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4015, IdParent = 3005, Name = "Аварийные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4016, IdParent = 3005, Name = "Осложнение", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 4017, IdParent = 3005, Name = "Незаложенные в ГГД операции", KeyValueName = "dT", KeyValueUnits = "мин" },
//переименованные категории с новым ИД
new () {Id = WellOperationCategory.IdBhaDisassembly, IdParent = 4000, Name = "Разборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdBhaAssembly, IdParent = 4000, Name = "Сборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdSlide, IdParent = 4001, Name = "Бурение слайдом", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = WellOperationCategory.IdRotor, IdParent = 4001, Name = "Бурение ротором", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = WellOperationCategory.IdStaticSurveying, IdParent = 4002, Name = "Замер ЗТС (запись MWD)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5006, IdParent = 4003, Name = "Проработка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdDevelopment, IdParent = 4003, Name = "Проработка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdTemplatingWhileDrilling, IdParent = 4003, Name = "Шаблонировка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5010, IdParent = 4004, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdSlipsTime, IdParent = 4004, Name = "Удержание в клиньях", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5012, IdParent = 4005, Name = "Подъем инструмента", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdBhaUp, IdParent = 4005, Name = "Подъем КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5014, IdParent = 4005, Name = "Спуск инструмента", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdBhaDown, IdParent = 4005, Name = "Спуск КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5016, IdParent = 4006, Name = "Промывка при спуске ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdCasingDown, IdParent = 4006, Name = "Спуск ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5018, IdParent = 4007, Name = "ОЗЦ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5019, IdParent = 4007, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5020, IdParent = 4008, Name = "Опрессовка БИ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5021, IdParent = 4008, Name = "Опрессовка ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5022, IdParent = 4008, Name = "ПЗР при спуске ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5023, IdParent = 4008, Name = "ПЗР при цементировании", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5024, IdParent = 4009, Name = "Разборка комплекса приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5025, IdParent = 4009, Name = "Сборка комплекса приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5026, IdParent = 4010, Name = "Подъем приборов ГИС (на трубах)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5027, IdParent = 4010, Name = "Спуск приборов ГИС (на трубах)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5028, IdParent = 4011, Name = "Комплекс ГИС на жестком кабеле", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5029, IdParent = 4011, Name = "Комплекс ГИС на кабеле", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5030, IdParent = 4011, Name = "Комплекс ГИС на трубах", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5031, IdParent = 4012, Name = "Закачка/прокачка пачки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5032, IdParent = 4012, Name = "Обработка БР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5033, IdParent = 4012, Name = "Ориентирование ТС при бурении", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5034, IdParent = 4012, Name = "Перезапись гаммы-каротажа", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5035, IdParent = 4012, Name = "Приготовление БР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdFlashing, IdParent = 4012, Name = "Промывка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5037, IdParent = 4012, Name = "Разбуривание тех.оснастки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5038, IdParent = 4012, Name = "Спуск инструмента с проработкой", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5039, IdParent = 4013, Name = "ВМР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5040, IdParent = 4013, Name = "Демонтаж ПВО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5041, IdParent = 4013, Name = "Долив затруба при подъёме", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5042, IdParent = 4013, Name = "Монтаж ПВО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5043, IdParent = 4013, Name = "Наработка жёлоба", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5044, IdParent = 4013, Name = "Обвязка устья с циркуляционной системой", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5045, IdParent = 4013, Name = "Оборудование устья", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5046, IdParent = 4013, Name = "Опрессовка ПВО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5047, IdParent = 4013, Name = "Перемонтаж ПВО ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5048, IdParent = 4013, Name = "Перетяжка талевого каната", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5049, IdParent = 4013, Name = "ПЗР при сборке КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5050, IdParent = 4013, Name = "Полная замена талевого каната", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5051, IdParent = 4013, Name = "ПР перед забуркой направления", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5052, IdParent = 4013, Name = "Продувка манифольда", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5053, IdParent = 4013, Name = "Срезка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5054, IdParent = 4013, Name = "Тайм-дриллинг", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5055, IdParent = 4013, Name = "Тех.отстой", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5056, IdParent = 4013, Name = "Учебная тревога \"Выброс\"", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5057, IdParent = 4013, Name = "Чистка ЦСГО/емкостного блока", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = WellOperationCategory.IdEquipmentRepair, IdParent = 4014, Name = "Ремонт бурового оборудования", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5059, IdParent = 4015, Name = "Ловильные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5060, IdParent = 4015, Name = "Ожидание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5061, IdParent = 4015, Name = "Определение места прихвата и ЛМ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5062, IdParent = 4015, Name = "Работа яссом", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5063, IdParent = 4015, Name = "Расхаживание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5064, IdParent = 4015, Name = "СПО - колокол", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5065, IdParent = 4015, Name = "СПО - метчик", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5066, IdParent = 4015, Name = "СПО - овершот", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5067, IdParent = 4015, Name = "СПО - труболовка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5068, IdParent = 4015, Name = "Торпедирование (встряхивание)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5069, IdParent = 4015, Name = "Торпедирование (отстрел)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5070, IdParent = 4015, Name = "Установка ванн", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5071, IdParent = 4015, Name = "Фрезеровка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5072, IdParent = 4016, Name = "Контролируемое ГНВП", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5073, IdParent = 4016, Name = "Поглощение", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5074, IdParent = 4016, Name = "Сальникообразование", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5075, IdParent = 4016, Name = "Утяжеление БР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5076, IdParent = 4017, Name = "НПВ / прочее", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5077, IdParent = 4017, Name = "Обработка раствора (несоответствие параметров)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5078, IdParent = 4017, Name = "подъем ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5079, IdParent = 4017, Name = "Ревизия КНБК/инструмента/ЗТС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5082, IdParent = 4000, Name = "Сборка устройства ориентирования КО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5083, IdParent = 4003, Name = "Проработка принудительная", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5084, IdParent = 4005, Name = "Шаблонировка подъем БИ, продувка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5085, IdParent = 4005, Name = "Спуск бурильного инструмента со сборкой с мостков", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5086, IdParent = 4005, Name = "Подъем БИ с выбросом на мостки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5087, IdParent = 4005, Name = "Спуск БИ со сборкой с мостков", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5088, IdParent = 4005, Name = "Сборка и спуск ТБТ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5089, IdParent = 4005, Name = "Спуск КО на транспотрной колонне", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5090, IdParent = 4008, Name = "Отворот допускной трубы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5091, IdParent = 4008, Name = "Активация подвески, опрессовка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5092, IdParent = 4008, Name = "Монтаж, опрессовка ФА", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5093, IdParent = 4008, Name = "Сборка хвостовика 114мм (согласно схеме)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5094, IdParent = 4008, Name = "ПЗР к спуску УЭЦН", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5095, IdParent = 4008, Name = "Активация подвески (потайной колонны, хвостовика)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5096, IdParent = 4008, Name = "Шаблонирование перед спуском", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5097, IdParent = 4012, Name = "Промывка - перевод скважины на новый раствор", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5098, IdParent = 4013, Name = "Сборка БИ с мостков на подсвечник", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5099, IdParent = 4013, Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО.", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5100, IdParent = 4013, Name = "Смена рабочего переводника ВСП", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5101, IdParent = 4014, Name = "Ремонт", KeyValueName = "dT", KeyValueUnits = "мин" },
};
public override WellOperationCategory[] GetData()
=> WellOperationCategory.WorkStages
.Concat(WellOperationCategory.WorkTypes)
.Concat(WellOperationCategory.WorkCategories)
.ToArray();
}
}

View File

@ -13,17 +13,122 @@ namespace AsbCloudDb.Model
/// БУРЕНИЕ
/// </summary>
public const int IdDrilling = 3000;
/// <summary>
/// СПО
/// </summary>
public const int IdSPOStage = 3001;
/// <summary>
/// КРЕПЛЕНИЕ
/// </summary>
public const int IdFastening = 3002;
/// <summary>
/// ГФР
/// </summary>
public const int IdGFR = 3003;
/// <summary>
/// Вспомогательные операции
/// </summary>
public const int IdAuxiliaryOperations = 3004;
/// <summary>
/// Непроизводительное время (НПВ)
/// </summary>
public const int IdNonProductiveTime = 3005;
/// <summary>
/// КНБК
/// </summary>
public const int IdKnbk = 4000;
/// <summary>
/// Механическое. бурение
/// </summary>
public const int IdMechanicalDrilling = 4001;
/// <summary>
/// Статический замер
/// </summary>
public const int IdMeasurementStat = 4002;
/// <summary>
/// Нормализация диаметра скважины
/// </summary>
public const int IdNormalizedWellDiameter = 4003;
/// <summary>
/// Наращивание
/// </summary>
public const int IdBuilding = 4004;
/// <summary>
/// СПО
/// </summary>
public const int IdSPO = 4005;
/// <summary>
/// Спуск обсадной колонны
/// </summary>
public const int IdCasingRunning = 4006;
/// <summary>
/// Цементирование
/// </summary>
public const int IdCementing = 4007;
/// <summary>
/// Вспомогательные работы при креплении
/// </summary>
public const int IdAuxiliaryWorkFastening = 4008;
/// <summary>
/// Сборка/разборка приборов ГИС
/// </summary>
public const int IdAssemblyOrDisassemblyGIS = 4009;
/// <summary>
/// СПО2
/// </summary>
public const int IdSPO2 = 4010;
/// <summary>
/// ГИС
/// </summary>
public const int IdGIS = 4011;
/// <summary>
/// Промывка, ОБР
/// </summary>
public const int IdFlushingOBR = 4012;
/// <summary>
/// Вспомогательные работы
/// </summary>
public const int IdAuxiliaryWork = 4013;
/// <summary>
/// Ремонт оборудования
/// </summary>
public const int IdEquipmentRepair = 4014;
/// <summary>
/// Аварийные работы
/// </summary>
public const int IdEmergencyWork = 4015;
/// <summary>
/// Осложнение
/// </summary>
public const int IdComplication = 4016;
/// <summary>
/// Незаложенные в ГГД операции
/// </summary>
public const int IdOperationsNotIncludedGGD = 4017;
/// <summary>
/// Разборка КНБК
/// </summary>
@ -83,12 +188,13 @@ namespace AsbCloudDb.Model
/// <summary>
/// Ремонт бурового оборудования
/// </summary>
public const int IdEquipmentRepair = 5058;
public const int IdEquipmentDrillingRepair = 5058;
/// <summary>
/// Список всех категорий НПВ
/// </summary>
public static readonly int[] NonProductiveTimeSubIds = {
IdEquipmentRepair,
IdEquipmentDrillingRepair,
5059,
5060,
5061,
@ -123,6 +229,150 @@ namespace AsbCloudDb.Model
public static readonly int[] MechanicalDrillingSubIds = { IdRotor, IdSlide, IdMechanicalDrilling, };
#endregion
#region Списки категорий операций по группам
/// <summary>
/// Этапы работ
/// </summary>
public static WellOperationCategory[] WorkStages { get; } = new WellOperationCategory[]{
new() { Id = IdDrilling, Name = "БУРЕНИЕ", KeyValueName = "dT", KeyValueUnits = "м/ч" },
new() { Id = IdSPOStage, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdFastening, Name = "КРЕПЛЕНИЕ", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdGFR, Name = "ГФР", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdAuxiliaryOperations, Name = "Вспомогательные операции", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdNonProductiveTime, Name = "Непроизводительное время (НПВ)", KeyValueName = "dT", KeyValueUnits = "мин" },
};
/// <summary>
/// Виды работ
/// </summary>
public static WellOperationCategory[] WorkTypes { get; } = new WellOperationCategory[]{
new () {Id = IdKnbk, IdParent = 3000, Name = "КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdMechanicalDrilling, IdParent = 3000, Name = "Механическое. бурение", KeyValueName = "dT", KeyValueUnits = "м/ч" },
new () {Id = IdMeasurementStat, IdParent = 3000, Name = "Статический замер", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdNormalizedWellDiameter, IdParent = 3000, Name = "Нормализация диаметра скважины", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdBuilding, IdParent = 3000, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdSPO , IdParent = 3001, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdCasingRunning, IdParent = 3002, Name = "Спуск обсадной колонны", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdCementing, IdParent = 3002, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdAuxiliaryWorkFastening, IdParent = 3002, Name = "Вспомогательные работы при креплении", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdAssemblyOrDisassemblyGIS, IdParent = 3003, Name = "Сборка/разборка приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdSPO2, IdParent = 3003, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdGIS, IdParent = 3003, Name = "ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFlushingOBR, IdParent = 3004, Name = "Промывка, ОБР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdAuxiliaryWork, IdParent = 3004, Name = "Вспомогательные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdEquipmentRepair, IdParent = 3005, Name = "Ремонт оборудования", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdEmergencyWork, IdParent = 3005, Name = "Аварийные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdComplication, IdParent = 3005, Name = "Осложнение", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdOperationsNotIncludedGGD, IdParent = 3005, Name = "Незаложенные в ГГД операции", KeyValueName = "dT", KeyValueUnits = "мин" },
};
/// <summary>
/// Категории работ
/// </summary>
public static WellOperationCategory[] WorkCategories { get; } = new WellOperationCategory[]{
new () {Id = IdBhaDisassembly, IdParent = 4000, Name = "Разборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdBhaAssembly, IdParent = 4000, Name = "Сборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdSlide, IdParent = 4001, Name = "Бурение слайдом", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdRotor, IdParent = 4001, Name = "Бурение ротором", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdStaticSurveying, IdParent = 4002, Name = "Замер ЗТС (запись MWD)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5006, IdParent = 4003, Name = "Проработка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdDevelopment, IdParent = 4003, Name = "Проработка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdTemplatingWhileDrilling, IdParent = 4003, Name = "Шаблонировка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5010, IdParent = 4004, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdSlipsTime, IdParent = 4004, Name = "Удержание в клиньях", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5012, IdParent = 4005, Name = "Подъем инструмента", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdBhaUp, IdParent = 4005, Name = "Подъем КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5014, IdParent = 4005, Name = "Спуск инструмента", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdBhaDown, IdParent = 4005, Name = "Спуск КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5016, IdParent = 4006, Name = "Промывка при спуске ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdCasingDown, IdParent = 4006, Name = "Спуск ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5018, IdParent = 4007, Name = "ОЗЦ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5019, IdParent = 4007, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5020, IdParent = 4008, Name = "Опрессовка БИ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5021, IdParent = 4008, Name = "Опрессовка ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5022, IdParent = 4008, Name = "ПЗР при спуске ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5023, IdParent = 4008, Name = "ПЗР при цементировании", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5024, IdParent = 4009, Name = "Разборка комплекса приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5025, IdParent = 4009, Name = "Сборка комплекса приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5026, IdParent = 4010, Name = "Подъем приборов ГИС (на трубах)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5027, IdParent = 4010, Name = "Спуск приборов ГИС (на трубах)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5028, IdParent = 4011, Name = "Комплекс ГИС на жестком кабеле", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5029, IdParent = 4011, Name = "Комплекс ГИС на кабеле", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5030, IdParent = 4011, Name = "Комплекс ГИС на трубах", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5031, IdParent = 4012, Name = "Закачка/прокачка пачки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5032, IdParent = 4012, Name = "Обработка БР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5033, IdParent = 4012, Name = "Ориентирование ТС при бурении", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5034, IdParent = 4012, Name = "Перезапись гаммы-каротажа", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5035, IdParent = 4012, Name = "Приготовление БР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFlashing, IdParent = 4012, Name = "Промывка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5037, IdParent = 4012, Name = "Разбуривание тех.оснастки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5038, IdParent = 4012, Name = "Спуск инструмента с проработкой", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5039, IdParent = 4013, Name = "ВМР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5040, IdParent = 4013, Name = "Демонтаж ПВО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5041, IdParent = 4013, Name = "Долив затруба при подъёме", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5042, IdParent = 4013, Name = "Монтаж ПВО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5043, IdParent = 4013, Name = "Наработка жёлоба", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5044, IdParent = 4013, Name = "Обвязка устья с циркуляционной системой", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5045, IdParent = 4013, Name = "Оборудование устья", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5046, IdParent = 4013, Name = "Опрессовка ПВО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5047, IdParent = 4013, Name = "Перемонтаж ПВО ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5048, IdParent = 4013, Name = "Перетяжка талевого каната", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5049, IdParent = 4013, Name = "ПЗР при сборке КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5050, IdParent = 4013, Name = "Полная замена талевого каната", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5051, IdParent = 4013, Name = "ПР перед забуркой направления", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5052, IdParent = 4013, Name = "Продувка манифольда", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5053, IdParent = 4013, Name = "Срезка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5054, IdParent = 4013, Name = "Тайм-дриллинг", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5055, IdParent = 4013, Name = "Тех.отстой", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5056, IdParent = 4013, Name = "Учебная тревога \"Выброс\"", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5057, IdParent = 4013, Name = "Чистка ЦСГО/емкостного блока", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdEquipmentDrillingRepair, IdParent = 4014, Name = "Ремонт бурового оборудования", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5059, IdParent = 4015, Name = "Ловильные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5060, IdParent = 4015, Name = "Ожидание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5061, IdParent = 4015, Name = "Определение места прихвата и ЛМ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5062, IdParent = 4015, Name = "Работа яссом", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5063, IdParent = 4015, Name = "Расхаживание", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5064, IdParent = 4015, Name = "СПО - колокол", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5065, IdParent = 4015, Name = "СПО - метчик", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5066, IdParent = 4015, Name = "СПО - овершот", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5067, IdParent = 4015, Name = "СПО - труболовка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5068, IdParent = 4015, Name = "Торпедирование (встряхивание)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5069, IdParent = 4015, Name = "Торпедирование (отстрел)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5070, IdParent = 4015, Name = "Установка ванн", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5071, IdParent = 4015, Name = "Фрезеровка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5072, IdParent = 4016, Name = "Контролируемое ГНВП", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5073, IdParent = 4016, Name = "Поглощение", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5074, IdParent = 4016, Name = "Сальникообразование", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5075, IdParent = 4016, Name = "Утяжеление БР", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5076, IdParent = 4017, Name = "НПВ / прочее", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5077, IdParent = 4017, Name = "Обработка раствора (несоответствие параметров)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5078, IdParent = 4017, Name = "подъем ОК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5079, IdParent = 4017, Name = "Ревизия КНБК/инструмента/ЗТС", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5082, IdParent = 4000, Name = "Сборка устройства ориентирования КО", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5083, IdParent = 4003, Name = "Проработка принудительная", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5084, IdParent = 4005, Name = "Шаблонировка подъем БИ, продувка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5085, IdParent = 4005, Name = "Спуск бурильного инструмента со сборкой с мостков", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5086, IdParent = 4005, Name = "Подъем БИ с выбросом на мостки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5087, IdParent = 4005, Name = "Спуск БИ со сборкой с мостков", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5088, IdParent = 4005, Name = "Сборка и спуск ТБТ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5089, IdParent = 4005, Name = "Спуск КО на транспотрной колонне", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5090, IdParent = 4008, Name = "Отворот допускной трубы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5091, IdParent = 4008, Name = "Активация подвески, опрессовка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5092, IdParent = 4008, Name = "Монтаж, опрессовка ФА", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5093, IdParent = 4008, Name = "Сборка хвостовика 114мм (согласно схеме)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5094, IdParent = 4008, Name = "ПЗР к спуску УЭЦН", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5095, IdParent = 4008, Name = "Активация подвески (потайной колонны, хвостовика)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5096, IdParent = 4008, Name = "Шаблонирование перед спуском", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5097, IdParent = 4012, Name = "Промывка - перевод скважины на новый раствор", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5098, IdParent = 4013, Name = "Сборка БИ с мостков на подсвечник", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5099, IdParent = 4013, Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО.", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5100, IdParent = 4013, Name = "Смена рабочего переводника ВСП", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5101, IdParent = 4014, Name = "Ремонт", KeyValueName = "dT", KeyValueUnits = "мин" },
};
#endregion
[Key]
[Column("id")]
public int Id { get; set; }

View File

@ -21,7 +21,7 @@ namespace AsbCloudInfrastructure.Repository
this.wellService = wellService;
}
public async Task<DrillerDto?> GetDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
public async Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
{
var hoursOffset = wellService.GetTimezone(idWell).Hours;
var date = workTime.ToUtcDateTimeOffset(hoursOffset);

View File

@ -331,10 +331,10 @@ namespace AsbCloudInfrastructure.Repository
query = query.Where(e => e.DateStart >= geDateOffset);
}
if (request.LeDate.HasValue)
if (request.LtDate.HasValue)
{
var leDateOffset = request.LeDate.Value.ToUtcDateTimeOffset(timezone.Hours);
query = query.Where(e => e.DateStart <= leDateOffset);
var ltDateOffset = request.LtDate.Value.ToUtcDateTimeOffset(timezone.Hours);
query = query.Where(e => e.DateStart < ltDateOffset);
}
var currentWellOperations = db.WellOperations
@ -352,6 +352,7 @@ namespace AsbCloudInfrastructure.Repository
IdWell = o.IdWell,
IdWellSectionType = o.IdWellSectionType,
IdCategory = o.IdCategory,
IdParentCategory = o.OperationCategory.IdParent,
CategoryName = o.OperationCategory.Name,
WellSectionTypeName = o.WellSectionType.Caption,

View File

@ -1,175 +1,93 @@
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport;
using ClosedXML.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
#nullable enable
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{
/// <summary>
/// Построение баланса времени
/// </summary>
class TimeBalanceBlock : BlockAbstract
{
private readonly TimeBalanceDto blockDto;
public CellAddress AddressTitle { get; }
public CellAddress AddressDrilling { get; set; }
public CellAddress AddressFlushing { get; set; }
public CellAddress AddressBuilding { get; set; }
public CellAddress AddressElaboration { get; set; }
public CellAddress AddressExtension { get; set; }
public CellAddress AddressRepair { get; set; }
public CellAddress AddressDrillingValue { get; set; }
public CellAddress AddressFlushingValue { get; set; }
public CellAddress AddressBuildingValue { get; set; }
public CellAddress AddressElaborationValue { get; set; }
public CellAddress AddressExtensionValue { get; set; }
public CellAddress AddressRepairValue { get; set; }
public CellAddress AddressKnbk { get; set; }
public CellAddress AddressSpo { get; set; }
public CellAddress AddressPzr { get; set; }
public CellAddress AddressPvo { get; set; }
public CellAddress AddressPgr { get; set; }
public CellAddress AddressGis { get; set; }
public CellAddress AddressKnbkValue { get; set; }
public CellAddress AddressSpoValue { get; set; }
public CellAddress AddressPzrValue { get; set; }
public CellAddress AddressPvoValue { get; set; }
public CellAddress AddressPgrValue { get; set; }
public CellAddress AddressGisValue { get; set; }
public CellAddress AddressOzc { get; set; }
public CellAddress AddressEngineeringWorks { get; set; }
public CellAddress AddressTakingMeasure { get; set; }
public CellAddress AddressCementing { get; set; }
public CellAddress AddressSimple { get; set; }
public CellAddress AddressNpv { get; set; }
public CellAddress AddressOzcValue { get; set; }
public CellAddress AddressEngineeringWorksValue { get; set; }
public CellAddress AddressTakingMeasureValue { get; set; }
public CellAddress AddressCementingValue { get; set; }
public CellAddress AddressSimpleValue { get; set; }
public CellAddress AddressNpvValue { get; set; }
public CellAddress[] AddressPeriodTableDataArray { get; }
/// <summary>
/// Начальная ячейка
/// </summary>
public override CellAddress AddressBlockBegin { get; }
/// <summary>
/// Конечная ячейка
/// </summary>
public override CellAddress AddressBlockEnd { get; }
public TimeBalanceBlock(CellAddress addressBlockBegin, TimeBalanceDto blockDto)
/// <summary>
/// Ячейка с заголовком
/// </summary>
private CellAddress Title { get { return AddressBlockBegin + (1, 3); } }
/// <summary>
/// Статистика по операциям
/// </summary>
private Dictionary<int, double> OperationsStatistics { get; }
/// <summary>
/// Категории операций
/// </summary>
private IEnumerable<WellOperationCategoryDto> OperationCategories { get; }
/// <summary>
/// количество столбцов в таблице
/// </summary>
private const int countColumns = 3;
/// <summary>
/// количество категорий операций
/// </summary>
private int OperationCategoriesCount { get { return OperationCategories.Count(); } }
public TimeBalanceBlock(CellAddress addressBlockBegin, TimeBalanceDto blockDto, IEnumerable<WellOperationCategoryDto> operationCategories)
{
AddressBlockBegin = addressBlockBegin.Copy();
this.blockDto = blockDto;
AddressTitle = addressBlockBegin + (1, 3);
AddressDrilling = addressBlockBegin + (2, 1);
AddressFlushing = addressBlockBegin + (3, 1);
AddressBuilding = addressBlockBegin + (4, 1);
AddressElaboration = addressBlockBegin + (5, 1);
AddressExtension = addressBlockBegin + (6, 1);
AddressRepair = addressBlockBegin + (7, 1);
AddressDrillingValue = addressBlockBegin + (2, 2);
AddressFlushingValue = addressBlockBegin + (3, 2);
AddressBuildingValue = addressBlockBegin + (4, 2);
AddressElaborationValue = addressBlockBegin + (5, 2);
AddressExtensionValue = addressBlockBegin + (6, 2);
AddressRepairValue = addressBlockBegin + (7, 2);
AddressKnbk = addressBlockBegin + (2, 3);
AddressSpo = addressBlockBegin + (3, 3);
AddressPzr = addressBlockBegin + (4, 3);
AddressPvo = addressBlockBegin + (5, 3);
AddressPgr = addressBlockBegin + (6, 3);
AddressGis = addressBlockBegin + (7, 3);
AddressKnbkValue = addressBlockBegin + (2, 4);
AddressSpoValue = addressBlockBegin + (3, 4);
AddressPzrValue = addressBlockBegin + (4, 4);
AddressPvoValue = addressBlockBegin + (5, 4);
AddressPgrValue = addressBlockBegin + (6, 4);
AddressGisValue = addressBlockBegin + (7, 4);
AddressOzc = addressBlockBegin + (2, 5);
AddressEngineeringWorks = addressBlockBegin + (3, 5);
AddressTakingMeasure = addressBlockBegin + (4, 5);
AddressCementing = addressBlockBegin + (5, 5);
AddressSimple = addressBlockBegin + (6, 5);
AddressNpv = addressBlockBegin + (7, 5);
AddressOzcValue = addressBlockBegin + (2, 6);
AddressEngineeringWorksValue = addressBlockBegin + (3, 6);
AddressTakingMeasureValue = addressBlockBegin + (4, 6);
AddressCementingValue = addressBlockBegin + (5, 6);
AddressSimpleValue = addressBlockBegin + (6, 6);
AddressNpvValue = addressBlockBegin + (7, 6);
AddressBlockEnd = AddressNpvValue;
OperationsStatistics = blockDto.OperationsStat;
OperationCategories = operationCategories;
var rowsCount = (int)Math.Ceiling( 1d * OperationCategoriesCount / countColumns);
var colsCount = (1 + 1) * countColumns;
AddressBlockEnd = Title + (rowsCount, colsCount);
}
public override void Draw(IXLWorksheet sheet)
{
sheet.Range(AddressTitle.RowNumber, AddressTitle.ColumnNumber, AddressTitle.RowNumber, AddressTitle.ColumnNumber + 1)
.Merge()
.SetValue("БАЛАНС ВРЕМЕНИ");
sheet.Cell(AddressDrilling)
._SetValue("Бурение", true);
sheet.Cell(AddressFlushing)
._SetValue("Промывка", true);
sheet.Cell(AddressBuilding)
._SetValue("Наращивание", true);
sheet.Cell(AddressElaboration)
._SetValue("Проработка", true);
sheet.Cell(AddressExtension)
._SetValue("Расширка", true);
sheet.Cell(AddressRepair)
._SetValue("Ремонт", true);
sheet.Cell(AddressDrillingValue)
._SetValue($"{blockDto.Drilling}");
sheet.Cell(AddressFlushingValue)
._SetValue($"{blockDto.Flushing}");
sheet.Cell(AddressBuildingValue)
._SetValue($"{blockDto.Building}");
sheet.Cell(AddressElaborationValue)
._SetValue($"{blockDto.Elaboration}");
sheet.Cell(AddressExtensionValue)
._SetValue($"{blockDto.Extension}");
sheet.Cell(AddressRepairValue)
._SetValue($"{blockDto.Repair}");
sheet.Cell(AddressKnbk)
._SetValue("КНБК");
sheet.Cell(AddressSpo)
._SetValue("СПО");
sheet.Cell(AddressPzr)
._SetValue("ПЗР");
sheet.Cell(AddressPvo)
._SetValue("ПВО");
sheet.Cell(AddressPgr)
._SetValue("ПГР");
sheet.Cell(AddressGis)
._SetValue("ГИС");
sheet.Cell(AddressKnbkValue)
._SetValue($"{blockDto.Knbk}");
sheet.Cell(AddressSpoValue)
._SetValue($"{blockDto.Spo}");
sheet.Cell(AddressPzrValue)
._SetValue($"{blockDto.Pzr}");
sheet.Cell(AddressPvoValue)
._SetValue($"{blockDto.Pvo}");
sheet.Cell(AddressPgrValue)
._SetValue($"{blockDto.Pgr}");
sheet.Cell(AddressGisValue)
._SetValue($"{blockDto.Gis}");
sheet.Cell(AddressOzc)
._SetValue("ОЗЦ");
sheet.Cell(AddressEngineeringWorks)
._SetValue("Тех. работы");
sheet.Cell(AddressTakingMeasure)
._SetValue("Снятие замера");
sheet.Cell(AddressCementing)
._SetValue("Цементирование");
sheet.Cell(AddressSimple)
._SetValue("Простой");
sheet.Cell(AddressNpv)
._SetValue("НПВ");
sheet.Cell(AddressOzcValue)
._SetValue($"{blockDto.Ozc}");
sheet.Cell(AddressEngineeringWorksValue)
._SetValue($"{blockDto.EngineeringWorks}");
sheet.Cell(AddressTakingMeasureValue)
._SetValue($"{blockDto.TakingMeasure}");
sheet.Cell(AddressCementingValue)
._SetValue($"{blockDto.Cementing}");
sheet.Cell(AddressSimpleValue)
._SetValue($"{blockDto.Simple}");
sheet.Cell(AddressNpvValue)
._SetValue($"{blockDto.Npv}");
sheet.Range(Title.RowNumber, Title.ColumnNumber, Title.RowNumber, Title.ColumnNumber + 1)
.Merge()
.SetValue("БАЛАНС ВРЕМЕНИ");
var i = 0;
foreach (var operationCategory in OperationCategories)
{
var row = 2 + (int)Math.Floor(1d * i / countColumns);
var col = 1 + 2 *(i % countColumns);
i++;
sheet.Cell(AddressBlockBegin + (row, col))
._SetValue(operationCategory.Name, true);
sheet.Cell(AddressBlockBegin + (row, col + 1))
._SetValue(GetValue(operationCategory.Id), true);
}
}
private string GetValue(int categoryId)
{
if (OperationsStatistics.TryGetValue(categoryId, out double duration))
return $"{duration}";
return "0";
}
}
}
#nullable disable

View File

@ -1,15 +1,21 @@
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport;
using AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks;
using ClosedXML.Excel;
using System.Collections.Generic;
using System.IO;
namespace AsbCloudInfrastructure.Services.DailyReport
{
public class DailyReportMakerExcel
{
public Stream MakeReportFromBlocks(DailyReportDto dto)
private IEnumerable<WellOperationCategoryDto> OperationCategories;
public Stream MakeReportFromBlocks(DailyReportDto dto, IEnumerable<WellOperationCategoryDto> operationCategories)
{
OperationCategories = operationCategories;
using var workbook = new XLWorkbook();
FillExampleBlocks(workbook, dto);
FillExampleBlocks(workbook, dto);
MemoryStream memoryStream = new MemoryStream();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
@ -26,7 +32,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport
var blockBha = new BhaBlock(addressStart, dto.Bha);
addressStart = blockBha.AddressBlockEnd + (1, 0);
addressStart.ColumnNumber = 2;
var timeBalance = new TimeBalanceBlock(addressStart, dto.TimeBalance);
var timeBalance = new TimeBalanceBlock(addressStart, dto.TimeBalance, OperationCategories);
addressStart = timeBalance.AddressBlockEnd + (1, 0);
addressStart.ColumnNumber = 2;
var blockDimensionless = new DimensionlessBlock(addressStart, dto.NoDrilling);
@ -47,7 +53,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport
blockSign.Draw(sheet);
//sheet.Columns().AdjustToContents(); // Adjust column width
sheet.Rows().AdjustToContents();
}
}
}
}

View File

@ -1,15 +1,19 @@
using System;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReport;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Mapster;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using System.Collections.Generic;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Exceptions;
namespace AsbCloudInfrastructure.Services.DailyReport
{
@ -17,16 +21,25 @@ namespace AsbCloudInfrastructure.Services.DailyReport
public class DailyReportService : IDailyReportService
{
private readonly IAsbCloudDbContext db;
private readonly IUserRepository userRepository;
private readonly IWellOperationRepository wellOperationRepository;
private readonly IWellService wellService;
private readonly DailyReportMakerExcel dailyReportMaker = new DailyReportMakerExcel();
public DailyReportService(IAsbCloudDbContext db, IWellService wellService)
public DailyReportService(
IAsbCloudDbContext db,
IWellService wellService,
IUserRepository userRepository,
IWellOperationRepository wellOperationRepository)
{
this.db = db;
this.wellService = wellService;
this.userRepository = userRepository;
this.wellOperationRepository = wellOperationRepository;
}
public async Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token)
public async Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken token)
{
var well = wellService.GetOrDefault(idWell);
if (well is null || well.Timezone is null)
@ -34,142 +47,196 @@ namespace AsbCloudInfrastructure.Services.DailyReport
var query = db.DailyReports.Where(r => r.IdWell == idWell);
DateTimeOffset ExtractDate(DateTime dateTime)
{
var dateTimeOffset = dateTime.ToUtcDateTimeOffset(well!.Timezone.Hours);
var date = new DateTimeOffset(dateTimeOffset.Year, dateTimeOffset.Month, dateTimeOffset.Day, 0,0,0,TimeSpan.Zero);
return date;
}
if (begin is not null)
{
var beginUTC = ExtractDate(begin.Value);
query = query.Where(d => d.StartDate >= beginUTC);
query = query.Where(d => d.StartDate >= begin);
}
if (end is not null)
{
var endUTC = ExtractDate(end.Value);
query = query.Where(d => d.StartDate <= endUTC);
query = query.Where(d => d.StartDate <= end);
}
var entities = await query
.OrderBy(e => e.StartDate)
.ToListAsync(token);
return entities.Select(r => Convert(r));
var entities = await query.OrderByDescending(e => e.StartDate)
.AsNoTracking()
.ToArrayAsync(token)
.ConfigureAwait(false);
var factOperationsForDtos = await GetFactOperationsForDailyReportAsync(idWell, token);
var userDtos = await userRepository.GetAllAsync(token);
var dtos = entities.Select(entity => Convert(entity, factOperationsForDtos, userDtos));
return dtos;
}
public async Task<DailyReportDto> GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token)
/// <summary>
/// Получение фактических операций для суточного рапорта
/// </summary>
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
private async Task<IEnumerable<WellOperationDto>> GetFactOperationsForDailyReportAsync(int idWell, CancellationToken token)
{
var dateOnly = DateTime.SpecifyKind(date.Date, DateTimeKind.Utc);
var dailyReportDto = await GetOrDefaultAsync(idWell, dateOnly, token);
dailyReportDto ??= await MakeDefaultDailyReportAsync(idWell, dateOnly, token);
return dailyReportDto;
var request = new WellOperationRequest()
{
IdWell = idWell,
OperationType = WellOperation.IdOperationTypeFact,
};
var factOperations = await wellOperationRepository.GetAsync(request, token);
return factOperations;
}
public async Task<int> AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default)
public async Task<int> AddAsync(int idWell, DateOnly startDate, int idUser, CancellationToken token)
{
var info = Convert(dto);
var well = wellService.GetOrDefault(idWell);
if (well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
var hasEntity = await db.DailyReports
.AnyAsync(r => r.IdWell == idWell && r.StartDate == startDate, token);
if (hasEntity)
throw new ArgumentInvalidException($"daily report on {startDate} already exists", nameof(startDate));
var entity = new AsbCloudDb.Model.DailyReport.DailyReport
{
IdWell = idWell,
StartDate = info.Head.ReportDate,
Info = info
StartDate = startDate,
Info = new DailyReportInfo()
{
Head = CreateHeadDailyReportBlock(well, startDate, idUser)
}
};
db.DailyReports.Add(entity);
var result = await db.SaveChangesAsync(token);
return result;
}
public async Task<int> UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token)
public async Task<int> UpdateBlockAsync(int idWell, DateOnly startDate, ItemInfoDto dto, CancellationToken token)
{
var dateOffset = date.Date;
var entity = await db.DailyReports
.FirstOrDefaultAsync(r => r.IdWell == idWell &&
r.StartDate.Year == dateOffset.Year &&
r.StartDate.DayOfYear == dateOffset.DayOfYear
, token);
var well = wellService.GetOrDefault(idWell);
if (well is null)
throw new ArgumentInvalidException("idWell doesn`t exist", nameof(idWell));
var entity = await db.DailyReports.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == startDate, token);
if (entity is null)
return 0;
throw new ArgumentInvalidException("Daily report doesn`t exist", nameof(startDate));
dto.LastUpdateDate = DateTimeOffset.Now;
if (dto is HeadDto headDto)
entity.Info.Head = headDto.Adapt<Head>();
if (dto is BhaDto bhaDto)
entity.Info.Bha = bhaDto.Adapt<Bha>();
if (dto is NoDrillingDto noDrillingDto)
entity.Info.NoDrilling = noDrillingDto.Adapt<NoDrilling>();
if (dto is SaubDto saubDto)
entity.Info.Saub = saubDto.Adapt<Saub>();
if (dto is SignDto signDto)
entity.Info.Sign = signDto.Adapt<Sign>();
entity.Info = Convert(dto);
db.DailyReports.Update(entity);
var result = await db.SaveChangesAsync(token);
return result;
}
public async Task<Stream?> MakeReportAsync(int idWell, DateTime date, CancellationToken token = default)
public async Task<Stream?> MakeReportAsync(int idWell, DateOnly date, CancellationToken token)
{
var stageIds = WellOperationCategory.WorkStages.Select(w => w.Id).ToArray();
var wellOperationCategories = wellOperationRepository.GetCategories(true)
.Where(o => o.IdParent is not null)
.Where(o => stageIds.Contains(o.IdParent!.Value));
var dailyReportDto = await GetOrDefaultAsync(idWell, date, token);
if (dailyReportDto is null)
return null;
var memoryStream = dailyReportMaker.MakeReportFromBlocks(dailyReportDto);
var memoryStream = dailyReportMaker.MakeReportFromBlocks(dailyReportDto, wellOperationCategories);
return memoryStream;
}
private async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateTime date, CancellationToken token)
private async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken token)
{
var dateOffset = date.Date;
var entity = await db.DailyReports
.FirstOrDefaultAsync(r => r.IdWell == idWell &&
r.StartDate.Year == dateOffset.Year &&
r.StartDate.DayOfYear == dateOffset.DayOfYear
, token);
.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == date, token);
if (entity is null)
return null;
var dto = Convert(entity);
throw new ArgumentInvalidException("Daily report doesn`t exist", nameof(date));
var factOperationsForDtos = await GetFactOperationsForDailyReportAsync(idWell, token);
var userDtos = await userRepository.GetAllAsync(token);
var dto = Convert(entity, factOperationsForDtos, userDtos);
return dto;
}
private async Task<DailyReportDto> MakeDefaultDailyReportAsync(int idWell, DateTime date, CancellationToken token)
/// <summary>
/// конвертация данных из модели базы данных в dto
/// </summary>
/// <param name="entity">модель базы данных</param>
/// <param name="factOperationsForDtos">список фактичских операций для формирования суточного рапорта</param>
/// <param name="users">список пользователей для нахождения последнего изменившего запись</param>
/// <returns></returns>
private DailyReportDto Convert(
AsbCloudDb.Model.DailyReport.DailyReport entity,
IEnumerable<WellOperationDto> factOperationsForDtos,
IEnumerable<UserExtendedDto> users)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
var dto = new DailyReportDto()
{
Head = new HeadDto()
{
ReportDate = date.Date,
WellName = well?.Caption ?? "",
ClusterName = well?.Cluster ?? "",
},
Bha = await GetPrevOrNewBhaAsync(idWell, date, token)
};
return dto;
}
private async Task<BhaDto> GetPrevOrNewBhaAsync(int idWell, DateTime date, CancellationToken token)
{
var dateOffset = date.Date;
var entity = await db.DailyReports
.Where(x => x.IdWell == idWell)
.OrderByDescending(x => x.StartDate)
.FirstOrDefaultAsync(r => r.StartDate.Year <= dateOffset.Year &&
r.StartDate.DayOfYear <= dateOffset.DayOfYear, token);
if (entity is null)
return new BhaDto();
var dto = Convert(entity);
return dto.Bha;
}
private static DailyReportDto Convert(AsbCloudDb.Model.DailyReport.DailyReport entity)
{
var dto = entity.Info.Adapt<DailyReportDto>();
dto.Head.ReportDate = entity.StartDate.Date;
dto.StartDate = entity.StartDate;
var dailyFactOperation = factOperationsForDtos
.Where(o => DateOnly.FromDateTime(o.DateStart) == dto.StartDate)
.Where(o => o.IdParentCategory is not null)
.GroupBy(o => o.IdParentCategory!.Value)
.ToDictionary(g => g.Key, g => g.Sum(o => o.DurationHours));
dto.TimeBalance.OperationsStat = dailyFactOperation;
var blocks = new ItemInfoDto[] {
dto.Head,
dto.Bha,
dto.NoDrilling,
dto.Saub,
dto.Sign
};
foreach (var block in blocks)
{
if (block.IdUser is not null)
{
block.UserName = users.FirstOrDefault(u => u.Id == block.IdUser.Value)?.MakeDisplayName()
?? $"userId:{block.IdUser.Value}";
}
}
return dto;
}
private static DailyReportInfo Convert(DailyReportDto dto)
/// <summary>
/// Создание блока "Заголовок" по умолчанию
/// </summary>
/// <param name="well"></param>
/// <param name="startDate"></param>
/// <param name="idUser"></param>
/// <returns></returns>
private Head CreateHeadDailyReportBlock(WellDto well, DateOnly startDate, int idUser)
{
var entity = dto.Adapt<DailyReportInfo>();
entity.Head.ReportDate = dto.Head.ReportDate.Date.Date;
return entity;
}
var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1);
var contractor = well.Companies.FirstOrDefault(company => company.IdCompanyType == 2);
return new Head()
{
ReportDate = startDate,
WellName = well.Caption,
ClusterName = well?.Cluster ?? string.Empty,
Customer = customer?.Caption ?? string.Empty,
Contractor = contractor?.Caption ?? string.Empty,
IdUser = idUser,
LastUpdateDate = DateTimeOffset.Now,
};
}
}
#nullable disable
}

View File

@ -86,16 +86,14 @@ namespace AsbCloudInfrastructure.Services.SAUB
}
}
// TODO: It shouldn`t be nullable. Throw exceptions instead and return empty.
/// <inheritdoc/>
public virtual async Task<IEnumerable<TDto>?> GetOrDefaultAsync(int idWell,
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell,
DateTime dateBegin = default, double intervalSec = 600d,
int approxPointsCount = 1024, CancellationToken token = default)
{
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
if (telemetry is null)
return null;
return Enumerable.Empty<TDto>();
var timezone = telemetryService.GetTimezone(telemetry.Id);
@ -134,7 +132,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
.ConfigureAwait(false);
if (fullDataCount == 0)
return default;
return Enumerable.Empty<TDto>();
if (fullDataCount > 1.75 * approxPointsCount)
{

View File

@ -121,8 +121,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
_ => 32_768
};
var data = await GetOrDefaultAsync(idWell, beginDate, intervalSec, approxPointsCount, token )
?? Enumerable.Empty<TelemetryDataSaubDto>();
var data = await GetAsync(idWell, beginDate, intervalSec, approxPointsCount, token );
var fileName = $"DataSaub idWell{idWell}";
if (telemetry.Info is not null)

View File

@ -0,0 +1,108 @@
using AsbCloudApp.ValidationAttributes;
using System;
using Xunit;
namespace AsbCloudWebApi.Tests.AttributeTest
{
public class DateValidationAttributeTest
{
[Fact]
public void AllowNull_true_on_null_valid()
{
var attribute = new DateValidationAttribute { AllowNull = true };
var result = attribute.IsValid(null);
Assert.True(result);
}
[Fact]
public void AllowNull_false_on_null_invalid()
{
var attribute = new DateValidationAttribute { AllowNull = false };
var result = attribute.IsValid(null);
Assert.False(result);
}
[Fact]
public void IsDateOnly_true_on_empty_timePart_valid()
{
var attribute = new DateValidationAttribute { IsDateOnly = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void IsDateOnly_true_on_timePart_invalid()
{
var attribute = new DateValidationAttribute { IsDateOnly = true };
var date = new DateTime(2023, 01, 01, 01, 01, 01);
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void IsDateOnly_true_on_utc_invalid()
{
var attribute = new DateValidationAttribute { IsDateOnly = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Utc);
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void AllowUtc_true_on_unspecified_valid()
{
var attribute = new DateValidationAttribute { AllowUtc = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Unspecified);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void AllowUtc_true_on_utc_valid()
{
var attribute = new DateValidationAttribute { AllowUtc = true };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Utc);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void AllowUtc_false_on_utc_invalid()
{
var attribute = new DateValidationAttribute { AllowUtc = false };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Utc);
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void AllowUtc_false_on_unspecified_valid()
{
var attribute = new DateValidationAttribute { AllowUtc = false };
var date = new DateTime(2023, 01, 01, 00, 00, 00, DateTimeKind.Unspecified);
var result = attribute.IsValid(date);
Assert.True(result);
}
[Fact]
public void GtDate_on_same_date_invalid()
{
var gtDate = "2023-01-01T00:00:00";
var date = DateTime.Parse(gtDate);
var attribute = new DateValidationAttribute { GtDate = gtDate };
var result = attribute.IsValid(date);
Assert.False(result);
}
[Fact]
public void GtDate_on_greater_date_valid()
{
var gtDate = "2023-01-01T00:00:00";
var date = DateTime.Parse(gtDate).AddMilliseconds(1);
var attribute = new DateValidationAttribute { GtDate = gtDate };
var result = attribute.IsValid(date);
Assert.True(result);
}
}
}

View File

@ -35,7 +35,7 @@ namespace AsbCloudWebApi.Tests.Middlware
public class TelemetryDataSaubService : ITelemetryDataSaubService
{
public async Task<IEnumerable<TelemetryDataSaubDto>?> GetOrDefaultAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default)
public async Task<IEnumerable<TelemetryDataSaubDto>?> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default)
{
await Task.Delay(1000, token);
return Enumerable.Empty<TelemetryDataSaubDto>();

View File

@ -1,4 +1,6 @@
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@ -10,6 +12,7 @@ using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers
{
#nullable enable
/// <summary>
/// Суточный рапорт
/// </summary>
@ -20,11 +23,16 @@ namespace AsbCloudWebApi.Controllers
{
private readonly IDailyReportService dailyReportService;
private readonly IWellService wellService;
private readonly IWellOperationRepository operationRepository;
public DailyReportController(IDailyReportService dailyReportService, IWellService wellService)
public DailyReportController(
IDailyReportService dailyReportService,
IWellService wellService,
IWellOperationRepository operationRepository)
{
this.dailyReportService = dailyReportService;
this.wellService = wellService;
this.operationRepository = operationRepository;
}
/// <summary>
@ -36,60 +44,115 @@ namespace AsbCloudWebApi.Controllers
/// <param name="token"></param>
/// <returns></returns>
[HttpGet]
//[Permission]
[ProducesResponseType(typeof(IEnumerable<DailyReportDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetListAsync(int idWell, DateTime? begin = null, DateTime? end = null, CancellationToken token = default)
public async Task<IActionResult> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken token)
{
var result = await dailyReportService.GetListAsync(idWell, begin, end, token);
return Ok(result);
}
/// <summary>
/// Получить из БД или генерировать набор данных для формирования рапорта на новую дату.
/// Создание суточного рапорта
/// </summary>
/// <param name="idWell"></param>
/// <param name="date"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("{date}")]
//[Permission]
[ProducesResponseType(typeof(DailyReportDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetOrGenerateAsync(int idWell, [Required] DateTime date, CancellationToken token = default)
{
var dto = await dailyReportService.GetOrGenerateAsync(idWell, date, token);
return Ok(dto);
}
/// <summary>
/// Сохранение нового набора данных для формирования рапорта
/// </summary>
/// <param name="idWell"></param>
/// <param name="dto"></param>
/// <param name="startDate"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPost]
//[Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> AddAsync(int idWell, [Required][FromBody] DailyReportDto dto, CancellationToken token = default)
public async Task<IActionResult> AddAsync(int idWell, [Required] DateOnly startDate, CancellationToken token)
{
var result = await dailyReportService.AddAsync(idWell, dto, token);
if (!await UserHasAccesToWellAsync(idWell, token))
return Forbid();
var idUser = User.GetUserId()!.Value;
var result = await dailyReportService.AddAsync(idWell, startDate, idUser, token);
return Ok(result);
}
/// <summary>
/// Сохранение изменений набора данных для формирования рапорта
/// Сохранение изменений набора данных для формирования рапорта (заголовок)
/// </summary>
/// <param name="idWell"></param>
/// <param name="date"></param>
/// <param name="date">Дата без учета времени</param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPut("{date}")]
//[Permission]
[HttpPut("{date}/head")]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> UpdateAsync(int idWell, [Required] DateTime date, [Required] DailyReportDto dto, CancellationToken token = default)
public Task<IActionResult> UpdateHeadAsync(int idWell, [Required] DateOnly date, [Required] HeadDto dto, CancellationToken token)
=> UpdateReportBlockAsync(idWell, date, dto, token);
/// <summary>
/// Сохранение изменений набора данных для формирования рапорта (блок КНБК)
/// </summary>
/// <param name="idWell"></param>
/// <param name="date">Дата без учета времени</param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPut("{date}/bha")]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public Task<IActionResult> UpdateBhaAsync(int idWell, [Required] DateOnly date, [Required] BhaDto dto, CancellationToken token)
=> UpdateReportBlockAsync(idWell, date, dto, token);
/// <summary>
/// Сохранение изменений набора данных для формирования рапорта (безметражные работы)
/// </summary>
/// <param name="idWell"></param>
/// <param name="date">Дата без учета времени</param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPut("{date}/noDrilling")]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public Task<IActionResult> UpdateNoDrillingAsync(int idWell, [Required] DateOnly date, [Required] NoDrillingDto dto, CancellationToken token)
=> UpdateReportBlockAsync(idWell, date, dto, token);
/// <summary>
/// Сохранение изменений набора данных для формирования рапорта (САУБ)
/// </summary>
/// <param name="idWell"></param>
/// <param name="date">Дата без учета времени</param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPut("{date}/saub")]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public Task<IActionResult> UpdateSaubAsync(int idWell, [Required] DateOnly date, [Required] SaubDto dto, CancellationToken token)
=> UpdateReportBlockAsync(idWell, date, dto, token);
/// <summary>
/// Сохранение изменений набора данных для формирования рапорта (подпись)
/// </summary>
/// <param name="idWell"></param>
/// <param name="date">Дата без учета времени</param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPut("{date}/sign")]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public Task<IActionResult> UpdateSignAsync(int idWell, [Required] DateOnly date, [Required] SignDto dto, CancellationToken token)
=> UpdateReportBlockAsync(idWell, date, dto, token);
/// <summary>
/// Обновление блока суточного рапорта
/// </summary>
/// <param name="idWell">ключ скважины</param>
/// <param name="date">дата суточного рапорта</param>
/// <param name="dto"></param>
/// <param name="token"></param>
/// <returns></returns>
private async Task<IActionResult> UpdateReportBlockAsync(int idWell, DateOnly date, ItemInfoDto dto, CancellationToken token)
{
var result = await dailyReportService.UpdateAsync(idWell, date, dto, token);
if (!await UserHasAccesToWellAsync(idWell, token))
return Forbid();
dto.IdUser = User.GetUserId();
dto.LastUpdateDate = DateTimeOffset.Now;
var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token);
return Ok(result);
}
@ -101,19 +164,34 @@ namespace AsbCloudWebApi.Controllers
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("{date}/excel")]
//[Permission]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> DownloadAsync(int idWell, DateTime date, CancellationToken token = default)
public async Task<IActionResult> DownloadAsync(int idWell, DateOnly date, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
if (!await UserHasAccesToWellAsync(idWell, token))
return Forbid();
var well = await wellService.GetOrDefaultAsync(idWell, token)
?? throw new ArgumentInvalidException($"Скважина c id:{idWell} не найдена", nameof(idWell));
var stream = await dailyReportService.MakeReportAsync(idWell, date, token);
if (stream != null)
if (stream is not null)
{
var fileName = $"Суточный рапорт по скважине {well.Caption} куст {well.Cluster}.xlsx";
var fileName = $"Суточный рапорт по скважине {well.Caption} куст {well.Cluster}.xlsx";
return File(stream, "application/octet-stream", fileName);
}
else
return NoContent();
}
protected async Task<bool> UserHasAccesToWellAsync(int idWell, CancellationToken token)
{
var idCompany = User.GetCompanyId();
if (idCompany is not null &&
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
.ConfigureAwait(false))
return true;
return false;
}
}
#nullable disable
}

View File

@ -77,22 +77,17 @@ namespace AsbCloudWebApi.Controllers
/// <param name="token"></param>
/// <returns></returns>
[HttpGet]
[Route("cluster/{idCluster}/stat")] // TODO: Это статистика кластера, перенести в ClusterOperationStatController
[Route("cluster/{idCluster}/stat")]
[Permission]
[ProducesResponseType(typeof(StatClusterDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetStatClusterAsync(int idCluster,
CancellationToken token = default)
{
int? idCompanyOrNull = User.GetCompanyId();
if (idCompanyOrNull is null)
int? idCompany = User.GetCompanyId();
if (idCompany is null)
return Forbid();
int idCompany = idCompanyOrNull ?? 0;
// TODO: Fix next commented lines
//if (!await CanUserAccessToWellAsync(idCluster, token).ConfigureAwait(false))
// return Forbid();
var result = await operationsStatService.GetStatClusterAsync(idCluster, idCompany, token)
var result = await operationsStatService.GetStatClusterAsync(idCluster, idCompany.Value, token)
.ConfigureAwait(false);
return Ok(result);
}

View File

@ -86,7 +86,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
if (!isCompanyOwnsWell)
return Forbid();
var content = await telemetryDataService.GetOrDefaultAsync(idWell, begin,
var content = await telemetryDataService.GetAsync(idWell, begin,
intervalSec, approxPointsCount, token).ConfigureAwait(false);
return Ok(content);

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers
{
#nullable enable
/// <summary>
/// Расписание бурильщиков
/// </summary>
@ -32,12 +33,12 @@ namespace AsbCloudWebApi.Controllers
/// <param name="token"></param>
/// <returns>бурильщик</returns>
[HttpGet("driller")]
public async Task<ActionResult<DrillerDto>> GetDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
public async Task<ActionResult<DrillerDto?>> GetDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
{
if (!await UserHasAccesToWellAsync(idWell, token))
return Forbid();
var result = await scheduleService.GetDrillerAsync(idWell, workTime, token);
var result = await scheduleService.GetOrDefaultDrillerAsync(idWell, workTime, token);
return Ok(result);
}

View File

@ -0,0 +1,22 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AsbCloudWebApi.Converters
{
#nullable enable
public class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateOnly.FromDateTime(reader.GetDateTime());
}
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
{
var isoDate = value.ToString("O");
writer.WriteStringValue(isoDate);
}
}
#nullable disable
}

View File

@ -0,0 +1,48 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AsbCloudWebApi.Converters
{
#nullable enable
public class DateOnlyTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string str)
{
return DateOnly.Parse(str);
}
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
{
if (destinationType == typeof(string) && value is DateOnly date)
{
return date.ToString("O");
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
#nullable disable
}

View File

@ -5,7 +5,7 @@ using System.Globalization;
namespace AsbCloudWebApi.Converters
{
#nullable enable
public class DateOnlyTypeConverter : TypeConverter
public class TimeOnlyTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{

View File

@ -3,11 +3,9 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
@ -19,6 +17,7 @@ namespace AsbCloudWebApi
{
services.AddSwaggerGen(c =>
{
c.MapType<DateOnly>(() => new OpenApiSchema { Type = "string", Format = "date" });
c.CustomOperationIds(e =>
{
return $"{e.ActionDescriptor.RouteValues["action"]}";

View File

@ -1,9 +1,10 @@
using AsbCloudApp.Data;
using System.Collections.Generic;
using System.Linq;
using AsbCloudWebApi.Converters;
using System;
using System.ComponentModel;
using System.Security.Claims;
namespace Microsoft.AspNetCore.Mvc
namespace Microsoft.AspNetCore.Mvc
{
public static class Extentions
{
@ -38,48 +39,12 @@ namespace Microsoft.AspNetCore.Mvc
});
}
public static BadRequestBuilder BadRequestBuilder(this ControllerBase controller, string paramName, params string[] errors)
=> new BadRequestBuilder(paramName, errors);
}
public class BadRequestBuilder
{
private readonly Dictionary<string, List<string>> body;
private List<string> GetOrCreateNew(string paramName)
public static MvcOptions UseDateOnlyTimeOnlyStringConverters(this MvcOptions options)
{
List<string> par;
if (body.ContainsKey(paramName))
par = body[paramName];
else
{
par = new List<string>();
body[paramName] = par;
}
return par;
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));
return options;
}
public BadRequestBuilder(string paramName, params string[] errors)
{
body = new();
body[paramName] = new List<string>(errors);
}
public BadRequestBuilder Add(string paramName, params string[] errors)
{
var par = GetOrCreateNew(paramName);
par.AddRange(errors);
return this;
}
public BadRequestObjectResult Build()
{
var o = body.Select(e => new { name = e.Key, errors = e.Value.ToArray() });
return new BadRequestObjectResult(o);
}
public static implicit operator BadRequestObjectResult(BadRequestBuilder d) => d.Build();
}
}

View File

@ -1,4 +1,5 @@
using AsbCloudInfrastructure;
using AsbCloudWebApi.Converters;
using AsbCloudWebApi.Middlewares;
using AsbCloudWebApi.SignalR;
using Microsoft.AspNetCore.Builder;
@ -6,6 +7,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Mvc;
namespace AsbCloudWebApi
{
@ -25,9 +27,13 @@ namespace AsbCloudWebApi
options.JsonSerializerOptions.NumberHandling =
System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals |
System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString;
options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
}))
.AddProtoBufNet();
services.AddControllers(options => options.UseDateOnlyTimeOnlyStringConverters());
ProtobufModel.EnshureRegistered();
services.AddSwagger();
@ -87,6 +93,7 @@ namespace AsbCloudWebApi
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)