using AsbCloudApp.Data; using AsbCloudApp.Data.SAUB; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; using AsbCloudInfrastructure.EfCache; using Mapster; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { public class MessageService : IMessageService { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; public MessageService(IAsbCloudDbContext db, ITelemetryService telemetryService) { this.db = db; this.telemetryService = telemetryService; } public async Task> GetMessagesAsync(MessageRequest request, CancellationToken token) { var idTelemetry = telemetryService.GetOrDefaultIdTelemetryByIdWell(request.IdWell); if (idTelemetry is null) return null; var allEvents = await db.TelemetryEvents.FromCacheAsync(token); var events = allEvents.Where(e => e.IdTelemetry == idTelemetry); if (!events.Any()) return null; var query = db.TelemetryMessages.Where(m => m.IdTelemetry == idTelemetry) .OrderBy(m => m.DateTime).AsNoTracking(); if (request.Categoryids?.Any() == true || !string.IsNullOrEmpty(request.SearchString)) { if (!string.IsNullOrEmpty(request.SearchString)) events = events.Where(e => e.MessageTemplate.Contains(request.SearchString, StringComparison.OrdinalIgnoreCase)); if (request.Categoryids?.Any() == true) events = events.Where(e => request.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.DateTime); var timezone = telemetryService.GetTimezone(idTelemetry ?? default); if (request.Begin != default) { var beginUtc = request.Begin.Value.ToUtcDateTimeOffset(timezone.Hours); query = query.Where(m => m.DateTime >= beginUtc); } if (request.End != default) { var endUtc = request.End.Value.ToUtcDateTimeOffset(timezone.Hours); query = query.Where(m => m.DateTime <= endUtc); } var result = new PaginationContainer { Skip = request.Skip ?? 0, Take = request.Take ?? 32, Count = query.Count() }; if (request.SortFields?.Any() == true) { query = query.SortBy(request.SortFields); } var messagesList = await query.Skip(request.Skip ?? 0) .Take(request.Take ?? 32).AsNoTracking() .ToListAsync(token).ConfigureAwait(false); if (messagesList.Count == 0) return result; var allUsers = await db.TelemetryUsers.FromCacheAsync(token); var users = allUsers.Where(u => u.IdTelemetry == idTelemetry); var eventsDict = events.GroupBy(x => x.IdEvent).ToDictionary(x => x.Key, x => x.FirstOrDefault()); var usersDict = users.GroupBy(x => x.IdUser).ToDictionary(x => x.Key, x => x.FirstOrDefault()); foreach (var message in messagesList) { var messageDto = new MessageDto { Id = message.Id, WellDepth = message.WellDepth }; messageDto.Date = message.DateTime.ToRemoteDateTime(timezone.Hours); if (message.IdTelemetryUser is not null) { if (usersDict.TryGetValue((int)message.IdTelemetryUser, out TelemetryUser user)) { messageDto.User = user.MakeDisplayName(); } else messageDto.User = message.IdTelemetryUser.ToString(); } if (eventsDict.TryGetValue(message.IdEvent, out TelemetryEvent e)) { messageDto.CategoryId = e.IdCategory; messageDto.Message = e.MakeMessageText(message); } result.Items.Add(messageDto); } return result; } public Task InsertAsync(string uid, IEnumerable dtos, CancellationToken token = default) { if (!dtos.Any()) return null; var telemetryId = telemetryService.GetOrCreateTelemetryIdByUid(uid); var timezone = telemetryService.GetTimezone(telemetryId); foreach (var dto in dtos) { var entity = dto.Adapt(); entity.Id = 0; entity.IdTelemetry = telemetryId; entity.DateTime = dto.Date.ToUtcDateTimeOffset(timezone.Hours); db.TelemetryMessages.Add(entity); } return db.SaveChangesAsync(token); } } }