diff --git a/AsbCloudApp/Data/WellDto.cs b/AsbCloudApp/Data/WellDto.cs
index d88aa631..c1b9a22b 100644
--- a/AsbCloudApp/Data/WellDto.cs
+++ b/AsbCloudApp/Data/WellDto.cs
@@ -50,6 +50,11 @@ namespace AsbCloudApp.Data
///
public int IdState { get; set; }
+ ///
+ /// Дата/время первой операции
+ ///
+ public DateTime? StartDate { get; set; }
+
///
/// Дата/время кода приходили данные последний раз
///
diff --git a/AsbCloudApp/Services/IWellOperationService.cs b/AsbCloudApp/Services/IWellOperationService.cs
index 475ea9bd..d3d3a310 100644
--- a/AsbCloudApp/Services/IWellOperationService.cs
+++ b/AsbCloudApp/Services/IWellOperationService.cs
@@ -33,5 +33,6 @@ namespace AsbCloudApp.Services
Task DeleteAsync(IEnumerable ids, CancellationToken token);
IDictionary GetSectionTypes();
+ DateTimeOffset? FirstOperationDate(int idWell);
}
}
diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs
index b552717e..55979e96 100644
--- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs
+++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs
@@ -19,6 +19,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
private readonly CacheTable cachedOperationCategories;
private readonly CacheTable cachedSectionTypes;
+ private Dictionary? firstOperationsCache = null;
+
public const int idOperationBhaAssembly = 1025;
public const int idOperationBhaDisassembly = 1026;
public const int idOperationNonProductiveTime = 1043;
@@ -49,6 +51,26 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return result;
}
+ public DateTimeOffset? FirstOperationDate(int idWell)
+ {
+ if(firstOperationsCache is null)
+ {
+ var query = db.WellOperations
+ .GroupBy(o => o.IdWell)
+ .Select(g => new Tuple
+ (
+ g.Key,
+ g.Where(o => o.IdType == idOperationTypePlan).Min(o => o.DateStart),
+ g.Where(o => o.IdType == idOperationTypeFact).Min(o => o.DateStart)
+ ));
+
+ firstOperationsCache = query
+ .ToDictionary(f => f.Item1, f => f.Item3 ?? f.Item2);
+ }
+
+ return firstOperationsCache?.GetValueOrDefault(idWell);
+ }
+
public async Task> GetOperationsAsync(
int idWell,
int? operationType = default,
diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs
index ebe5ca84..44085c81 100644
--- a/AsbCloudInfrastructure/Services/WellService.cs
+++ b/AsbCloudInfrastructure/Services/WellService.cs
@@ -29,6 +29,7 @@ namespace AsbCloudInfrastructure.Services
private readonly CacheTable cacheRelationCompaniesWells;
private readonly CacheTable cacheCompanyWellTypes;
private readonly ITimezoneService timezoneService;
+ private readonly Lazy wellOperationService;
public ITelemetryService TelemetryService => telemetryService;
@@ -37,6 +38,7 @@ namespace AsbCloudInfrastructure.Services
{
this.telemetryService = telemetryService;
this.timezoneService = timezoneService;
+ this.wellOperationService = new Lazy(() => new WellOperationService.WellOperationService(db, cacheDb, this));
cacheRelationCompaniesWells = cacheDb.GetCachedTable((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well));
cacheCompanyWellTypes = cacheDb.GetCachedTable((AsbCloudDbContext)db);
Includes.Add($"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}");
@@ -48,7 +50,7 @@ namespace AsbCloudInfrastructure.Services
public DateTimeOffset GetLastTelemetryDate(int idWell)
{
var well = Cache.FirstOrDefault(w => w.Id == idWell);
-
+
if (well?.IdTelemetry is null)
return DateTimeOffset.MinValue;
@@ -63,7 +65,7 @@ namespace AsbCloudInfrastructure.Services
var wellsIds = relations.Select(r => r.IdWell);
var wells = await Cache.WhereAsync(w => wellsIds.Contains(w.Id), token);
-
+
var dtos = wells.Select(Convert);
return dtos;
}
@@ -202,6 +204,7 @@ namespace AsbCloudInfrastructure.Services
if (TryGetTimezone(entity, out var timezone))
dto.Timezone = timezone;
+ dto.StartDate = wellOperationService.Value.FirstOperationDate(entity.Id)?.ToRemoteDateTime(dto.Timezone.Hours);
dto.WellType = entity.WellType?.Caption;
dto.Cluster = entity.Cluster?.Caption;
dto.Deposit = entity.Cluster?.Deposit?.Caption;
diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs
index fe92aa60..33142088 100644
--- a/ConsoleApp1/Program.cs
+++ b/ConsoleApp1/Program.cs
@@ -6,21 +6,35 @@ using System.Linq;
namespace ConsoleApp1
{
+ class Cron
+ {
+ public DateTimeOffset Origin { get; set; }
+ public TimeSpan Period { get; set; }
+
+ public DateTimeOffset Next()
+ {
+ var delta = DateTimeOffset.Now - Origin;
+ var n = Math.Ceiling(delta / Period);
+ return Origin + n * Period;
+ }
+ }
+
class Program
{
static void Main(/*string[] args*/)
{
// use ServiceFactory to make services
- var db = ServiceFactory.Context;
- //var d = db.TelemetryDataSaubStats.ToList();
+ var op = ServiceFactory.MakeWellOperationsService();
+ var d = op.FirstOperationDate(90);
- //db.RefreshMaterializedViewAsync().Wait();
+ var period = TimeSpan.FromHours(5);
+ var c = new Cron
+ {
+ Period = period,
+ Origin = new DateTimeOffset(2022, 5, 8, 0, 0, 7, TimeSpan.FromHours(5)),
+ };
- var d = db.WellSectionTypes
- .Include(e => e.DrillParamsCollection)
- .Include(e => e.WellComposites)
- .Include(e => e.WellOperations)
- .ToList();
+ Console.WriteLine($"origin: {c.Origin} next: {c.Next()}");
Console.WriteLine("End of Test");
Console.ReadLine();
diff --git a/ConsoleApp1/ServiceFactory.cs b/ConsoleApp1/ServiceFactory.cs
index b71f727e..41cbd9a8 100644
--- a/ConsoleApp1/ServiceFactory.cs
+++ b/ConsoleApp1/ServiceFactory.cs
@@ -70,6 +70,9 @@ namespace ConsoleApp1
public static WellService MakeWellService()
=> new WellService(Context, CacheDb, MakeTelemetryService(), TimezoneService);
+ public static WellOperationService MakeWellOperationsService()
+ => new WellOperationService(Context, CacheDb, MakeWellService());
+
public static OperationsStatService MakeOperationsStatService()
=> new OperationsStatService(Context, CacheDb, MakeWellService());