using EnvelopeGenerator.Application.Common.Notifications.EnvelopeDeleted; using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Exceptions; using EnvelopeGenerator.Application.Histories.Commands; using EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.Domain.Entities; using MediatR; using Microsoft.EntityFrameworkCore; using System.Linq; namespace EnvelopeGenerator.Application.Envelopes.Commands; public class DeleteEnvelopeCommandHandler : IRequestHandler { private readonly IRepository _envelopeRepository; private readonly IMediator _mediator; public DeleteEnvelopeCommandHandler( IRepository envelopeRepository, IMediator mediator) { _envelopeRepository = envelopeRepository; _mediator = mediator; } public async Task Handle(DeleteEnvelopeCommand request, CancellationToken cancel) { var reason = request.Reason?.Trim(); if (string.IsNullOrWhiteSpace(reason)) throw new BadRequestException("Please provide a reason."); var envelope = await _envelopeRepository.Query .Include(e => e.User) .Include(e => e.EnvelopeReceivers) .ThenInclude(er => er.Receiver) .FirstOrDefaultAsync(e => e.Id == request.EnvelopeId, cancel) ?? throw new NotFoundException($"Envelope {request.EnvelopeId} not found."); if (envelope.UserId != request.UserId) throw new ForbiddenException(); if (envelope.Status is EnvelopeStatus.EnvelopeDeleted or EnvelopeStatus.EnvelopeWithdrawn) return new DeleteEnvelopeResultDto(envelope.Id, envelope.Status, IsNoOp: true); var targetStatus = envelope.Status > EnvelopeStatus.EnvelopeSaved ? EnvelopeStatus.EnvelopeWithdrawn : EnvelopeStatus.EnvelopeDeleted; var changedWhen = DateTime.Now; envelope.Status = targetStatus; envelope.Comment = reason; envelope.ChangedWhen = changedWhen; await _envelopeRepository.UpdateAsync(e => { e.Status = targetStatus; e.Comment = reason; e.ChangedWhen = changedWhen; }, e => e.Id == envelope.Id, cancel); var userReference = envelope.User?.Email; if (string.IsNullOrWhiteSpace(userReference)) throw new BadRequestException("Envelope sender email is missing."); await _mediator.Send(new CreateHistoryCommand { EnvelopeId = envelope.Id, UserReference = userReference, Status = targetStatus, Comment = reason }, cancel); foreach (var envelopeReceiver in envelope.EnvelopeReceivers ?? Enumerable.Empty()) { if (envelopeReceiver.Receiver is null) continue; await _mediator.Publish(new EnvelopeDeletedNotification { Envelope = envelope, EnvelopeReceiver = envelopeReceiver, Reason = reason, SenderReference = userReference }, cancel); } return new DeleteEnvelopeResultDto(envelope.Id, targetStatus, IsNoOp: false); } }