using AutoMapper; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.Contracts.SQLExecutor; using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create; using EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read; using EnvelopeGenerator.Application.Envelopes.Queries.ReceiverName; using EnvelopeGenerator.Domain.Entities; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Threading.Channels; namespace EnvelopeGenerator.GeneratorAPI.Controllers; /// /// Controller für die Verwaltung von Umschlagempfängern. /// /// /// Dieser Controller bietet Endpunkte für das Abrufen und Verwalten von Umschlagempfängerdaten. /// [Route("api/[controller]")] [Authorize] [ApiController] public class EnvelopeReceiverController : ControllerBase { private readonly ILogger _logger; private readonly IEnvelopeReceiverService _erService; private readonly IMediator _mediator; private readonly IMapper _mapper; private readonly IEnvelopeExecutor _envelopeExecutor; private readonly IEnvelopeReceiverExecutor _erExecutor; /// /// Konstruktor für den EnvelopeReceiverController. /// /// Logger-Instanz zur Protokollierung von Informationen und Fehlern. /// Service zur Verwaltung von Umschlagempfängern. /// Mediator-Instanz zur Verarbeitung von Befehlen und Abfragen. /// /// /// public EnvelopeReceiverController(ILogger logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator, IMapper mapper, IEnvelopeExecutor envelopeExecutor, IEnvelopeReceiverExecutor erExecutor) { _logger = logger; _erService = envelopeReceiverService; _mediator = mediator; _mapper = mapper; _envelopeExecutor = envelopeExecutor; _erExecutor = erExecutor; } /// /// Ruft eine Liste von Umschlagempfängern basierend auf den angegebenen Abfrageparametern ab. /// /// Die Abfrageparameter für die Filterung von Umschlagempfängern. /// Eine HTTP-Antwort mit der Liste der gefundenen Umschlagempfänger oder einem Fehlerstatus. /// /// Dieser Endpunkt ermöglicht es, Umschlagempfänger basierend auf dem Benutzernamen und optionalen Statusfiltern abzurufen. /// Wenn der Benutzername nicht ermittelt werden kann, wird ein Serverfehler zurückgegeben. /// /// Die Liste der Umschlagempfänger wurde erfolgreich abgerufen. /// Wenn kein autorisierter Token vorhanden ist /// Ein unerwarteter Fehler ist aufgetreten. [Authorize] [HttpGet] public async Task GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver) { try { var username = User.GetUsername(); if (username is null) { _logger.LogError(@"Envelope Receiver dto cannot be sent because username claim is null. Potential authentication and authorization error. The value of other claims are [id: {id}], [username: {username}], [name: {name}], [prename: {prename}], [email: {email}].", User.GetId(), User.GetUsername(), User.GetName(), User.GetPrename(), User.GetEmail()); return StatusCode(StatusCodes.Status500InternalServerError); } return await _erService.ReadByUsernameAsync( username: username, min_status: envelopeReceiver.Status?.Min ?? envelopeReceiver.Envelope?.Status, max_status:envelopeReceiver.Status?.Max ?? envelopeReceiver.Envelope?.Status, ignore_statuses: envelopeReceiver.Status?.Ignore ?? Array.Empty()) .ThenAsync( Success: Ok, Fail: IActionResult (msg, ntc) => { _logger.LogNotice(ntc); return StatusCode(StatusCodes.Status500InternalServerError, msg); }); } catch (Exception ex) { _logger.LogError(ex, "An unexpected error occurred. {message}", ex.Message); return new StatusCodeResult(StatusCodes.Status500InternalServerError); } } /// /// Ruft den Namen des zuletzt verwendeten Empfängers basierend auf der angegebenen E-Mail-Adresse ab. /// /// Die Abfrage, die die E-Mail-Adresse des Empfängers enthält. /// Eine HTTP-Antwort mit dem Namen des Empfängers oder einem Fehlerstatus. /// /// Dieser Endpunkt ermöglicht es, den Namen des zuletzt verwendeten Empfängers basierend auf der E-Mail-Adresse abzurufen. /// /// Der Name des Empfängers wurde erfolgreich abgerufen. /// Wenn kein autorisierter Token vorhanden ist /// Kein Empfänger gefunden. /// Ein unerwarteter Fehler ist aufgetreten. [Authorize] [HttpGet("salute")] public async Task GetReceiverName([FromQuery] ReadReceiverNameQuery receiverName) { try { return await _erService.ReadLastUsedReceiverNameByMail(receiverName.EmailAddress).ThenAsync( Success: res => res is null ? Ok(string.Empty) : Ok(res), Fail: IActionResult (msg, ntc) => { if (ntc.HasFlag(Flag.NotFound)) return NotFound(); _logger.LogNotice(ntc); return StatusCode(StatusCodes.Status500InternalServerError); }); } catch (Exception ex) { _logger.LogError(ex, "{message}", ex.Message); return StatusCode(StatusCodes.Status500InternalServerError); } } /// /// Datenübertragungsobjekt mit Informationen zu Umschlägen, Empfängern und Unterschriften. /// /// /// HTTP-Antwort /// /// Sample request: /// /// POST /api/envelope /// { /// "title": "Vertragsdokument", /// "message": "Bitte unterschreiben Sie dieses Dokument.", /// "document": { /// "dataAsBase64": "dGVzdC1iYXNlNjQtZGF0YQ==" /// }, /// "receivers": [ /// { /// "emailAddress": "example@example.com", /// "signatures": [ /// { /// "x": 100, /// "y": 200, /// "page": 1 /// } /// ], /// "name": "Max Mustermann", /// "phoneNumber": "+49123456789" /// } /// ], /// "tfaEnabled": false /// } /// /// /// Envelope-Erstellung und Sendeprozessbefehl erfolgreich /// Wenn ein Fehler im HTTP-Body auftritt /// Wenn kein autorisierter Token vorhanden ist /// Es handelt sich um einen unerwarteten Fehler. Die Protokolle sollten überprüft werden. [Authorize] [HttpPost] public async Task CreateAsync([FromBody] CreateEnvelopeReceiverCommand request) { try { CancellationToken cancel = default; int userId = User.GetId(); var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancel); List sentRecipients = new(); List unsentRecipients = new(); foreach (var receiver in request.Receivers) { var envelopeReceiver = await _erExecutor.AddEnvelopeReceiverAsync(envelope.Uuid, receiver.EmailAddress, receiver.Salution, receiver.PhoneNumber, cancel); if (envelopeReceiver is null) unsentRecipients.Add(receiver); else sentRecipients.Add(envelopeReceiver); } var res = _mapper.Map(envelope); res.UnsentRecipients = unsentRecipients; res.SentRecipients = _mapper.Map>(sentRecipients); return Ok(res); } catch (Exception ex) { _logger.LogError(ex, "{Message}", ex.Message); return StatusCode(StatusCodes.Status500InternalServerError); } } }