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 MessageService : IMessageService { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private readonly CacheTable cacheTelemetry; private readonly CacheTable cacheEvents; private readonly CacheTable cacheTUsers; public MessageService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService) { this.db = db; this.telemetryService = telemetryService; cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheEvents = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheTUsers = cacheDb.GetCachedTable((AsbCloudDbContext)db); } public async Task> GetMessagesAsync( int idWell, IEnumerable categoryids = default, DateTime begin = default, DateTime end = default, string searchString = default, int skip = 0, int take = 32, bool isUtc = true, CancellationToken token = default) { var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); if (idTelemetry is null) return null; var events = cacheEvents.Where(e => e.IdTelemetry == idTelemetry); if (!events.Any()) return null; var query = db.TelemetryMessages.Where(m => m.IdTelemetry == idTelemetry) .OrderBy(m => m.Date).AsNoTracking(); if ((categoryids?.Any() == true) || !string.IsNullOrEmpty(searchString)) { if (!string.IsNullOrEmpty(searchString)) events = events.Where(e => e.MessageTemplate.Contains(searchString, StringComparison.OrdinalIgnoreCase)); if (categoryids?.Any() == true) events = events.Where(e => categoryids.ToList().Contains(e.IdCategory)); var eventIds = events.Select(e => e.IdEvent); if (!eventIds.Any()) return null; query = query.Where(m => eventIds.Contains(m.IdEvent)); } query = query.OrderByDescending(m => m.Date); var timeOffset = await telemetryService.GetTelemetryTimeZoneOffsetAsync(idTelemetry??default, token) .ConfigureAwait(false); if (timeOffset is not null) { begin = telemetryService.TimeZoneService.DateToUtc(begin, timeOffset ?? default); end = telemetryService.TimeZoneService.DateToUtc(end, timeOffset ?? default); } if (begin != default) query = query.Where(m => m.Date >= begin); if (end != default) query = query.Where(m => m.Date <= end); var result = new PaginationContainer { Skip = skip, Take = take, Count = query.Count() }; if (skip > 0) query = query.Skip(skip); var messagesList = await query.Take(take).AsNoTracking() .ToListAsync(token).ConfigureAwait(false); if (messagesList.Count == 0) return result; var users = cacheTUsers.Where(u => u.IdTelemetry == idTelemetry); foreach (var message in messagesList) { var messageDto = new MessageDto { Date = message.Date, Id = message.Id, WellDepth = message.WellDepth }; if (message.IdTelemetryUser is not null) { if (users.Any()) { var user = users.FirstOrDefault(u => u.IdUser == message.IdTelemetryUser); messageDto.User = user.MakeDisplayName(); } else messageDto.User = message.IdTelemetryUser.ToString(); } var e = events.FirstOrDefault(e => e.IdEvent == message.IdEvent); if (e != null) { messageDto.CategoryId = e.IdCategory; messageDto.Message = e.MakeMessageText(message); } result.Items.Add(messageDto); } if (isUtc && timeOffset is not null) return result; result.Items = result.Items.Select(m => { m.Date = telemetryService.TimeZoneService.DateToTimeZone( m.Date, timeOffset ?? default); return m; }).ToList(); return result; } public async Task GetMessagesDatesRangeAsync(int idWell, bool isUtc, CancellationToken token = default) { var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); if (telemetryId is null) return null; var (From, To) = await db.GetDatesRangeAsync((int)telemetryId, token) .ConfigureAwait(false); var result = new DatesRangeDto { From = From, To = To }; if (isUtc) return result; result = await telemetryService.FixDatesRangeByTimeZoneAsync((int)telemetryId, result, token) .ConfigureAwait(false); return result; } public Task InsertAsync(string uid, IEnumerable dtos, CancellationToken token = default) { if (!dtos.Any()) return null; var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); var maxDateDto = dtos.Max(m => m.Date); telemetryService.SaveRequestDate(uid, maxDateDto); foreach (var dto in dtos) { var entity = dto.Adapt(); entity.Id = 0; entity.IdTelemetry = telemetryId; db.TelemetryMessages.Add(entity); } return db.SaveChangesAsync(token); } } }