179 lines
6.3 KiB
C#
179 lines
6.3 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class BurnPdfCommand : IRequest
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand>
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private readonly PDFBurnerParams _pdfBurnerParams;
|
|
|
|
private readonly AnnotationManager _manager;
|
|
|
|
private readonly IRepository<Signature> _signRepo;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="pdfBurnerParams"></param>
|
|
/// <param name="manager"></param>
|
|
/// <param name="signRepo"></param>
|
|
public BurnPdfCommandHandler(PDFBurnerParams pdfBurnerParams, AnnotationManager manager, IRepository<Signature> signRepo)
|
|
{
|
|
_pdfBurnerParams = pdfBurnerParams;
|
|
_manager = manager;
|
|
_signRepo = signRepo;
|
|
}
|
|
|
|
public byte[] BurnAnnotsToPDF(byte[] pSourceBuffer, List<string> 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);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="pSourceBuffer"></param>
|
|
/// <param name="elements"></param>
|
|
/// <returns></returns>
|
|
public byte[] BurnElementAnnotsToPDF(byte[] pSourceBuffer, List<Signature> 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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="pSourceBuffer"></param>
|
|
/// <param name="pInstantJSONList"></param>
|
|
/// <returns></returns>
|
|
public byte[] BurnInstantJSONAnnotsToPDF(byte[] pSourceBuffer, List<string> pInstantJSONList)
|
|
{
|
|
return Enumerable.Empty<byte>().ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
public Task Handle(BurnPdfCommand request, CancellationToken cancellationToken)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
} |