DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellService.cs

231 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache;
using Mapster;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services
{
public class WellService : CrudCacheServiceBase<WellDto, Well>, IWellService
{
private static readonly TypeAdapterConfig typeAdapterConfig = TypeAdapterConfig<WellDto, Well>
.NewConfig()
.Ignore(dst => dst.Cluster,
dst => dst.RelationCompaniesWells,
dst => dst.Telemetry,
dst => dst.WellComposites,
dst => dst.WellCompositeSrcs,
dst => dst.WellOperations,
dst => dst.WellType)
.Config;
private readonly ITelemetryService telemetryService;
private readonly CacheTable<RelationCompanyWell> cacheRelationCompaniesWells;
private readonly CacheTable<CompanyType> cacheCompanyWellTypes;
public ITelemetryService TelemetryService => telemetryService;
public WellService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService)
:base(db, cacheDb)
{
this.telemetryService = telemetryService;
cacheRelationCompaniesWells = cacheDb.GetCachedTable<RelationCompanyWell>((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well));
cacheCompanyWellTypes = cacheDb.GetCachedTable<CompanyType>((AsbCloudDbContext)db);
Includes.Add($"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}");
Includes.Add(nameof(Well.Telemetry));
Includes.Add($"{nameof(Well.RelationCompaniesWells)}.{nameof(RelationCompanyWell.Company)}");
Includes.Add(nameof(Well.WellType));
}
public DateTimeOffset GetLastTelemetryDate(int idWell)
{
var well = Cache.FirstOrDefault(w => w.Id == idWell);
if (well?.IdTelemetry is null)
return DateTimeOffset.MinValue;
var lastTelemetryDate = telemetryService.GetLastTelemetryDate((int)well.IdTelemetry);
return lastTelemetryDate;
}
public async Task<IEnumerable<WellDto>> GetWellsByCompanyAsync(int idCompany, CancellationToken token)
{
var relations = await cacheRelationCompaniesWells
.WhereAsync(r => r.IdCompany == idCompany, token);
var wellsIds = relations.Select(r => r.IdWell);
var wells = await Cache.WhereAsync(w => wellsIds.Contains(w.Id));
var dtos = wells.Select(Convert);
return dtos;
}
public override async Task<int> InsertAsync(WellDto dto, CancellationToken token = default)
{
if (dto.IdWellType is < 1 or > 2)
throw new ArgumentException("Тип скважины указан неправильно.", nameof(dto));
if (dto.IdState is < 0 or > 2)
throw new ArgumentException("Текущее состояние работы скважины указано неправильно.", nameof(dto));
if (dto.Id != 0 && await Cache.ContainsAsync(w => w.Id == dto.Id, token))
throw new ArgumentException($"Нельзя повторно добавить скважину с id: {dto.Id}", nameof(dto));
var entity = Convert(dto);
var result = await Cache.InsertAsync(entity, token);
if (dto.Companies.Any())
{
var newRelations = dto.Companies.Select(c => new RelationCompanyWell { IdWell = result.Id, IdCompany = c.Id });
await cacheRelationCompaniesWells.InsertAsync(newRelations, token);
}
return result.Id;
}
public override Task<int> InsertRangeAsync(IEnumerable<WellDto> dtos, CancellationToken token)
{
throw new NotImplementedException();
}
public override async Task<int> UpdateAsync(int idWell, WellDto dto,
CancellationToken token = default)
{
if (dto.IdWellType is < 1 or > 2)
throw new ArgumentException("Тип скважины указан неправильно.", nameof(dto));
if (dto.IdState is < 0 or > 2)
throw new ArgumentException("Текущее состояние работы скважины указано неправильно.", nameof(dto));
if(dto.Id != idWell)
throw new ArgumentException($"Нельзя поменять id для скважины: {idWell} => {dto.Id}.", nameof(dto));
var entity = Convert(dto);
var oldRelations = await cacheRelationCompaniesWells
.WhereAsync(r => r.IdWell == idWell, token);
if(dto.Companies.Count() != oldRelations.Count() ||
dto.Companies.Any(c => !oldRelations.Any(oldC => oldC.IdCompany == c.Id)))
{
await cacheRelationCompaniesWells.RemoveAsync(r => r.IdWell == idWell, token);
var newRelations = dto.Companies.Select(c=> new RelationCompanyWell {IdWell = idWell, IdCompany = c.Id });
await cacheRelationCompaniesWells.InsertAsync(newRelations, token);
}
var result = await Cache.UpsertAsync(entity, token);
return result;
}
public bool IsCompanyInvolvedInWell(int idCompany, int idWell)
=> cacheRelationCompaniesWells.Contains(r => r.IdWell == idWell && r.IdCompany == idCompany);
public async Task<bool> IsCompanyInvolvedInWellAsync(int idCompany, int idWell, CancellationToken token)
=> await cacheRelationCompaniesWells.ContainsAsync(r => r.IdWell == idWell &&
r.IdCompany == idCompany, token).ConfigureAwait(false);
public async Task<string> GetWellCaptionByIdAsync(int idWell, CancellationToken token)
{
var entity = await Cache.FirstOrDefaultAsync(w => w.Id == idWell, token).ConfigureAwait(false);
var dto = Convert(entity);
return dto.Caption;
}
public async Task<IEnumerable<CompanyDto>> GetCompaniesAsync(int idWell, CancellationToken token)
{
var relations = await cacheRelationCompaniesWells.WhereAsync(r => r.IdWell == idWell, token);
var dtos = relations.Select(r => Convert(r.Company));
return dtos;
}
private IEnumerable<CompanyDto> GetCompanies(int idWell)
{
var relations = cacheRelationCompaniesWells.Where(r => r.IdWell == idWell);
var dtos = relations.Select(r => Convert(r.Company));
return dtos;
}
public string GetStateText(int state)
{
return state switch
{
1 => "В работе",
2 => "Завершена",
_ => "Неизвестно",
};
}
public async Task<IEnumerable<int>> GetClusterWellsIdsAsync(int idWell, CancellationToken token)
{
var well = await Cache.FirstOrDefaultAsync(w => w.Id == idWell, token)
.ConfigureAwait(false);
if (well is null)
return null;
var clusterWells = await Cache.WhereAsync(w => w.IdCluster == well.IdCluster, token)
.ConfigureAwait(false);
return clusterWells.Select(w => w.Id);
}
protected override Well Convert(WellDto dto)
{
var entity = dto.Adapt<Well>(typeAdapterConfig);
//dto.WellType = entity.WellType?.Caption;
//dto.Cluster = entity.Cluster?.Caption;
//dto.Deposit = entity.Cluster?.Deposit?.Caption;
//dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id);
//dto.Companies = GetCompanies(entity.Id);
return entity;
}
protected override WellDto Convert(Well entity)
{
var dto = base.Convert(entity);
dto.WellType = entity.WellType?.Caption;
dto.Cluster = entity.Cluster?.Caption;
dto.Deposit = entity.Cluster?.Deposit?.Caption;
dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id).DateTime;
dto.Companies = GetCompanies(entity.Id);
return dto;
}
private CompanyDto Convert(Company entity)
{
var dto = entity.Adapt<CompanyDto>();
dto.CompanyTypeCaption = entity.CompanyType?.Caption
?? cacheCompanyWellTypes.FirstOrDefault(c => c.Id == entity.IdCompanyType).Caption;
return dto;
}
public DateTimeOffset DateToUtc(int idWell, DateTime date)
{
var GetTimeZoneOffset(int idWell)
}
public DateTime DateToTimeZone(DateTimeOffset date, double remoteTimezoneOffsetHours);
public double? GetTimeZoneOffset(int idWell)
{
// TODO: Add timeZoneOffset into Db.Well.
var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell);
if (idTelemetry is not null)
{
var timeZoneOffset = telemetryService.GetTimeZoneOffset((int)idTelemetry);
if (timeZoneOffset is not null)
return timeZoneOffset;
}
Trace.WriteLine("No timeZoneOffset");
return null;
}
}
}