100 lines
3.5 KiB
C#
100 lines
3.5 KiB
C#
using AutoMapper;
|
|
using DigitalData.Core.Abstraction.Application.Repository;
|
|
using DigitalData.Core.Exceptions;
|
|
using EnvelopeGenerator.Application.Common.Dto;
|
|
using EnvelopeGenerator.Application.Common.Enums;
|
|
using EnvelopeGenerator.Application.Documents.Queries;
|
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
|
|
using EnvelopeGenerator.Application.Envelopes.Queries;
|
|
using EnvelopeGenerator.Domain.Entities;
|
|
using EnvelopeGenerator.Domain.Exceptions;
|
|
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace EnvelopeGenerator.Application.PdfSigning;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public record SignPdfByEnvelopeReceiverCommand : IRequest<Stream>
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int EnvelopeId { get; init; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int ReceiverId { get; init; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public Stream? Document { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class SignPdfByEnvelopeReceiverCommandHandler(IRepository<DocReceiverElement> Repo, IMapper Mapper, ISender Sender) : IRequestHandler<SignPdfByEnvelopeReceiverCommand, Stream>
|
|
{
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancel"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotFoundException"></exception>
|
|
public async Task<Stream> Handle(SignPdfByEnvelopeReceiverCommand request, CancellationToken cancel)
|
|
{
|
|
cancel.ThrowIfCancellationRequested();
|
|
|
|
// read elements
|
|
var elements = await Repo.Where(el => el.ReceiverId == request.ReceiverId && el.Document.EnvelopeId == request.EnvelopeId)
|
|
.Include(e => e.Receiver)
|
|
.ToListAsync(cancel) ?? throw new NotFoundException($"No elements found for Envelope ID {request.EnvelopeId} and Receiver ID {request.ReceiverId}.");
|
|
var elementDtos = Mapper.Map<List<DocReceiverElementDto>>(elements)
|
|
.OrderBy(e => e.Page)
|
|
.ThenBy(e => e.Id)
|
|
.ToList();
|
|
|
|
// read secrets for phone number
|
|
var erSecrets = await Sender.Send(new ReadEnvelopeReceiverSecretQuery()
|
|
{
|
|
Envelope = new() { Id = request.EnvelopeId },
|
|
Receiver = new() { Id = request.ReceiverId }
|
|
}, cancel) ?? throw new DataIntegrityException($"No secrets found for Envelope ID {request.EnvelopeId} and Receiver ID {request.ReceiverId}.");
|
|
|
|
// read document
|
|
if(request.Document is null)
|
|
{
|
|
var unsignedDoc = await Sender.Send(new ReadDocumentQuery(EnvelopeId: request.EnvelopeId), cancel);
|
|
var unsignedDocBytes = unsignedDoc.ByteData ?? throw new NotFoundException($"Document not found for Envelope ID {request.EnvelopeId} and Receiver ID {request.ReceiverId}.");
|
|
request.Document = new MemoryStream(unsignedDocBytes);
|
|
}
|
|
|
|
Stream doc = request.Document;
|
|
|
|
// sign document for each element
|
|
foreach (var element in elementDtos)
|
|
{
|
|
var lastElement = element == elementDtos.Last();
|
|
|
|
var signedDoc = await Sender.Send(new SignPdfByElementCommand
|
|
{
|
|
Document = doc,
|
|
Element = element,
|
|
CertificationLevel = lastElement ? PdfSignatureCertificationLevel.NoChangesAllowed : PdfSignatureCertificationLevel.FillFormsAndAnnotate,
|
|
Phone = erSecrets.PhoneNumber
|
|
}, cancel);
|
|
|
|
await doc.DisposeAsync();
|
|
doc = signedDoc;
|
|
}
|
|
|
|
return doc;
|
|
}
|
|
}
|