forked from ddrilling/AsbCloudServer
- Added t_daily_report table and related migrations;
- Added request processing service for DailyReportController. Implemented all methods except DownloadAsync.
This commit is contained in:
parent
c31cb55d2b
commit
019c6a4db1
216
AsbCloudApp/Data/DailyReportDto.cs
Normal file
216
AsbCloudApp/Data/DailyReportDto.cs
Normal file
@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DailyReportDto
|
||||
{
|
||||
/// <summary>
|
||||
///название скважины
|
||||
/// <summary>
|
||||
public string WellName { get; set; }
|
||||
|
||||
///<summary>
|
||||
///название куста
|
||||
///<summary>
|
||||
public string ClusterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///заказчик
|
||||
///<summary>
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///подрядчик
|
||||
///<summary>
|
||||
public string Contractor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///дата рапорта
|
||||
///<summary>
|
||||
public DateTime ReportDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///глубина забоя на дату начала интервала
|
||||
///<summary>
|
||||
public double? WellDepthIntervalStartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///глубина забоя на дату окончания интервала
|
||||
///<summary>
|
||||
public double? WellDepthIntervalFinishDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Глубина забоя по стволу на окончание отчетного периода
|
||||
///<summary>
|
||||
public double? BottomholeDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Глубина забоя по вертикали на дату окончания отчетного периода
|
||||
///<summary>
|
||||
public double? VerticalDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Зeнитный угол на дату окончания отчетного периода
|
||||
///<summary>
|
||||
public double? ZenithAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Азимутальный угол на дату окончания отчетного периода
|
||||
///<summary>
|
||||
public double? AzimuthAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО бурильщиков
|
||||
///<summary>
|
||||
public string FirstDriller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО бурильщиков
|
||||
///<summary>
|
||||
public string SecondDriller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Время работы АПД
|
||||
///<summary>
|
||||
public double? WorkTimeSAUB { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Время работы спин мастер
|
||||
///<summary>
|
||||
public double? WorkTimeSpinMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Время работы торк мастер
|
||||
///<summary>
|
||||
public double? WorkTimeTorkMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных с включенным АПД
|
||||
///<summary>
|
||||
public double? PenetrationSAUB { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных с включенным Спин мастер
|
||||
///<summary>
|
||||
public double? PenetrationSpinMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных с включенным торк мастер
|
||||
///<summary>
|
||||
public double? PenetrationTorkMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество запусков МСЕ
|
||||
///<summary>
|
||||
public int CountLaunchesMSE { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///КНБК описание
|
||||
///<summary>
|
||||
public string BHADescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Нормативное время на одну операцию по подготовке ствола скважины к наращиванию
|
||||
///<summary>
|
||||
public double? StandardTimeBarrelPreparation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Нормативное время на одну операцию по наращиванию
|
||||
///<summary>
|
||||
public double? StandardTimeExtension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Фактическое время проработок при подготовке ствола скважины к наращиванию.
|
||||
///<summary>
|
||||
public double? ActualTimeBarrelPreparation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Фактическое время наращиваний
|
||||
///<summary>
|
||||
public double? ActualTimeExtension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Режимы бурения в роторе
|
||||
///<summary>
|
||||
public IEnumerable<string> RotorDrillingModes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///режимы бурения в слайде
|
||||
///<summary>
|
||||
public IEnumerable<string> SlideDrillingModes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество метров пробуренных в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? PenetrationInRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество часов бурения в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? NumberDrillingHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///средний диф перепад в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? AVGDiffDropRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных в слайде за отчетный период
|
||||
///<summary>
|
||||
public double? PenetrationInSlide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///время бурения в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? DrillingTimeInRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///средний диф перепад в слайде за отчетный период
|
||||
///<summary>
|
||||
public double? AVGDiffPressureSlide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Плановая МСП за секцию
|
||||
///<summary>
|
||||
public double? SectionROPPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Общее время бурения за секцию
|
||||
///<summary>
|
||||
public double? SectionDrillingTimeTotal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Общая проходка за секцию
|
||||
///<summary>
|
||||
public double? SectionPenetrationTotal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество наращиваний за отчетный период
|
||||
///<summary>
|
||||
public int ExtensionsCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Отклонение относительно ГГД
|
||||
///<summary>
|
||||
public double? DeviationFromTVD { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///указываются все причины, которые влияют на снижение МСП.
|
||||
///<summary>
|
||||
public string DeclinesReasonsROP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО Мастера буровой
|
||||
///<summary>
|
||||
public string DrillingMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО супервайзера
|
||||
///<summary>
|
||||
public string Supervisor { get; set; }
|
||||
}
|
||||
}
|
20
AsbCloudApp/Services/IDailyReportService.cs
Normal file
20
AsbCloudApp/Services/IDailyReportService.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface IDailyReportService
|
||||
{
|
||||
Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateTime? v1, DateTime? v2, CancellationToken cancellationToken);
|
||||
Task<IEnumerable<DailyReportDto>> GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token);
|
||||
Task<int> AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default);
|
||||
Task<int> UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token = default);
|
||||
Task<Stream> MakeReportAsync(int idWell, DateTime date, CancellationToken token = default);
|
||||
}
|
||||
}
|
5807
AsbCloudDb/Migrations/20220420124920_Add_DailyReport_Table.Designer.cs
generated
Normal file
5807
AsbCloudDb/Migrations/20220420124920_Add_DailyReport_Table.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using AsbCloudDb.Model;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_DailyReport_Table : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_daily_report",
|
||||
columns: table => new
|
||||
{
|
||||
id_well = table.Column<int>(type: "integer", nullable: false, comment: "ID скважины"),
|
||||
start_date = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата отчёта"),
|
||||
info = table.Column<DailyReportInfo>(type: "jsonb", nullable: true, comment: "Список параметров для отчёта")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("t_id_well_date_start_pk", x => new { x.id_well, x.start_date });
|
||||
table.ForeignKey(
|
||||
name: "FK_t_daily_report_t_well_id_well",
|
||||
column: x => x.id_well,
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Ежедневные отчёты");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_daily_report");
|
||||
}
|
||||
}
|
||||
}
|
@ -137,6 +137,31 @@ namespace AsbCloudDb.Migrations
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b =>
|
||||
{
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ID скважины");
|
||||
|
||||
b.Property<DateTimeOffset>("StartDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("start_date")
|
||||
.HasComment("Дата отчёта");
|
||||
|
||||
b.Property<DailyReportInfo>("Info")
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("info")
|
||||
.HasComment("Список параметров для отчёта");
|
||||
|
||||
b.HasKey("IdWell", "StartDate")
|
||||
.HasName("t_id_well_date_start_pk");
|
||||
|
||||
b.ToTable("t_daily_report");
|
||||
|
||||
b.HasComment("Ежедневные отчёты");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Deposit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -5142,6 +5167,17 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("CompanyType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DrillFlowChart", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
|
@ -43,6 +43,7 @@ namespace AsbCloudDb.Model
|
||||
public virtual DbSet<RelationUserRolePermission> RelationUserRolePermissions { get; set; }
|
||||
public virtual DbSet<RelationUserRoleUserRole> RelationUserRoleUserRoles { get; set; }
|
||||
public virtual DbSet<RelationUserDrillingProgramPart> RelationDrillingProgramPartUsers { get; set; }
|
||||
public virtual DbSet<DailyReport> DailyReport { get; set; }
|
||||
|
||||
// WITS
|
||||
public DbSet<WITS.Record1> Record1 { get; set; }
|
||||
@ -299,6 +300,12 @@ namespace AsbCloudDb.Model
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity<DailyReport>(entity =>
|
||||
{
|
||||
entity.HasKey(e => new { e.IdWell, e.StartDate })
|
||||
.HasName("t_id_well_date_start_pk");
|
||||
});
|
||||
|
||||
FillData(modelBuilder);
|
||||
}
|
||||
|
||||
|
28
AsbCloudDb/Model/DailyReport.cs
Normal file
28
AsbCloudDb/Model/DailyReport.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_daily_report"), Comment("Ежедневные отчёты")]
|
||||
public class 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("info", TypeName = "jsonb"), Comment("Список параметров для отчёта")]
|
||||
public DailyReportInfo Info { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
public virtual Well Well { get; set; }
|
||||
}
|
||||
}
|
216
AsbCloudDb/Model/DailyReportInfo.cs
Normal file
216
AsbCloudDb/Model/DailyReportInfo.cs
Normal file
@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
public class DailyReportInfo
|
||||
{
|
||||
/// <summary>
|
||||
///название скважины
|
||||
/// <summary>
|
||||
public string WellName { get; set; }
|
||||
|
||||
///<summary>
|
||||
///название куста
|
||||
///<summary>
|
||||
public string ClusterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///заказчик
|
||||
///<summary>
|
||||
public string Customer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///подрядчик
|
||||
///<summary>
|
||||
public string Contractor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///дата рапорта
|
||||
///<summary>
|
||||
public DateTime ReportDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///глубина забоя на дату начала интервала
|
||||
///<summary>
|
||||
public double? WellDepthIntervalStartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///глубина забоя на дату окончания интервала
|
||||
///<summary>
|
||||
public double? WellDepthIntervalFinishDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Глубина забоя по стволу на окончание отчетного периода
|
||||
///<summary>
|
||||
public double? BottomholeDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Глубина забоя по вертикали на дату окончания отчетного периода
|
||||
///<summary>
|
||||
public double? VerticalDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Зeнитный угол на дату окончания отчетного периода
|
||||
///<summary>
|
||||
public double? ZenithAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Азимутальный угол на дату окончания отчетного периода
|
||||
///<summary>
|
||||
public double? AzimuthAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО бурильщиков
|
||||
///<summary>
|
||||
public string FirstDriller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО бурильщиков
|
||||
///<summary>
|
||||
public string SecondDriller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Время работы АПД
|
||||
///<summary>
|
||||
public double? WorkTimeSAUB { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Время работы спин мастер
|
||||
///<summary>
|
||||
public double? WorkTimeSpinMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Время работы торк мастер
|
||||
///<summary>
|
||||
public double? WorkTimeTorkMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных с включенным АПД
|
||||
///<summary>
|
||||
public double? PenetrationSAUB { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных с включенным Спин мастер
|
||||
///<summary>
|
||||
public double? PenetrationSpinMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных с включенным торк мастер
|
||||
///<summary>
|
||||
public double? PenetrationTorkMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество запусков МСЕ
|
||||
///<summary>
|
||||
public int CountLaunchesMSE { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///КНБК описание
|
||||
///<summary>
|
||||
public string BHADescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Нормативное время на одну операцию по подготовке ствола скважины к наращиванию
|
||||
///<summary>
|
||||
public double? StandardTimeBarrelPreparation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Нормативное время на одну операцию по наращиванию
|
||||
///<summary>
|
||||
public double? StandardTimeExtension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Фактическое время проработок при подготовке ствола скважины к наращиванию.
|
||||
///<summary>
|
||||
public double? ActualTimeBarrelPreparation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Фактическое время наращиваний
|
||||
///<summary>
|
||||
public double? ActualTimeExtension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Режимы бурения в роторе
|
||||
///<summary>
|
||||
public IEnumerable<string> RotorDrillingModes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///режимы бурения в слайде
|
||||
///<summary>
|
||||
public IEnumerable<string> SlideDrillingModes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество метров пробуренных в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? PenetrationInRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество часов бурения в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? NumberDrillingHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///средний диф перепад в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? AVGDiffDropRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///количество метров пробуренных в слайде за отчетный период
|
||||
///<summary>
|
||||
public double? PenetrationInSlide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///время бурения в роторе за отчетный период
|
||||
///<summary>
|
||||
public double? DrillingTimeInRotor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///средний диф перепад в слайде за отчетный период
|
||||
///<summary>
|
||||
public double? AVGDiffPressureSlide { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Плановая МСП за секцию
|
||||
///<summary>
|
||||
public double? SectionROPPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Общее время бурения за секцию
|
||||
///<summary>
|
||||
public double? SectionDrillingTimeTotal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Общая проходка за секцию
|
||||
///<summary>
|
||||
public double? SectionPenetrationTotal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Количество наращиваний за отчетный период
|
||||
///<summary>
|
||||
public int ExtensionsCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Отклонение относительно ГГД
|
||||
///<summary>
|
||||
public double? DeviationFromTVD { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///указываются все причины, которые влияют на снижение МСП.
|
||||
///<summary>
|
||||
public string DeclinesReasonsROP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО Мастера буровой
|
||||
///<summary>
|
||||
public string DrillingMaster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///ФИО супервайзера
|
||||
///<summary>
|
||||
public string Supervisor { get; set; }
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ namespace AsbCloudDb.Model
|
||||
DbSet<DrillingProgramPart> DrillingProgramParts { get; set; }
|
||||
DbSet<RelationUserDrillingProgramPart> RelationDrillingProgramPartUsers { get; set; }
|
||||
DbSet<RelationCompanyWell> RelationCompaniesWells { get; set; }
|
||||
DbSet<DailyReport> DailyReport { get; set; }
|
||||
|
||||
int SaveChanges();
|
||||
int SaveChanges(bool acceptAllChangesOnSuccess);
|
||||
|
@ -85,6 +85,7 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IWellOperationService, WellOperationService>();
|
||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
|
||||
// admin crud services:
|
||||
services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>(); // может быть включен в сервис TelemetryService
|
||||
|
8
AsbCloudInfrastructure/IInfrastructureMarker.cs
Normal file
8
AsbCloudInfrastructure/IInfrastructureMarker.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace AsbCloudInfrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Тип для поиска этой сборки
|
||||
/// </summary>
|
||||
public interface IInfrastructureMarker
|
||||
{}
|
||||
}
|
Binary file not shown.
337
AsbCloudInfrastructure/Services/DailyReportService.cs
Normal file
337
AsbCloudInfrastructure/Services/DailyReportService.cs
Normal file
@ -0,0 +1,337 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.Cache;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
public class DailyReportService : IDailyReportService
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IOperationsStatService operationsStatService;
|
||||
const string sheetNameSchedule = "Дневной отчёт";
|
||||
private static readonly int[,] ParamsCellsIndexes = new int[42, 2] {
|
||||
{0,0},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1},
|
||||
{1,1}
|
||||
};
|
||||
|
||||
|
||||
public DailyReportService(IAsbCloudDbContext db, IWellService wellService)
|
||||
{
|
||||
this.db = db;
|
||||
this.wellService = wellService;
|
||||
}
|
||||
private DateTimeOffset Convert(DateTime date, int idWell)
|
||||
{
|
||||
var hours = wellService.GetTimezone(idWell).Hours;
|
||||
var dateOffset = DateTimeExtentions.ToUtcDateTimeOffset((DateTime)date, hours);
|
||||
return dateOffset;
|
||||
}
|
||||
|
||||
private DailyReportDto Convert(DailyReport data, int idWell)
|
||||
{
|
||||
var hours = wellService.GetTimezone(idWell).Hours;
|
||||
var dto = data.Adapt<DailyReportDto>();
|
||||
dto.ReportDate = data.StartDate.ToRemoteDateTime(hours);
|
||||
return dto;
|
||||
}
|
||||
private static Stream GetExcelTemplateStream()
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetAssembly(typeof(AsbCloudInfrastructure.IInfrastructureMarker));
|
||||
var stream = assembly.GetManifestResourceStream("AsbCloudInfrastructure.Services.DailyReport.DailyReportTemplate.xlsx");
|
||||
return stream;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token)
|
||||
{
|
||||
var hours = wellService.GetTimezone(idWell).Hours;
|
||||
var query = db.DailyReport.Where(r => r.IdWell == idWell);
|
||||
|
||||
if (begin is not null)
|
||||
query = query.Where(d => d.StartDate >= Convert((DateTime)begin, idWell));
|
||||
|
||||
if (end is not null)
|
||||
query = query.Where(d => d.StartDate <= Convert((DateTime)end, idWell));
|
||||
|
||||
var data = await query.ToListAsync(token);
|
||||
return data.Select(d=>Convert(d, idWell));
|
||||
}
|
||||
|
||||
public IEnumerable<DailyReportDto> GetDefaultDailyReportDto()
|
||||
{
|
||||
var dto = new DailyReportDto()
|
||||
{
|
||||
ReportDate = DateTime.Now,
|
||||
};
|
||||
IEnumerable<DailyReportDto> result = new List<DailyReportDto> { dto };
|
||||
return result;
|
||||
}
|
||||
public async Task<IEnumerable<DailyReportDto>> GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token)
|
||||
{
|
||||
var query = db.DailyReport.Where(r => r.IdWell == idWell);
|
||||
query = query.Where(d => d.StartDate == Convert(date, idWell));
|
||||
|
||||
var data = await query.ToListAsync(token);
|
||||
if (data.Count == 0)
|
||||
return GetDefaultDailyReportDto();
|
||||
else
|
||||
return data.Select(d => Convert(d, idWell));
|
||||
}
|
||||
public async Task<int> AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default)
|
||||
{
|
||||
var entity = dto.Adapt<DailyReport>();
|
||||
entity.StartDate = Convert(dto.ReportDate, idWell);
|
||||
db.DailyReport.Add(entity);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
return result;
|
||||
}
|
||||
public async Task<int> UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token)
|
||||
{
|
||||
var entity = dto.Adapt<DailyReport>();
|
||||
entity.StartDate = Convert(dto.ReportDate, idWell);
|
||||
db.DailyReport.Update(entity);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Stream> MakeReportAsync(int idWell, DateTime date, CancellationToken token = default)
|
||||
{
|
||||
var tvd = await operationsStatService.GetTvdAsync(idWell, token);
|
||||
|
||||
if (!tvd.Any())
|
||||
return null;
|
||||
|
||||
var well = await wellService.GetAsync(idWell, token);
|
||||
|
||||
var ecxelTemplateStream = GetExcelTemplateStream();
|
||||
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
||||
FillScheduleSheetToWorkbook(workbook, tvd, well);
|
||||
FillTvdSheetToWorkbook(workbook, tvd, well);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static void FillScheduleSheetToWorkbook(XLWorkbook workbook, IEnumerable<PlanFactPredictBase<WellOperationDto>> tvd, WellDto well)
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameSchedule);
|
||||
if (sheet is null)
|
||||
return;
|
||||
|
||||
const int headerRowsCount = 6;
|
||||
const int rowTitle = 3;
|
||||
|
||||
const int columnRowNumber = 2;
|
||||
const int columnCaption = 3;
|
||||
const int columnWellDepthStartPlan = 4;
|
||||
const int columnWellDepthStartFact = 5;
|
||||
const int columnWellDepthStartPredict = 6;
|
||||
const int columnWellDepthEndPlan = 7;
|
||||
const int columnWellDepthEndFact = 8;
|
||||
const int columnWellDepthEndPredict = 9;
|
||||
const int columnDeltaWellDepthPerDay = 10;
|
||||
const int columnDurationPlan = 11;
|
||||
const int columnDurationFact = 12;
|
||||
const int columnDurationPredict = 13;
|
||||
const int columnDateStartPlan = 14;
|
||||
const int columnDateStartFact = 15;
|
||||
const int columnDateStartPredict = 16;
|
||||
const int columnDateEndPlan = 17;
|
||||
const int columnDateEndFact = 18;
|
||||
const int columnDateEndPredict = 19;
|
||||
const int columnGuilty = 20;
|
||||
const int columnNpt = 21;
|
||||
|
||||
var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}";
|
||||
sheet.Row(rowTitle).Cell(3).Value = subTitle;
|
||||
|
||||
var tvdList = tvd.ToList();
|
||||
|
||||
}
|
||||
|
||||
private static void FillTvdSheetToWorkbook(XLWorkbook workbook, IEnumerable<PlanFactPredictBase<WellOperationDto>> tvd, WellDto well)
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameTvd);
|
||||
if (sheet is null)
|
||||
return;
|
||||
|
||||
const int rowTitle = 2;
|
||||
const int rowSubtitle = 3;
|
||||
const int colTitle = 5;
|
||||
|
||||
const int rowTopStatTitle = 2;
|
||||
const int colTopStatvalue = 10;
|
||||
|
||||
const int colBottomStatvalue = 3;
|
||||
const int rowStartDateFact = 43;
|
||||
const int rowEndDatePlan = 44;
|
||||
const int rowEndDateFact = 45;
|
||||
|
||||
sheet.Row(rowSubtitle).Cell(colTitle).Value
|
||||
= $"скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}";
|
||||
|
||||
SetCell(sheet.Row(rowTitle), colTopStatvalue, DateTime.Now);
|
||||
|
||||
var Plan = tvd.Where(t => t.Plan is not null)
|
||||
.Select(t => t.Plan);
|
||||
var Fact = tvd.Where(t => t.Fact is not null)
|
||||
.Select(t => t.Fact);
|
||||
var Predict = tvd.Where(t => t.Predict is not null)
|
||||
.Select(t => t.Predict);
|
||||
|
||||
var startDateFact = Fact.FirstOrDefault()?.DateStart;
|
||||
var planLast = Plan.LastOrDefault();
|
||||
var factLast = Fact.LastOrDefault();
|
||||
var predictLast = Predict.LastOrDefault();
|
||||
|
||||
static DateTime GetEndDate(WellOperationDto operation)
|
||||
=> operation is not null
|
||||
? operation.DateStart.AddHours(operation.DurationHours)
|
||||
: default;
|
||||
|
||||
var endDatePlan = GetEndDate(planLast);
|
||||
var endDateFact = GetEndDate(factLast);
|
||||
var endDatePredict = GetEndDate(predictLast);
|
||||
|
||||
var endDate = endDatePredict > endDateFact
|
||||
? endDatePredict
|
||||
: endDateFact;
|
||||
|
||||
if (startDateFact is not null)
|
||||
{
|
||||
SetCell(sheet.Row(rowStartDateFact), colBottomStatvalue, startDateFact);
|
||||
SetCell(sheet.Row(rowEndDatePlan), colBottomStatvalue, endDatePlan);
|
||||
SetCell(sheet.Row(rowEndDateFact), colBottomStatvalue, endDate);
|
||||
if (endDate != default)
|
||||
{
|
||||
var deltaEndDate = (endDatePlan - endDate).TotalDays;
|
||||
SetCell(sheet.Row(rowTopStatTitle + 1), colTopStatvalue, Math.Abs(deltaEndDate));
|
||||
if (deltaEndDate >= 0)
|
||||
SetCell(sheet.Row(rowTopStatTitle + 1), colTopStatvalue - 1, "+")
|
||||
.Style.Font.SetFontColor(XLColor.Green);
|
||||
else
|
||||
SetCell(sheet.Row(rowTopStatTitle + 1), colTopStatvalue - 1, "—")
|
||||
.Style.Font.SetFontColor(XLColor.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetColunmLetter(int columnNumber)
|
||||
{
|
||||
string letter = "";
|
||||
|
||||
while (columnNumber > 0)
|
||||
{
|
||||
int modulo = (columnNumber - 1) % 26;
|
||||
letter = Convert.ToChar('A' + modulo) + letter;
|
||||
columnNumber = (columnNumber - modulo) / 26;
|
||||
}
|
||||
|
||||
return letter;
|
||||
}
|
||||
|
||||
private static IXLStyle SetBorder(IXLStyle style)
|
||||
{
|
||||
style.Border.RightBorder = XLBorderStyleValues.Thin;
|
||||
style.Border.LeftBorder = XLBorderStyleValues.Thin;
|
||||
style.Border.TopBorder = XLBorderStyleValues.Thin;
|
||||
style.Border.BottomBorder = XLBorderStyleValues.Thin;
|
||||
style.Border.InsideBorder = XLBorderStyleValues.Thin;
|
||||
return style;
|
||||
}
|
||||
|
||||
private static IXLCell SetDateTime(IXLCell cell)
|
||||
{
|
||||
cell.DataType = XLDataType.DateTime;
|
||||
cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS";
|
||||
return cell;
|
||||
}
|
||||
|
||||
private static IXLCell SetNumber(IXLCell cell)
|
||||
{
|
||||
cell.DataType = XLDataType.Number;
|
||||
cell.Style.NumberFormat.Format = "0.00";
|
||||
return cell;
|
||||
}
|
||||
|
||||
private static IXLCell SetCell(IXLRow row, int colunm, object value)
|
||||
{
|
||||
var cell = row.Cell(colunm);
|
||||
cell.Value = value;
|
||||
|
||||
SetBorder(cell.Style);
|
||||
cell.Style.Alignment.WrapText = true;
|
||||
|
||||
if (value is string valueString && valueString.Length > maxChartsToWrap)
|
||||
{
|
||||
var baseHeight = row.Height;
|
||||
row.Height = 0.82d * baseHeight * Math.Ceiling(1d + valueString.Length / maxChartsToWrap);
|
||||
}
|
||||
|
||||
if (value is DateTime)
|
||||
{
|
||||
SetDateTime(cell);
|
||||
}
|
||||
else if (value is IFormattable)
|
||||
{
|
||||
SetNumber(cell);
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
112
AsbCloudWebApi/Controllers/DailyReportController.cs
Normal file
112
AsbCloudWebApi/Controllers/DailyReportController.cs
Normal file
@ -0,0 +1,112 @@
|
||||
using AsbCloudApp.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class DailyReportController : ControllerBase
|
||||
{
|
||||
private readonly IDailyReportService dailyReportService;
|
||||
|
||||
public DailyReportController(IDailyReportService dailyReportService)
|
||||
{
|
||||
this.dailyReportService = dailyReportService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Список наборов данных для формирования рапорта
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="begin"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <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)
|
||||
{
|
||||
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="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
//[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> AddAsync(int idWell, [Required] DailyReportDto dto, CancellationToken token = default)
|
||||
{
|
||||
var result = await dailyReportService.AddAsync(idWell, dto, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение изменений набора данных для формирования рапорта
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="date"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{date}")]
|
||||
//[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> UpdateAsync(int idWell, [Required] DateTime date, [Required] DailyReportDto dto, CancellationToken token = default)
|
||||
{
|
||||
var result = await dailyReportService.UpdateAsync(idWell, date, dto, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сформировать и скачать рапорт в формате excel
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <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)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
var stream = dailyReportService.MakeReportAsync();
|
||||
var fileName = "CP.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user