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; 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.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.File { IdWell = idWell, IdAuthor = idUser, IdCategory = ReportCategoryId, Name = newReportName, Date = 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 IEnumerable GetSuitableReports(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) { var suitableReportsFromDb = GetSuitableReportsFromDb(idWell, begin, end, stepSeconds, format); 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.Date, Begin = r.Begin, End = r.End, Step = r.Step, Format = r.Format == 0 ? ".pdf" : ".las" }); return suitableReportsProperties; } public DatesRangeDto GetReportsDatesRange(int idWell) { var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); if (telemetryId is null) return null; var datesRange = (from d in db.DataSaubBases where d.IdTelemetry == telemetryId select d.Date).Union( from m in db.Messages where m.IdTelemetry == telemetryId select m.Date).DefaultIfEmpty().GroupBy(g => true) .Select(g => new { From = g.Min(), To = g.Max() }).OrderBy(gr => gr.From).FirstOrDefault(); return new DatesRangeDto { From = datesRange.From, To = datesRange.To.Year == 1 ? DateTime.MaxValue : datesRange.To }; } private IEnumerable GetSuitableReportsFromDb(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) { var suitableReportsNames = (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.Date) .Take(512).ToList(); 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; } } }