using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Exceptions; using EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Exceptions; using MediatR; using Microsoft.EntityFrameworkCore; namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands; /// /// /// public record RemoveEnvelopeReceiverCommand : IRequest { /// /// /// public required int EnvelopeId { get; init; } /// /// /// public required int ReceiverId { get; init; } internal int? UserId { get; private set; } /// /// /// /// /// public RemoveEnvelopeReceiverCommand Authenticated(int userId) { UserId = userId; return this; } } /// /// /// /// public class RemoveEnvelopeReceiverCommandHandler( IRepository Repo, IRepository ElementRepo, IRepository AnnotRepo) : IRequestHandler { /// /// /// /// /// /// /// public async Task Handle(RemoveEnvelopeReceiverCommand request, CancellationToken cancel) { var er = await Repo.Query .Where(er => er.EnvelopeId == request.EnvelopeId && er.ReceiverId == request.ReceiverId) .Include(er => er.Envelope) .SingleOrDefaultAsync(cancel) ?? throw new NotFoundException(); if (er.Envelope is null) throw new InvalidOperationException($"In {nameof(RemoveEnvelopeReceiverCommandHandler)} EnvelopeReceiver.Envelope is null." + $"This should not happen." + $"EnvelopeId: {request.EnvelopeId}, ReceiverId: {request.ReceiverId}"); if (request.UserId is int userId && er.Envelope.UserId != userId) throw new AuthorizationException("Cannot remove receiver from envelope that you do not own."); if (er.Envelope.Status > EnvelopeStatus.EnvelopeSaved) throw new ForbiddenException("Cannot remove receiver from envelope that is already processed."); // 1. Delete all ElementAnnotations for this EnvelopeReceiver await AnnotRepo.DeleteAsync(ann => ann.Element.Document.EnvelopeId == request.EnvelopeId && ann.Element.ReceiverId == request.ReceiverId, cancel); // 2. Delete all DocReceiverElements for this EnvelopeReceiver await ElementRepo.DeleteAsync(el => el.Document.EnvelopeId == request.EnvelopeId && el.ReceiverId == request.ReceiverId, cancel); // 3. Delete the EnvelopeReceiver await Repo.DeleteAsync(er => er.EnvelopeId == request.EnvelopeId && er.ReceiverId == request.ReceiverId, cancel); } }