using System.Data; using System.IO; using EnvelopeGenerator.Domain.Entities; using iText.Kernel.Pdf; using iText.Layout.Element; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions; using LayoutDocument = iText.Layout.Document; namespace EnvelopeGenerator.Jobs.FinalizeDocument; public class ReportCreator { private readonly ILogger _logger; public ReportCreator() : this(NullLogger.Instance) { } public ReportCreator(ILogger logger) { _logger = logger; } public byte[] CreateReport(SqlConnection connection, Envelope envelope) { try { var reportItems = LoadReportItems(connection, envelope.Id); using var stream = new MemoryStream(); using var writer = new PdfWriter(stream); using var pdf = new PdfDocument(writer); using var document = new LayoutDocument(pdf); document.Add(new Paragraph("Envelope Finalization Report").SetFontSize(16)); document.Add(new Paragraph($"Envelope Id: {envelope.Id}")); document.Add(new Paragraph($"UUID: {envelope.Uuid}")); document.Add(new Paragraph($"Title: {envelope.Title}")); document.Add(new Paragraph($"Subject: {envelope.Comment}")); document.Add(new Paragraph($"Generated: {DateTime.UtcNow:O}")); document.Add(new Paragraph(" ")); var table = new Table(4).UseAllAvailableWidth(); table.AddHeaderCell("Date"); table.AddHeaderCell("Status"); table.AddHeaderCell("User"); table.AddHeaderCell("EnvelopeId"); foreach (var item in reportItems.OrderByDescending(r => r.ItemDate)) { table.AddCell(item.ItemDate.ToString("u")); table.AddCell(item.ItemStatus.ToString()); table.AddCell(item.ItemUserReference); table.AddCell(item.EnvelopeId.ToString()); } document.Add(table); document.Close(); return stream.ToArray(); } catch (Exception ex) { _logger.LogError(ex, "Could not create report for envelope {EnvelopeId}", envelope.Id); throw new CreateReportException("Could not prepare report data", ex); } } private List LoadReportItems(SqlConnection connection, int envelopeId) { const string sql = "SELECT ENVELOPE_ID, POS_WHEN, POS_STATUS, POS_WHO FROM VWSIG_ENVELOPE_REPORT WHERE ENVELOPE_ID = @EnvelopeId"; var result = new List(); using var command = new SqlCommand(sql, connection); command.Parameters.AddWithValue("@EnvelopeId", envelopeId); using var reader = command.ExecuteReader(); while (reader.Read()) { result.Add(new ReportItem { EnvelopeId = reader.GetInt32(0), ItemDate = reader.IsDBNull(1) ? DateTime.MinValue : reader.GetDateTime(1), ItemStatus = reader.IsDBNull(2) ? default : (EnvelopeGenerator.Domain.Constants.EnvelopeStatus)reader.GetInt32(2), ItemUserReference = reader.IsDBNull(3) ? string.Empty : reader.GetString(3) }); } return result; } }