using DigitalData.Core.Abstraction.Application.Repository; using EnvelopeGenerator.Application.Common.Configurations; using EnvelopeGenerator.Application.Exceptions; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.PdfEditor; using GdPicture14; using MediatR; using Microsoft.EntityFrameworkCore; namespace EnvelopeGenerator.Application.Pdf; /// /// /// public class BurnPdfCommand : IRequest { } /// /// /// public class BurnPdfCommandHandler : IRequestHandler { /// /// /// private readonly PDFBurnerParams _pdfBurnerParams; private readonly AnnotationManager _manager; private readonly IRepository _signRepo; /// /// /// /// /// /// public BurnPdfCommandHandler(PDFBurnerParams pdfBurnerParams, AnnotationManager manager, IRepository signRepo) { _pdfBurnerParams = pdfBurnerParams; _manager = manager; _signRepo = signRepo; } public byte[] BurnAnnotsToPDF(byte[] pSourceBuffer, List pInstantJSONList, int envelopeId) { // read the elements of envelope with their annotations var elements = _signRepo .Where(sig => sig.Document.EnvelopeId == envelopeId) .Include(sig => sig.Annotations) .ToList(); return elements.Any() ? BurnElementAnnotsToPDF(pSourceBuffer, elements) : BurnInstantJSONAnnotsToPDF(pSourceBuffer, pInstantJSONList); } /// /// /// /// /// /// public byte[] BurnElementAnnotsToPDF(byte[] pSourceBuffer, List elements) { // Add background using (var doc = PdfEditor.Pdf.FromMemory(pSourceBuffer)) { // TODO: take the length from the largest y pSourceBuffer = doc.Background(elements, 1.9500000000000002 * 0.93, 2.52 * 0.67) .ExportStream() .ToArray(); GdPictureStatus oResult; using (var oSourceStream = new MemoryStream(pSourceBuffer)) { // Open PDF oResult = _manager.InitFromStream(oSourceStream); if (oResult != GdPictureStatus.OK) throw new BurnAnnotationException($"Could not open document for burning: [{oResult}]"); // Imported from background (add to configuration) double margin = 0.2; double inchFactor = 72; // Y offset of form fields var keys = new[] { "position", "city", "date" }; // add to configuration double unitYOffsets = 0.2; var yOffsetsOfFF = keys .Select((k, i) => new { Key = k, Value = unitYOffsets * i + 1 }) .ToDictionary(x => x.Key, x => x.Value); // Add annotations foreach (var element in elements) { double frameX = element.Left - 0.7 - margin; var frame = element.Annotations?.FirstOrDefault(a => a.Name == "frame"); double frameY = element.Top - 0.5 - margin; double frameYShift = frame.Y - frameY * inchFactor; double frameXShift = frame.X - frameX * inchFactor; foreach (var annot in element.Annotations) { double yOffsetofFF; if (!yOffsetsOfFF.TryGetValue(annot.Name, out yOffsetofFF)) yOffsetofFF = 0; double y = frameY + yOffsetofFF; if (annot.Type == AnnotationType.FormField) { AddFormFieldValue( annot.X / inchFactor, y, annot.Width / inchFactor, annot.Height / inchFactor, element.Page, annot.Value ); } else if (annot.Type == AnnotationType.Image) { AddImageAnnotation( annot.X / inchFactor, annot.Name == "signature" ? (annot.Y - frameYShift) / inchFactor : y, annot.Width / inchFactor, annot.Height / inchFactor, element.Page, annot.Value ); } else if (annot.Type == AnnotationType.Ink) { AddInkAnnotation(element.Page, annot.Value); } } } // Save PDF using (var oNewStream = new MemoryStream()) { oResult = _manager.SaveDocumentToPDF(oNewStream); if (oResult != GdPictureStatus.OK) throw new BurnAnnotationException($"Could not save document to stream: [{oResult}]"); _manager.Close(); return oNewStream.ToArray(); } } } } /// /// /// /// /// /// public byte[] BurnInstantJSONAnnotsToPDF(byte[] pSourceBuffer, List pInstantJSONList) { return Enumerable.Empty().ToArray(); } /// /// /// /// /// /// /// public Task Handle(BurnPdfCommand request, CancellationToken cancellationToken) { throw new NotImplementedException(); } }