Enhance envelope creation functionality and configuration
- Updated DependencyInjection to include new command handler. - Modified CreateEnvelopeReceiverCommand for nullable responses. - Altered SQL command in EnvelopeReceiverAddReadSQL. - Refactored EnvelopeReceiverController with new dependencies and improved CreateAsync method. - Expanded appsettings.json with additional configuration settings. - Introduced new DTOs for signatures and receivers in CreateEnvelopeReceiverDtos.
This commit is contained in:
parent
cae00d9177
commit
2692fee6d2
@ -7,6 +7,7 @@ using DigitalData.Core.Client;
|
||||
using QRCoder;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using System.Reflection;
|
||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
namespace EnvelopeGenerator.Application;
|
||||
|
||||
@ -58,6 +59,7 @@ public static class DependencyInjection
|
||||
services.AddMediatR(cfg =>
|
||||
{
|
||||
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
|
||||
cfg.RegisterServicesFromAssembly(typeof(CreateEnvelopeReceiverCommandHandler).Assembly);
|
||||
});
|
||||
|
||||
return services;
|
||||
|
||||
@ -18,43 +18,4 @@ public record CreateEnvelopeReceiverCommand(
|
||||
[Required] DocumentCreateCommand Document,
|
||||
[Required] IEnumerable<ReceiverGetOrCreateCommand> Receivers,
|
||||
bool TFAEnabled = false
|
||||
) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest<CreateEnvelopeReceiverResponse>;
|
||||
|
||||
#region DTOs
|
||||
/// <summary>
|
||||
/// Signaturposition auf einem Dokument.
|
||||
/// </summary>
|
||||
/// <param name="X">X-Position</param>
|
||||
/// <param name="Y">Y-Position</param>
|
||||
/// <param name="Page">Seite, auf der sie sich befindet</param>
|
||||
public record Signature([Required] int X, [Required] int Y, [Required] int Page);
|
||||
|
||||
/// <summary>
|
||||
/// DTO für Empfänger, die erstellt oder abgerufen werden sollen.
|
||||
/// Wenn nicht, wird sie erstellt und mit einer Signatur versehen.
|
||||
/// </summary>
|
||||
/// <param name="Signatures">Unterschriften auf Dokumenten.</param>
|
||||
/// <param name="Salution">Der Name, mit dem der Empfänger angesprochen werden soll. Bei Null oder keinem Wert wird der zuletzt verwendete Name verwendet.</param>
|
||||
/// <param name="PhoneNumber">Sollte mit Vorwahl geschrieben werden</param>
|
||||
public record ReceiverGetOrCreateCommand([Required] IEnumerable<Signature> Signatures, string? Salution = null, string? PhoneNumber = null)
|
||||
{
|
||||
private string _emailAddress = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// E-Mail-Adresse des Empfängers.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string EmailAddress { get => _emailAddress.ToLower(); init => _emailAddress = _emailAddress.ToLower(); }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// DTO zum Erstellen eines Dokuments.
|
||||
/// </summary>
|
||||
/// <param name="DataAsByte">
|
||||
/// Die Dokumentdaten im Byte-Array-Format. Wird verwendet, wenn das Dokument als Roh-Binärdaten bereitgestellt wird.
|
||||
/// </param>
|
||||
/// <param name="DataAsBase64">
|
||||
/// Die Dokumentdaten im Base64-String-Format. Wird verwendet, wenn das Dokument als Base64-codierter String bereitgestellt wird.
|
||||
/// </param>
|
||||
public record DocumentCreateCommand(byte[]? DataAsByte = null, string? DataAsBase64 = null);
|
||||
#endregion
|
||||
) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest<CreateEnvelopeReceiverResponse?>;
|
||||
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
#region DTOs
|
||||
/// <summary>
|
||||
/// Signaturposition auf einem Dokument.
|
||||
/// </summary>
|
||||
/// <param name="X">X-Position</param>
|
||||
/// <param name="Y">Y-Position</param>
|
||||
/// <param name="Page">Seite, auf der sie sich befindet</param>
|
||||
public record Signature([Required] int X, [Required] int Y, [Required] int Page);
|
||||
|
||||
/// <summary>
|
||||
/// DTO für Empfänger, die erstellt oder abgerufen werden sollen.
|
||||
/// Wenn nicht, wird sie erstellt und mit einer Signatur versehen.
|
||||
/// </summary>
|
||||
/// <param name="Signatures">Unterschriften auf Dokumenten.</param>
|
||||
/// <param name="Salution">Der Name, mit dem der Empfänger angesprochen werden soll. Bei Null oder keinem Wert wird der zuletzt verwendete Name verwendet.</param>
|
||||
/// <param name="PhoneNumber">Sollte mit Vorwahl geschrieben werden</param>
|
||||
public record ReceiverGetOrCreateCommand([Required] IEnumerable<Signature> Signatures, string? Salution = null, string? PhoneNumber = null)
|
||||
{
|
||||
private string? _emailAddress = "h.tek@digitaldata.works";
|
||||
|
||||
/// <summary>
|
||||
/// E-Mail-Adresse des Empfängers.
|
||||
/// </summary>
|
||||
public string? EmailAddress { get => _emailAddress?.ToLower(); init => _emailAddress = _emailAddress?.ToLower() ?? "h.tek@digitaldata.works"; }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// DTO zum Erstellen eines Dokuments.
|
||||
/// </summary>
|
||||
/// <param name="DataAsByte">
|
||||
/// Die Dokumentdaten im Byte-Array-Format. Wird verwendet, wenn das Dokument als Roh-Binärdaten bereitgestellt wird.
|
||||
/// </param>
|
||||
/// <param name="DataAsBase64">
|
||||
/// Die Dokumentdaten im Base64-String-Format. Wird verwendet, wenn das Dokument als Base64-codierter String bereitgestellt wird.
|
||||
/// </param>
|
||||
public record DocumentCreateCommand(byte[]? DataAsByte = null, string? DataAsBase64 = null);
|
||||
#endregion
|
||||
@ -14,12 +14,9 @@ public class EnvelopeReceiverAddReadSQL : ISQL<Envelope>
|
||||
/// </summary>
|
||||
public string Raw => @"
|
||||
USE [DD_ECM]
|
||||
GO
|
||||
|
||||
DECLARE @OUT_RECEIVER_ID int
|
||||
|
||||
DECLARE @ENV_UID varchar(36) = @ENV_UID
|
||||
|
||||
EXEC [dbo].[PRSIG_API_CREATE_RECEIVER]
|
||||
@ENV_UID = @ENV_UID,
|
||||
@EMAIL_ADRESS = @EMAIL_ADRESS ,
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
using DigitalData.Core.DTO;
|
||||
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;
|
||||
|
||||
@ -26,17 +31,29 @@ public class EnvelopeReceiverController : ControllerBase
|
||||
|
||||
private readonly IMediator _mediator;
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly IEnvelopeExecutor _envelopeExecutor;
|
||||
|
||||
private readonly IEnvelopeReceiverExecutor _erExecutor;
|
||||
|
||||
/// <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>
|
||||
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator)
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="envelopeExecutor"></param>
|
||||
/// <param name="erExecutor"></param>
|
||||
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator, IMapper mapper, IEnvelopeExecutor envelopeExecutor, IEnvelopeReceiverExecutor erExecutor)
|
||||
{
|
||||
_logger = logger;
|
||||
_erService = envelopeReceiverService;
|
||||
_mediator = mediator;
|
||||
_mapper = mapper;
|
||||
_envelopeExecutor = envelopeExecutor;
|
||||
_erExecutor = erExecutor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -120,8 +137,7 @@ public class EnvelopeReceiverController : ControllerBase
|
||||
/// <summary>
|
||||
/// Datenübertragungsobjekt mit Informationen zu Umschlägen, Empfängern und Unterschriften.
|
||||
/// </summary>
|
||||
/// <param name="createEnvelopeQuery"></param>
|
||||
/// <param name="cancellationToken">Token to cancel the operation</param>
|
||||
/// <param name="request"></param>
|
||||
/// <returns>HTTP-Antwort</returns>
|
||||
/// <remarks>
|
||||
/// Sample request:
|
||||
@ -157,9 +173,38 @@ public class EnvelopeReceiverController : ControllerBase
|
||||
/// <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 createEnvelopeQuery, CancellationToken cancellationToken)
|
||||
public async Task<IActionResult> CreateAsync([FromBody] CreateEnvelopeReceiverCommand request)
|
||||
{
|
||||
await _mediator.Send(createEnvelopeQuery, cancellationToken);
|
||||
return Accepted();
|
||||
try
|
||||
{
|
||||
CancellationToken cancel = default;
|
||||
int userId = User.GetId();
|
||||
|
||||
var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancel);
|
||||
|
||||
List<EnvelopeReceiver> sentRecipients = new();
|
||||
List<ReceiverGetOrCreateCommand> 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<CreateEnvelopeReceiverResponse>(envelope);
|
||||
res.UnsentRecipients = unsentRecipients;
|
||||
res.SentRecipients = _mapper.Map<IEnumerable<ReceiverReadDto>>(sentRecipients);
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,5 +36,210 @@
|
||||
"QueryString": "AuthToken",
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "work-flow.digitaldata.works"
|
||||
},
|
||||
"PSPDFKitLicenseKey": "SXCtGGY9XA-31OGUXQK-r7c6AkdLGPm2ljuyDr1qu0kkhLvydg-Do-fxpNUF4Rq3fS_xAnZRNFRHbXpE6sQ2BMcCSVTcXVJO6tPviexjpiT-HnrDEySlUERJnnvh-tmeOWprxS6BySPnSILkmaVQtUfOIUS-cUbvvEYHTvQBKbSF8di4XHQFyfv49ihr51axm3NVV3AXwh2EiKL5C5XdqBZ4sQ4O7vXBjM2zvxdPxlxdcNYmiU83uAzw7B83O_jubPzya4CdUHh_YH7Nlp2gP56MeG1Sw2JhMtfG3Rj14Sg4ctaeL9p6AEWca5dDjJ2li5tFIV2fQSsw6A_cowLu0gtMm5i8IfJXeIcQbMC2-0wGv1oe9hZYJvFMdzhTM_FiejM0agemxt3lJyzuyP8zbBSOgp7Si6A85krLWPZptyZBTG7pp7IHboUHfPMxCXqi-zMsqewOJtQBE2mjntU-lPryKnssOpMPfswwQX7QSkJYV5EMqNmEhQX6mEkp2wcqFzMC7bJQew1aO4pOpvChUaMvb1vgRek0HxLag0nwQYX2YrYGh7F_xXJs-8HNwJe8H0-eW4x4faayCgM5rB5772CCCsD9ThZcvXFrjNHHLGJ8WuBUFm6LArvSfFQdii_7j-_sqHMpeKZt26NFgivj1A==",
|
||||
"Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value.
|
||||
"default-src 'self'",
|
||||
"script-src 'self' 'nonce-{0}' 'unsafe-eval'",
|
||||
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com:*",
|
||||
"img-src 'self' data: https: blob:",
|
||||
"font-src 'self' https://fonts.gstatic.com:*",
|
||||
"connect-src 'self' https://nominatim.openstreetmap.org:* http://localhost:* https://localhost:* ws://localhost:* wss://localhost:* blob:",
|
||||
"frame-src 'self'",
|
||||
"media-src 'self'",
|
||||
"object-src 'self'"
|
||||
],
|
||||
"NLog": {
|
||||
"throwConfigExceptions": true,
|
||||
"variables": {
|
||||
"logDirectory": "E:\\LogFiles\\Digital Data\\signFlow",
|
||||
"logFileNamePrefix": "${shortdate}-ECM.EnvelopeGenerator.Web"
|
||||
},
|
||||
"targets": {
|
||||
"infoLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"errorLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"criticalLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
|
||||
"maxArchiveDays": 30
|
||||
}
|
||||
},
|
||||
// Trace, Debug, Info, Warn, Error and *Fatal*
|
||||
"rules": [
|
||||
{
|
||||
"logger": "*",
|
||||
"minLevel": "Info",
|
||||
"maxLevel": "Warn",
|
||||
"writeTo": "infoLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Error",
|
||||
"writeTo": "errorLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Fatal",
|
||||
"writeTo": "criticalLogs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ContactLink": {
|
||||
"Label": "Kontakt",
|
||||
"Href": "https://digitaldata.works/",
|
||||
"HrefLang": "de",
|
||||
"Target": "_blank",
|
||||
"Title": "Digital Data GmbH"
|
||||
},
|
||||
/* Resx naming format is -> Resource.language.resx (eg: Resource.de_DE.resx).
|
||||
To add a new language, first you should write the required resx file.
|
||||
first is the default culture name. */
|
||||
"Cultures": [
|
||||
{
|
||||
"Language": "de-DE",
|
||||
"FIClass": "fi-de"
|
||||
},
|
||||
{
|
||||
"Language": "en-US",
|
||||
"FIClass": "fi-us"
|
||||
}
|
||||
],
|
||||
"DisableMultiLanguage": false,
|
||||
"Regexes": [
|
||||
{
|
||||
"Pattern": "/^\\p{L}+(?:([\\ \\-\\']|(\\.\\ ))\\p{L}+)*$/u",
|
||||
"Name": "City",
|
||||
"Platforms": [ ".NET" ]
|
||||
},
|
||||
{
|
||||
"Pattern": "/^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$/",
|
||||
"Name": "City",
|
||||
"Platforms": [ "javascript" ]
|
||||
}
|
||||
],
|
||||
"CustomImages": {
|
||||
"App": {
|
||||
"Src": "/img/DD_signFLOW_LOGO.png",
|
||||
"Classes": {
|
||||
"Main": "signFlow-logo"
|
||||
}
|
||||
},
|
||||
"Company": {
|
||||
"Src": "/img/digital_data.svg",
|
||||
"Classes": {
|
||||
"Show": "dd-show-logo",
|
||||
"Locked": "dd-locked-logo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DispatcherParams": {
|
||||
"SendingProfile": 1,
|
||||
"AddedWho": "DDEnvelopGenerator",
|
||||
"ReminderTypeId": 202377,
|
||||
"EmailAttmt1": ""
|
||||
},
|
||||
"MailParams": {
|
||||
"Placeholders": {
|
||||
"[NAME_PORTAL]": "signFlow",
|
||||
"[SIGNATURE_TYPE]": "signieren",
|
||||
"[REASON]": ""
|
||||
}
|
||||
},
|
||||
"GtxMessagingParams": {
|
||||
"Uri": "https://rest.gtx-messaging.net",
|
||||
"Path": "smsc/sendsms/f566f7e5-bdf2-4a9a-bf52-ed88215a432e/json",
|
||||
"Headers": {},
|
||||
"QueryParams": {
|
||||
"from": "signFlow"
|
||||
}
|
||||
},
|
||||
"TFARegParams": {
|
||||
"TimeLimit": "00:30:00"
|
||||
},
|
||||
"DbTriggerParams": {
|
||||
"Envelope": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ],
|
||||
"EnvelopeHistory": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ],
|
||||
"EmailOut": [ "TBEMLP_EMAIL_OUT_AFT_INS", "TBEMLP_EMAIL_OUT_AFT_UPD" ],
|
||||
"EnvelopeReceiverReadOnly": [ "TBSIG_ENVELOPE_RECEIVER_READ_ONLY_UPD" ],
|
||||
"Receiver": []
|
||||
},
|
||||
"MainPageTitle": null,
|
||||
"AnnotationParams": {
|
||||
"Background": {
|
||||
"Margin": 0.20,
|
||||
"BackgroundColor": {
|
||||
"R": 222,
|
||||
"G": 220,
|
||||
"B": 215
|
||||
},
|
||||
"BorderColor": {
|
||||
"R": 204,
|
||||
"G": 202,
|
||||
"B": 198
|
||||
},
|
||||
"BorderStyle": "underline",
|
||||
"BorderWidth": 4
|
||||
},
|
||||
"DefaultAnnotation": {
|
||||
"Width": 1,
|
||||
"Height": 0.5,
|
||||
"MarginTop": 1
|
||||
},
|
||||
"Annotations": [
|
||||
{
|
||||
"Name": "Signature",
|
||||
"MarginTop": 0
|
||||
},
|
||||
{
|
||||
"Name": "PositionLabel",
|
||||
"VerBoundAnnotName": "Signature",
|
||||
"WidthRatio": 1.2,
|
||||
"HeightRatio": 0.5,
|
||||
"MarginTopRatio": 0.22
|
||||
},
|
||||
{
|
||||
"Name": "Position",
|
||||
"VerBoundAnnotName": "PositionLabel",
|
||||
"WidthRatio": 1.2,
|
||||
"HeightRatio": 0.5,
|
||||
"MarginTopRatio": -0.05
|
||||
},
|
||||
{
|
||||
"Name": "CityLabel",
|
||||
"VerBoundAnnotName": "Position",
|
||||
"WidthRatio": 1.2,
|
||||
"HeightRatio": 0.5,
|
||||
"MarginTopRatio": 0.05
|
||||
},
|
||||
{
|
||||
"Name": "City",
|
||||
"VerBoundAnnotName": "CityLabel",
|
||||
"WidthRatio": 1.2,
|
||||
"HeightRatio": 0.5,
|
||||
"MarginTopRatio": -0.05
|
||||
},
|
||||
{
|
||||
"Name": "DateLabel",
|
||||
"VerBoundAnnotName": "City",
|
||||
"WidthRatio": 1.55,
|
||||
"HeightRatio": 0.5,
|
||||
"MarginTopRatio": 0.05
|
||||
},
|
||||
{
|
||||
"Name": "Date",
|
||||
"VerBoundAnnotName": "DateLabel",
|
||||
"WidthRatio": 1.55,
|
||||
"HeightRatio": 0.5,
|
||||
"MarginTopRatio": -0.1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user