using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Mapster; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class WellService : IWellService { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private readonly CacheTable cacheRelationCompaniesWells; private readonly CacheTable cacheWells; public WellService(IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb) { this.db = db; this.telemetryService = telemetryService; cacheRelationCompaniesWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); } public DateTime GetLastTelemetryDate(int idWell) { var well = cacheWells.FirstOrDefault(w => w.Id == idWell); if (well?.IdTelemetry is null) return DateTime.MinValue; var lastTelemetryDate = telemetryService.GetLastTelemetryDate((int)well.IdTelemetry); return lastTelemetryDate; } public async Task> GetTransmittingWellsAsync(int idCompany, CancellationToken token) { var activeTelemetryIds = telemetryService.GetTransmittingTelemetriesAsync(idCompany) .Select(t => t.Id); var wells = await (from w in db.GetWellsForCompany(idCompany) where w.IdTelemetry != null && activeTelemetryIds.Contains((int)w.IdTelemetry) select w) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); return wells.Select(Convert); } public async Task> GetWellsByCompanyAsync(int idCompany, CancellationToken token) { var wells = await db.GetWellsForCompany(idCompany).ToListAsync(token); return wells.Select(Convert); } public async Task UpdateWellAsync(int idWell, WellParamsDto 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)); var entity = await db.Wells .FirstOrDefaultAsync(w => w.Id == idWell, token) .ConfigureAwait(false); if (entity is null) throw new ArgumentException("Тип секции указан неправильно.", nameof(idWell)); entity.Caption = dto.Caption; entity.Latitude = dto.Latitude; entity.Longitude = dto.Longitude; entity.IdWellType = dto.IdWellType; entity.IdState = dto.IdState; db.Wells.Update(entity); return await db.SaveChangesAsync(token); } public bool IsCompanyInvolvedInWell(int idCompany, int idWell) => cacheRelationCompaniesWells.Contains(r => r.IdWell == idWell && r.IdCompany == idCompany); public async Task IsCompanyInvolvedInWellAsync(int idCompany, int idWell, CancellationToken token) => await cacheRelationCompaniesWells.ContainsAsync(r => r.IdWell == idWell && r.IdCompany == idCompany, token).ConfigureAwait(false); public async Task GetAsync(int idWell, CancellationToken token) { var entity = await db.Wells .Include(w => w.Cluster) .ThenInclude(c => c.Deposit) .FirstOrDefaultAsync(w => w.Id == idWell, token) .ConfigureAwait(false); if (entity is null) return null; var dto = Convert(entity); return dto; } public async Task GetWellCaptionByIdAsync(int idWell, CancellationToken token) { var entity = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token).ConfigureAwait(false); var dto = Convert(entity); return dto.Caption; } public async Task> GetCompaniesAsync(int idWell, CancellationToken token) { var well = await db.Wells .Include(w => w.RelationCompaniesWells) .ThenInclude(r => r.Company) .FirstOrDefaultAsync(w => w.Id == idWell, token) .ConfigureAwait(false); var companies = well.RelationCompaniesWells.Select(r => r.Company); return companies.Adapt(); } public string GetStateText(int state) { return state switch { 1 => "В работе", 2 => "Завершена", _ => "Незвестно", }; } private WellDto Convert(Well well) { return new WellDto { Id = well.Id, Caption = well.Caption, Cluster = well.Cluster?.Caption, Deposit = well.Cluster?.Deposit?.Caption, LastTelemetryDate = GetLastTelemetryDate(well.Id), IdWellType = well.IdWellType ?? default, IdState = well.IdState, Latitude = well.Latitude, Longitude = well.Longitude, }; } } }