using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbSaubReport; using AsbSaubReportPdf; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class ReportService : IReportService { private readonly IAsbCloudDbContext db; private readonly IConfiguration configuration; private readonly ITelemetryService telemetryService; private readonly IFileService fileService; private readonly IBackgroundQueue queue; public ReportService(IAsbCloudDbContext db, IConfiguration configuration, ITelemetryService telemetryService, IFileService fileService, IBackgroundQueue queue) { this.db = db; this.configuration = configuration; this.telemetryService = telemetryService; this.fileService = fileService; this.queue = queue; ReportCategoryId = db.FileCategories.AsNoTracking() .FirstOrDefault(c => c.Name.Equals("Рапорт")).Id; } public int ReportCategoryId { get; private set; } public int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin, DateTime end, Action progressHandler, Action reportNameHandler) { var newReportId = queue.EnqueueTask((id) => { var optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseNpgsql(configuration.GetConnectionString("DefaultConnection")); using (var context = new AsbCloudDbContext(optionsBuilder.Options)) { var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, context); generator.OnProgress += (s, e) => progressHandler.Invoke(e.progress, e.operation, id); var newReportName = generator.Make(); if (newReportName is not null) { var shorReportName = Path.GetFileName(newReportName); reportNameHandler.Invoke(shorReportName, id); var newReportFile = new AsbCloudDb.Model.FileInfo { IdWell = idWell, IdAuthor = idUser, IdCategory = ReportCategoryId, Name = newReportName, UploadDate = DateTime.Now, }; context.Files.Add(newReportFile); context.SaveChanges(); var newReportProperties = new ReportProperties { IdWell = idWell, IdFile = newReportFile.Id, Begin = begin, End = end, Step = stepSeconds, Format = format }; context.ReportProperties.Add(newReportProperties); context.SaveChanges(); } } }); return newReportId; } public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) { var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, (AsbCloudDbContext)db); return generator.GetPagesCount(); } public async Task> GetSuitableReportsAsync(int idWell, DateTime begin, DateTime end, int stepSeconds, int format, CancellationToken token = default) { var suitableReportsFromDb = await GetSuitableReportsFromDbAsync(idWell, begin, end, stepSeconds, format, token).ConfigureAwait(false); var suitableReportsProperties = suitableReportsFromDb.Select(r => new ReportPropertiesDto { Id = r.Id, Name = Path.GetFileName(r.File.Name), FullName = r.File.Name, IdWell = r.IdWell, Date = r.File.UploadDate, Begin = r.Begin, End = r.End, Step = r.Step, Format = r.Format == 0 ? ".pdf" : ".las" }); return suitableReportsProperties; } public async Task GetReportsDatesRangeAsync(int idWell, CancellationToken token = default) { var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); if (telemetryId is null) return null; var datesRange = await (from d in db.DataSaubBases where d.IdTelemetry == telemetryId select d.Date).Union( from m in db.TelemetryMessages where m.IdTelemetry == telemetryId select m.Date).DefaultIfEmpty() .GroupBy(g => true) .AsNoTracking() .Select(g => new { From = g.Min(), To = g.Max() }).OrderBy(gr => gr.From) .FirstOrDefaultAsync(token) .ConfigureAwait(false); return new DatesRangeDto { From = datesRange.From, To = datesRange.To.Year == 1 ? DateTime.MaxValue : datesRange.To }; } private async Task> GetSuitableReportsFromDbAsync(int idWell, DateTime begin, DateTime end, int stepSeconds, int format, CancellationToken token = default) { var suitableReportsNames = await(from r in db.ReportProperties.Include(r => r.File) where r.IdWell == idWell && r.Begin >= begin && r.End <= end && r.Step <= stepSeconds && r.Format == format select r).OrderBy(o => o.File.UploadDate) .AsNoTracking() .Take(512).ToListAsync(token) .ConfigureAwait(false); return suitableReportsNames; } private IReportGenerator GetReportGenerator(int idWell, DateTime begin, DateTime end, int stepSeconds, int format, AsbCloudDbContext context) { var dataSource = new ReportDataSourcePgCloud(context, idWell); IReportGenerator generator; switch (format) { case 1: //LAS generator = new AsbSaubReportLas.LasReprotGenerator(dataSource); break; case 0: //PDF default: generator = new PdfReprotGenerator(dataSource); break; } generator.ReportDirectory = Path.Combine(fileService.RootPath, $"{idWell}", $"{ReportCategoryId}"); generator.Begin = begin; generator.End = end; generator.Step = TimeSpan.FromSeconds(stepSeconds); generator.WithCharts = true; generator.WithEvents = true; return generator; } } }