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; } }