diff --git a/EnvelopeGenerator.Application/Envelopes/Queries/ReadSignedEnvelopeQuery.cs b/EnvelopeGenerator.Application/Envelopes/Queries/ReadSignedEnvelopeQuery.cs new file mode 100644 index 00000000..80f196ea --- /dev/null +++ b/EnvelopeGenerator.Application/Envelopes/Queries/ReadSignedEnvelopeQuery.cs @@ -0,0 +1,62 @@ +using AutoMapper; +using DigitalData.Core.Abstraction.Application.Repository; +using EnvelopeGenerator.Application.Common.Dto; +using EnvelopeGenerator.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace EnvelopeGenerator.Application.Envelopes.Queries; + +/// +/// +/// +public record ReadSignedEnvelopeQuery : IRequest> +{ + /// + /// + /// + public bool? Burned { get; init; } = null; + + internal int? UserId { get; private set; } = null; + + /// + /// + /// + /// + /// + public ReadSignedEnvelopeQuery Authorized(int userId) + { + UserId = userId; + return this; + } +} + +/// +/// +/// +/// +/// +public class ReadSignedEnvelopeQueryHandler(IRepository Repo, IMapper Mapper) : IRequestHandler> +{ + /// + /// + /// + /// + /// + /// + /// + public async Task> Handle(ReadSignedEnvelopeQuery request, CancellationToken cancel) + { + var eQuery = Repo.Query.Where(e => e.Status == Domain.Constants.EnvelopeStatus.EnvelopeCompletelySigned); + + if (request.Burned is bool burned) + eQuery = burned ? eQuery.Where(e => e.DocResult != null) : eQuery.Where(e => e.DocResult == null); + + if(request.UserId is int userId) + eQuery = eQuery.Where(e => e.UserId == userId); + + var envelopes = await eQuery.ToListAsync(cancel); + + return Mapper.Map>(envelopes); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/PdfSigning/FinalizeEnvelopeCommand.cs b/EnvelopeGenerator.Application/PdfSigning/FinalizeEnvelopeCommand.cs new file mode 100644 index 00000000..67ac39a5 --- /dev/null +++ b/EnvelopeGenerator.Application/PdfSigning/FinalizeEnvelopeCommand.cs @@ -0,0 +1,107 @@ +using DigitalData.Core.Abstraction.Application.Repository; +using DigitalData.Core.Exceptions; +using EnvelopeGenerator.Application.Common.Interfaces.Services.Notification; +using EnvelopeGenerator.Application.Common.Query; +using EnvelopeGenerator.Domain.Constants; +using EnvelopeGenerator.Domain.Entities; +using EnvelopeGenerator.Domain.Interfaces; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace EnvelopeGenerator.Application.PdfSigning; + +/// +/// +/// +public record FinalizeEnvelopeCommand : EnvelopeQueryBase, IRequest +{ + internal int? UserId { get; private set; } = null; + + /// + /// + /// + /// + /// + public FinalizeEnvelopeCommand Authorized(int userId) + { + UserId = userId; + return this; + } + + /// + /// + /// + public bool BurnedAllowed { get; init; } = false; + + /// + /// + /// + public bool SaveDocResult { get; init; } = true; +} + +/// +/// +/// +/// +/// +public class FinalizeEnvelopeCommandHandler(IRepository Repo, ISender Sender, IEnvelopeNotificationService NtfServer) : IRequestHandler +{ + /// + /// + /// + /// + /// + /// + /// + public async Task Handle(FinalizeEnvelopeCommand 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).ThenInclude(er => er.Receiver) + .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 InvalidOperationException($"Envelope is not owned by user ID: {request.Id} UUID: {request.Uuid}"); + + // already burned + if (!request.BurnedAllowed && envelope.IsBurned()) + throw new InvalidOperationException($"Envelope is already burned ID: {request.Id} UUID: {request.Uuid}"); + + // envelope is not completely signed + if (envelope.Status!= EnvelopeStatus.EnvelopeCompletelySigned) + throw new InvalidOperationException($"Envelope status is not completely signed ID: {request.Id} UUID: {request.Uuid}"); + + using var docStream = await Sender.Send(new SignPdfByEnvelopeCommand() + { + Envelope = envelope + }, cancel); + + if (docStream.CanSeek) + docStream.Position = 0; + + using var ms = new MemoryStream(); + docStream.CopyTo(ms); + byte[] doc = ms.ToArray(); + + foreach (var er in envelope.EnvelopeReceivers) + { + await NtfServer.Notify(er.Receiver.EmailAddress, new DocumentSignedNotification() + { + DocumentTitle = envelope.Title, + NameReceiver = er.Name, + Attachment = doc + }, cancel); + } + + if (request.SaveDocResult) + await Repo.UpdateAsync(e => e.DocResult = doc, e => e.Id == envelope.Id, cancel); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs b/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs index 3ce35e81..019e977b 100644 --- a/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs +++ b/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs @@ -29,6 +29,8 @@ public record SignPdfByEnvelopeCommand : EnvelopeQueryBase, IRequest UserId = userId; return this; } + + internal Envelope? Envelope { get; set; } } /// @@ -45,15 +47,20 @@ public class SignPdfByEnvelopeCommandHandler(IRepository Repo, ISender /// public async Task Handle(SignPdfByEnvelopeCommand request, CancellationToken cancel) { - var envelopeQuery = Repo.Query; + if (request.Envelope is null) + { + 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); + 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}"); + request.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}"); + } + + var envelope = request.Envelope; if (request.UserId is int userId && userId != envelope.UserId) throw new AuthorizationException($"Envelope is not authorized for user with Id: {request.UserId} Envelope ID: {request.Id} UUID: {request.Uuid}");