Files
EnvelopeGenerator/EnvelopeGenerator.Application/PdfSigning/FinalizeEnvelopeCommand.cs
TekH a35e05d016 Refactor Attachments property and syntax
Changed the `Attachments` property type in `EnvelopeNotificationBase.cs` from `List` to `IReadOnlyList` to enhance immutability and thread safety. Updated the `FinalizeEnvelopeCommandHandler` in `FinalizeEnvelopeCommand.cs` to use a single-line syntax for `Attachments` initialization, improving code readability.
2026-10-28 16:28:17 +01:00

108 lines
3.6 KiB
C#

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;
/// <summary>
///
/// </summary>
public record FinalizeEnvelopeCommand : EnvelopeQueryBase, IRequest
{
internal int? UserId { get; private set; } = null;
/// <summary>
///
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public FinalizeEnvelopeCommand Authorized(int userId)
{
UserId = userId;
return this;
}
/// <summary>
///
/// </summary>
public bool BurnedAllowed { get; init; } = false;
/// <summary>
///
/// </summary>
public bool SaveDocResult { get; init; } = true;
}
/// <summary>
///
/// </summary>
/// <param name="Repo"></param>
/// <param name="Sender"></param>
/// <param name="NtfServer"></param>
public class FinalizeEnvelopeCommandHandler(IRepository<Envelope> Repo, ISender Sender, IEnvelopeNotificationService NtfServer) : IRequestHandler<FinalizeEnvelopeCommand>
{
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="NotFoundException"></exception>
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,
Attachments = [($"unterzeichnetes-dokument.pdf", doc)]
}, cancel);
}
if (request.SaveDocResult)
await Repo.UpdateAsync(e => e.DocResult = doc, e => e.Id == envelope.Id, cancel);
}
}