using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Exceptions; using EnvelopeGenerator.Application.Common.Query; using EnvelopeGenerator.Domain.Entities; using MediatR; using Microsoft.EntityFrameworkCore; namespace EnvelopeGenerator.Application.PdfSigning; /// /// /// public record SignPdfByEnvelopeCommand : EnvelopeQueryBase, IRequest { /// /// /// public int? ReceiverId { get; init; } = null; internal int? UserId { get; private set; } = null; /// /// /// /// /// public SignPdfByEnvelopeCommand Authorized(int userId) { UserId = userId; return this; } } /// /// /// public class SignPdfByEnvelopeCommandHandler(IRepository Repo, ISender sender) : IRequestHandler { /// /// /// /// /// /// /// public async Task Handle(SignPdfByEnvelopeCommand request, CancellationToken cancel) { var envelopeQuery = Repo.Query; if (request.Id is int id) envelopeQuery = envelopeQuery.Where(e => e.Id == id); else if (request.Uuid is string uuid) envelopeQuery = envelopeQuery.Where(e => e.Uuid == uuid); var envelope = await envelopeQuery.Include(e => e.EnvelopeReceivers).Include(e => e.Documents).SingleOrDefaultAsync(cancel) ?? throw new NotFoundException($"Envelope is not found ID: {request.Id} UUID: {request.Uuid}"); if (request.UserId is int userId && userId != envelope.UserId) throw new UnauthorizedAccessException($"Envelope is not authorized for user with Id: {request.UserId} Envelope ID: {request.Id} UUID: {request.Uuid}"); if (envelope.EnvelopeReceivers.Count == 0) throw new NotFoundException($"Envelope has no receivers to sign ID: {request.Id} UUID: {request.Uuid}"); if(envelope.Documents.FirstOrDefault() is not Document document || document.ByteData is not byte[] byteData || byteData.Length == 0) throw new NotFoundException($"Envelope has no documents to sign ID: {request.Id} UUID: {request.Uuid}"); Stream doc = new MemoryStream(byteData); var eReceivers = request.ReceiverId is int receiverId ? envelope.EnvelopeReceivers.Where(e => e.ReceiverId == receiverId) : envelope.EnvelopeReceivers; foreach (var eReceiver in eReceivers) { var signedDoc = await sender.Send(new SignPdfByEnvelopeReceiverCommand() { EnvelopeId = eReceiver.EnvelopeId, ReceiverId = eReceiver.ReceiverId }, cancel); await doc.DisposeAsync(); doc = signedDoc; } return doc; } }