314 lines
12 KiB
C#
314 lines
12 KiB
C#
using AutoMapper;
|
|
using DigitalData.Core.Abstraction.Application.DTO;
|
|
using EnvelopeGenerator.Application.Interfaces.Services;
|
|
using EnvelopeGenerator.Application.Interfaces.SQLExecutor;
|
|
using EnvelopeGenerator.Application.Dto.Receiver;
|
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
|
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
|
|
using EnvelopeGenerator.Application.Envelopes.Queries;
|
|
using EnvelopeGenerator.Application.SQL;
|
|
using EnvelopeGenerator.Domain.Entities;
|
|
using EnvelopeGenerator.GeneratorAPI.Models;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Data.SqlClient;
|
|
using Microsoft.Extensions.Options;
|
|
using System.Data;
|
|
using System.Reflection.Metadata;
|
|
using EnvelopeGenerator.Domain;
|
|
|
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
|
|
|
/// <summary>
|
|
/// Controller für die Verwaltung von Umschlagempfängern.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Dieser Controller bietet Endpunkte für das Abrufen und Verwalten von Umschlagempfängerdaten.
|
|
/// </remarks>
|
|
[Route("api/[controller]")]
|
|
[Authorize]
|
|
[ApiController]
|
|
public class EnvelopeReceiverController : ControllerBase
|
|
{
|
|
private readonly ILogger<EnvelopeReceiverController> _logger;
|
|
|
|
[Obsolete("Use MediatR")]
|
|
private readonly IEnvelopeReceiverService _erService;
|
|
|
|
private readonly IMediator _mediator;
|
|
|
|
private readonly IMapper _mapper;
|
|
|
|
private readonly IEnvelopeExecutor _envelopeExecutor;
|
|
|
|
private readonly IEnvelopeReceiverExecutor _erExecutor;
|
|
|
|
private readonly IDocumentExecutor _documentExecutor;
|
|
|
|
private readonly string _cnnStr;
|
|
|
|
/// <summary>
|
|
/// Konstruktor für den EnvelopeReceiverController.
|
|
/// </summary>
|
|
/// <param name="logger">Logger-Instanz zur Protokollierung von Informationen und Fehlern.</param>
|
|
/// <param name="envelopeReceiverService">Service zur Verwaltung von Umschlagempfängern.</param>
|
|
/// <param name="mediator">Mediator-Instanz zur Verarbeitung von Befehlen und Abfragen.</param>
|
|
/// <param name="mapper"></param>
|
|
/// <param name="envelopeExecutor"></param>
|
|
/// <param name="erExecutor"></param>
|
|
/// <param name="documentExecutor"></param>
|
|
/// <param name="csOpt"></param>
|
|
[Obsolete("Use MediatR")]
|
|
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator, IMapper mapper, IEnvelopeExecutor envelopeExecutor, IEnvelopeReceiverExecutor erExecutor, IDocumentExecutor documentExecutor, IOptions<ConnectionString> csOpt)
|
|
{
|
|
_logger = logger;
|
|
_erService = envelopeReceiverService;
|
|
_mediator = mediator;
|
|
_mapper = mapper;
|
|
_envelopeExecutor = envelopeExecutor;
|
|
_erExecutor = erExecutor;
|
|
_documentExecutor = documentExecutor;
|
|
_cnnStr = csOpt.Value.Value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ruft eine Liste von Umschlagempfängern basierend auf den angegebenen Abfrageparametern ab.
|
|
/// </summary>
|
|
/// <param name="envelopeReceiver">Die Abfrageparameter für die Filterung von Umschlagempfängern.</param>
|
|
/// <returns>Eine HTTP-Antwort mit der Liste der gefundenen Umschlagempfänger oder einem Fehlerstatus.</returns>
|
|
/// <remarks>
|
|
/// 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.
|
|
/// </remarks>
|
|
/// <response code="200">Die Liste der Umschlagempfänger wurde erfolgreich abgerufen.</response>
|
|
/// <response code="401">Wenn kein autorisierter Token vorhanden ist</response>
|
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
|
[Authorize]
|
|
[HttpGet]
|
|
[Obsolete("Use MediatR")]
|
|
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver)
|
|
{
|
|
var username = User.GetUsernameOrDefault();
|
|
|
|
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.GetUsernameOrDefault(), User.GetNameOrDefault(), User.GetPrenameOrDefault(), User.GetEmailOrDefault());
|
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
}
|
|
|
|
return await _erService.ReadByUsernameAsync(
|
|
username: username,
|
|
min_status: envelopeReceiver.Envelope.Status?.Min,
|
|
max_status: envelopeReceiver.Envelope.Status?.Max,
|
|
envelopeQuery: envelopeReceiver.Envelope,
|
|
receiverQuery: envelopeReceiver.Receiver,
|
|
ignore_statuses: envelopeReceiver.Envelope.Status?.Ignore ?? Array.Empty<Constants.EnvelopeStatus>())
|
|
.ThenAsync(
|
|
Success: Ok,
|
|
Fail: IActionResult (msg, ntc) =>
|
|
{
|
|
_logger.LogNotice(ntc);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, msg);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ruft den Namen des zuletzt verwendeten Empfängers basierend auf der angegebenen E-Mail-Adresse ab.
|
|
/// </summary>
|
|
/// <param name="receiver">Abfrage, bei der nur eine der Angaben ID, Signatur oder E-Mail-Adresse des Empfängers eingegeben werden muss.</param>
|
|
/// <returns>Eine HTTP-Antwort mit dem Namen des Empfängers oder einem Fehlerstatus.</returns>
|
|
/// <remarks>
|
|
/// Dieser Endpunkt ermöglicht es, den Namen des zuletzt verwendeten Empfängers basierend auf der E-Mail-Adresse abzurufen.
|
|
/// </remarks>
|
|
/// <response code="200">Der Name des Empfängers wurde erfolgreich abgerufen.</response>
|
|
/// <response code="401">Wenn kein autorisierter Token vorhanden ist</response>
|
|
/// <response code="404">Kein Empfänger gefunden.</response>
|
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
|
[Authorize]
|
|
[HttpGet("salute")]
|
|
[Obsolete("Use MediatR")]
|
|
public async Task<IActionResult> GetReceiverName([FromQuery] ReadReceiverNameQuery receiver)
|
|
{
|
|
return await _erService.ReadLastUsedReceiverNameByMailAsync(receiver.EmailAddress, receiver.Id, receiver.Signature).ThenAsync(
|
|
Success: res => res is null ? NotFound() : Ok(res),
|
|
Fail: IActionResult (msg, ntc) =>
|
|
{
|
|
if (ntc.HasFlag(Flag.NotFound))
|
|
return NotFound();
|
|
|
|
_logger.LogNotice(ntc);
|
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Datenübertragungsobjekt mit Informationen zu Umschlägen, Empfängern und Unterschriften.
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns>HTTP-Antwort</returns>
|
|
/// <remarks>
|
|
/// 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
|
|
/// }
|
|
///
|
|
/// </remarks>
|
|
/// <response code="202">Envelope-Erstellung und Sendeprozessbefehl erfolgreich</response>
|
|
/// <response code="400">Wenn ein Fehler im HTTP-Body auftritt</response>
|
|
/// <response code="401">Wenn kein autorisierter Token vorhanden ist</response>
|
|
/// <response code="500">Es handelt sich um einen unerwarteten Fehler. Die Protokolle sollten überprüft werden.</response>
|
|
[Authorize]
|
|
[HttpPost]
|
|
public async Task<IActionResult> CreateAsync([FromBody] CreateEnvelopeReceiverCommand request)
|
|
{
|
|
CancellationToken cancel = default;
|
|
int userId = User.GetId();
|
|
|
|
#region Create Envelope
|
|
var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancel);
|
|
#endregion
|
|
|
|
#region Add receivers
|
|
List<EnvelopeReceiver> sentReceivers = new();
|
|
List<ReceiverGetOrCreateCommand> unsentReceivers = 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)
|
|
unsentReceivers.Add(receiver);
|
|
else
|
|
sentReceivers.Add(envelopeReceiver);
|
|
}
|
|
|
|
var res = _mapper.Map<CreateEnvelopeReceiverResponse>(envelope);
|
|
res.UnsentReceivers = unsentReceivers;
|
|
res.SentReceiver = _mapper.Map<List<ReceiverReadDto>>(sentReceivers.Select(er => er.Receiver));
|
|
#endregion
|
|
|
|
#region Add document
|
|
var document = await _documentExecutor.CreateDocumentAsync(request.Document.DataAsBase64, envelope.Uuid, cancel);
|
|
|
|
if (document is null)
|
|
return StatusCode(StatusCodes.Status500InternalServerError, "Document creation is failed.");
|
|
#endregion
|
|
|
|
#region Add document element
|
|
// @DOC_ID, @RECEIVER_ID, @POSITION_X, @POSITION_Y, @PAGE
|
|
string sql = @"
|
|
DECLARE @OUT_SUCCESS bit;
|
|
|
|
EXEC [dbo].[PRSIG_API_ADD_DOC_RECEIVER_ELEM]
|
|
{0},
|
|
{1},
|
|
{2},
|
|
{3},
|
|
{4},
|
|
@OUT_SUCCESS OUTPUT;
|
|
|
|
SELECT @OUT_SUCCESS as [@OUT_SUCCESS];";
|
|
|
|
foreach (var rcv in res.SentReceiver)
|
|
foreach (var sign in request.Receivers.Where(r => r.EmailAddress == rcv.EmailAddress).FirstOrDefault()?.Signatures ?? Array.Empty<Signature>())
|
|
{
|
|
using (SqlConnection conn = new(_cnnStr))
|
|
{
|
|
conn.Open();
|
|
|
|
var formattedSQL = string.Format(sql, document.Id.ToSqlParam(), rcv.Id.ToSqlParam(), sign.X.ToSqlParam(), sign.Y.ToSqlParam(), sign.Page.ToSqlParam());
|
|
|
|
using SqlCommand cmd = new SqlCommand(formattedSQL, conn);
|
|
cmd.CommandType = CommandType.Text;
|
|
|
|
using SqlDataReader reader = cmd.ExecuteReader();
|
|
if (reader.Read())
|
|
{
|
|
bool outSuccess = reader.GetBoolean(0);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Create history
|
|
// ENV_UID, STATUS_ID, USER_ID,
|
|
string sql_hist = @"
|
|
USE [DD_ECM]
|
|
|
|
DECLARE @OUT_SUCCESS bit;
|
|
|
|
EXEC [dbo].[PRSIG_API_ADD_HISTORY_STATE]
|
|
{0},
|
|
{1},
|
|
{2},
|
|
@OUT_SUCCESS OUTPUT;
|
|
|
|
SELECT @OUT_SUCCESS as [@OUT_SUCCESS];";
|
|
|
|
using (SqlConnection conn = new(_cnnStr))
|
|
{
|
|
conn.Open();
|
|
var formattedSQL_hist = string.Format(sql_hist, envelope.Uuid.ToSqlParam(), 1003.ToSqlParam(), userId.ToSqlParam());
|
|
using (SqlCommand cmd = new SqlCommand(formattedSQL_hist, conn))
|
|
{
|
|
cmd.CommandType = CommandType.Text;
|
|
|
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
|
{
|
|
if (reader.Read())
|
|
{
|
|
bool outSuccess = reader.GetBoolean(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
return Ok(res);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <returns></returns>
|
|
public static bool IsBase64String(string input)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(input))
|
|
return false;
|
|
|
|
try
|
|
{
|
|
Convert.FromBase64String(input);
|
|
return true;
|
|
}
|
|
catch (FormatException)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
} |