using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Common.Interfaces.Doc;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
using EnvelopeGenerator.Application.DocReceiverElements.Queries;
using MediatR;
namespace EnvelopeGenerator.Application.PdfSigning;
///
///
///
public record SignPdfByElementCommand : IRequest
{
///
///
///
public DocReceiverElementDto? Element { get; set; }
///
///
///
public int? ElementId { get; init; }
}
///
///
///
///
public class SignPdfCommandHandler(ISender sender, IPdfDigitalSignatureService signService, IPdfPageImageRenderer imgRenderer) : IRequestHandler
{
///
///
///
///
///
///
public async Task Handle(SignPdfByElementCommand request, CancellationToken cancellationToken)
{
// ensure element
if(request.Element is null)
{
var elements = await sender.Send(new ReadDocReceiverElementQuery()
{
Id = request.ElementId!,
IncludeDocument= true
}, cancellationToken);
if (!elements.Any())
throw new NotFoundException($"Element with ID {request.ElementId} not found.");
request.Element = elements.FirstOrDefault();
}
// ensure document
var doc = request.Element!.Document;
if(doc is null || doc.ByteData is null || doc.ByteData.Length == 0)
throw new NotFoundException("Document data is missing or empty.");
// create signature image from element
var img = imgRenderer.ComposeSignaturePreviewPng(request.Element);
// sign pdf
var inputPdf = new MemoryStream(doc.ByteData);
var outputPdf = new MemoryStream();
await signService.SignPdfAsync(
inputPdf: inputPdf,
outputPdf: outputPdf,
options: new PdfSignOptionsDto
{
Appearance = new PdfSignatureAppearanceDto(
PageNumber: request.Element.Page,
Left: request.Element.Left,
Bottom: request.Element.Y,
Width: request.Element.Width,
Height: request.Element.Height)
},
image: img,
cancellationToken: cancellationToken);
return outputPdf;
}
}