using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbSaubReport; 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 IBackgroundQueue queue; public ReportService(IAsbCloudDbContext db, IConfiguration configuration, ITelemetryService telemetryService, IBackgroundQueue queue) { this.db = db; this.configuration = configuration; this.telemetryService = telemetryService; this.queue = queue; RootPath = "reports"; } public string RootPath { get; private set; } public int CreateReport(int wellId, 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(wellId, 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 newReportProperties = new Report { Name = newReportName, IdWell = wellId, Date = DateTime.Now, Begin = begin, End = end, Step = stepSeconds, Format = format }; context.Reports.Add(newReportProperties); context.SaveChanges(); } } }); return newReportId; } public int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format) { var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format, (AsbCloudDbContext)db); return generator.GetPagesCount(); } public IEnumerable GetSuitableReports(int wellId, DateTime begin, DateTime end, int stepSeconds, int format) { var suitableReportsFromDb = GetSuitableReportsFromDb(wellId, begin, end, stepSeconds, format); var suitableReportsProperties = suitableReportsFromDb.Select(r => new ReportPropertiesDto { Id = r.Id, Name = Path.GetFileName(r.Name), FullName = r.Name, WellId = r.IdWell, Date = r.Date, Begin = r.Begin, End = r.End, Step = r.Step, Format = r.Format == 0 ? ".pdf" : ".las" }); return suitableReportsProperties; } public DatesRangeDto GetReportsDatesRange(int wellId) { var telemetry = telemetryService.GetTelemetryByWellId(wellId); if (telemetry is null) return null; var datesRange = (from d in db.DataSaubBases where d.IdTelemetry == telemetry.Id select d.Date).Union( from m in db.Messages where m.IdTelemetry == telemetry.Id 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 wellId, DateTime begin, DateTime end, int stepSeconds, int format) { var suitableReportsNames = (from r in db.Reports where r.IdWell == wellId && r.Begin >= begin && r.End <= end && r.Step <= stepSeconds && r.Format == format select r).OrderBy(o => o.Date).Take(512).ToList(); return suitableReportsNames; } private IReportGenerator GetReportGenerator(int wellId, DateTime begin, DateTime end, int stepSeconds, int format, AsbCloudDbContext context) { var dataSource = new ReportDataSourcePgCloud(context, wellId); var generator = new PdfGenerator(dataSource) { ReportDirectory = Path.Combine(RootPath, $"{wellId}"), Begin = begin, End = end, Step = TimeSpan.FromSeconds(stepSeconds), WithCharts = true, WithEvents = true }; switch (format) { case 0: return generator; case 1: return generator; default: return generator; } } } }