Compare commits
258 Commits
396c6014fb
...
feat/signF
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
456c591fae | ||
|
|
41b2841c25 | ||
|
|
6a6da4a876 | ||
|
|
af280ee64e | ||
|
|
9b945ce232 | ||
|
|
8b1199bc71 | ||
|
|
1d74b7ca06 | ||
|
|
c1bce7c639 | ||
|
|
4401a70217 | ||
|
|
fd53f5bfd6 | ||
|
|
6126fce24d | ||
|
|
ce41090979 | ||
|
|
3fa113003c | ||
|
|
5504093591 | ||
|
|
040cf8641d | ||
|
|
09df86000b | ||
|
|
406ddfb226 | ||
|
|
b01f13fb5f | ||
|
|
00fedc7c4c | ||
|
|
171de98552 | ||
|
|
ea6d80918c | ||
|
|
3b82467133 | ||
|
|
686b1a3a59 | ||
|
|
93019362b7 | ||
|
|
7f97fd3113 | ||
|
|
5ce6c25393 | ||
|
|
972b258706 | ||
|
|
4ee5250b01 | ||
|
|
3fce092486 | ||
|
|
89d6abbb6c | ||
|
|
8b4ad5e28d | ||
|
|
773b43b1ad | ||
|
|
83fa5a29e8 | ||
|
|
09a231d01f | ||
|
|
2007ae91fb | ||
|
|
8d118308cd | ||
|
|
5a8f2d298f | ||
|
|
1a978c0ab7 | ||
|
|
ce0b1f1785 | ||
|
|
0698b44b68 | ||
|
|
7fefc68061 | ||
|
|
3035ec7e9c | ||
|
|
3a1fe45524 | ||
|
|
2db0748e60 | ||
|
|
d873d6dcf1 | ||
|
|
41e0c51055 | ||
|
|
126370ebdb | ||
|
|
629c0d51b2 | ||
|
|
dc4b5bade0 | ||
|
|
6fc0c32c46 | ||
|
|
b15616cf53 | ||
|
|
519df50404 | ||
|
|
9a71d2b805 | ||
|
|
5f8e8deb5b | ||
|
|
645153113c | ||
|
|
2ba7f41a21 | ||
|
|
c8f21be905 | ||
|
|
1875acb7b5 | ||
|
|
6bdf0d5220 | ||
|
|
ad855b77cd | ||
|
|
a781440252 | ||
|
|
5fc689ee4d | ||
|
|
38d05850e3 | ||
|
|
06d25b6f5b | ||
|
|
55b01cf396 | ||
|
|
49ccd9fef2 | ||
|
|
f877910a73 | ||
|
|
f6f4137332 | ||
|
|
486b717801 | ||
|
|
f2a09ea10e | ||
|
|
cc86e5fadd | ||
|
|
bce29aa31a | ||
|
|
95a1fd1355 | ||
|
|
613b2130a5 | ||
|
|
e4eb3e1192 | ||
|
|
1c4f7f2386 | ||
|
|
a7e4d6e58f | ||
|
|
b9c4f7da1c | ||
|
|
cec79e5b6d | ||
|
|
2f08991eeb | ||
|
|
21859ca6e6 | ||
|
|
27d9a149bc | ||
|
|
a76a079736 | ||
|
|
10341fd3cc | ||
|
|
05de44bc13 | ||
|
|
d2c45f71a0 | ||
|
|
42451a767b | ||
|
|
2692fee6d2 | ||
|
|
cae00d9177 | ||
|
|
eaa1232490 | ||
|
|
8c2550ff1d | ||
|
|
b5b9155bc0 | ||
|
|
3cc8e2b5db | ||
|
|
37032a48c9 | ||
|
|
82fc7fa762 | ||
|
|
749366fff5 | ||
|
|
40dc0ecda3 | ||
|
|
7b7a4b4f65 | ||
|
|
b609253893 | ||
|
|
b0eb1b6389 | ||
|
|
1b515ea904 | ||
|
|
4cabaf3191 | ||
|
|
8cfa28a863 | ||
|
|
3955a3232d | ||
|
|
b93ba6be17 | ||
|
|
39ff4b8867 | ||
|
|
7b7aba6efd | ||
|
|
a42e4287ff | ||
|
|
a757749767 | ||
|
|
5166f41941 | ||
|
|
928f2a7780 | ||
|
|
d46aa6e2b8 | ||
|
|
7cffc3f7bc | ||
|
|
841da3c261 | ||
|
|
adbfd69418 | ||
|
|
1e54b775a2 | ||
|
|
6e82b24578 | ||
|
|
5331efe3c1 | ||
|
|
3b4ad2960a | ||
|
|
33048e185b | ||
|
|
3ae1b94eb7 | ||
|
|
14e6a661d3 | ||
|
|
3d1966a715 | ||
|
|
c173814b8d | ||
|
|
a85397a363 | ||
|
|
2d3987b81e | ||
|
|
875ff95278 | ||
|
|
dcdf0844cb | ||
|
|
27e9de4709 | ||
|
|
e2bdc73b76 | ||
|
|
4f95a1eed4 | ||
|
|
6874e7e92c | ||
|
|
7abb3a6c8a | ||
|
|
9183ba4da5 | ||
|
|
08e2e91e9a | ||
|
|
2966d64455 | ||
|
|
41cb2c2d93 | ||
|
|
edd54ab302 | ||
|
|
51920089af | ||
|
|
5714c54385 | ||
|
|
09d2640345 | ||
|
|
82cb50b7e1 | ||
|
|
ff36dc47c1 | ||
|
|
186f3c3319 | ||
|
|
276adda516 | ||
|
|
ac0ae10fab | ||
|
|
3713669ec5 | ||
|
|
7f0131fc2d | ||
|
|
d9deb589d1 | ||
|
|
c961e9fffd | ||
|
|
ae31b1da0f | ||
|
|
bf5faf53bd | ||
|
|
9a74b448f2 | ||
|
|
784a834214 | ||
|
|
3c5f5cb5f5 | ||
|
|
7c57b7e332 | ||
|
|
4bf91df85f | ||
|
|
50796b22d9 | ||
|
|
2974ddb985 | ||
|
|
54f39103e1 | ||
|
|
8b505ae39a | ||
|
|
d75da655d2 | ||
|
|
e72ea534e5 | ||
|
|
e95d1d782e | ||
|
|
32be5077f9 | ||
|
|
d80fa0b023 | ||
|
|
ea6ee11a4e | ||
|
|
13a87f29d9 | ||
|
|
4e2682a75d | ||
|
|
278d56c58d | ||
|
|
9f71579c78 | ||
|
|
5f8df74b9d | ||
|
|
ebb248969c | ||
|
|
4040741e6f | ||
|
|
4077786ef7 | ||
|
|
ba8394c749 | ||
|
|
97dcc0f0a1 | ||
|
|
8785505a91 | ||
|
|
975beff416 | ||
|
|
45d39069aa | ||
|
|
d3db1e74fa | ||
|
|
4d34eb7adc | ||
|
|
ba4a57512f | ||
|
|
11f4896556 | ||
|
|
44aeb53413 | ||
|
|
d56aa1a778 | ||
|
|
a012396dd4 | ||
|
|
42a1016607 | ||
|
|
4b616896f8 | ||
|
|
54c17f106e | ||
|
|
e171b50868 | ||
|
|
a20c2b556f | ||
|
|
a070a0f64c | ||
|
|
c0608b457c | ||
|
|
927b89554d | ||
|
|
160005e230 | ||
|
|
2848425625 | ||
|
|
c61b497ef2 | ||
|
|
1ece216a27 | ||
|
|
8f6847c060 | ||
|
|
0dc65a53b5 | ||
|
|
7b75a373bd | ||
|
|
fe252b9979 | ||
|
|
f17820e011 | ||
|
|
a21c993cb5 | ||
|
|
dd4afc5ddf | ||
|
|
c220b9e1c8 | ||
|
|
778a498e00 | ||
|
|
48240f2f30 | ||
|
|
e3dfa8dd39 | ||
|
|
6e641395d5 | ||
|
|
fbd09cb570 | ||
|
|
7389909d77 | ||
|
|
ded88383b3 | ||
|
|
1b9b51fbd2 | ||
|
|
afa6dda16f | ||
|
|
994c844f25 | ||
|
|
4551e5dc64 | ||
|
|
ff34e6afab | ||
|
|
a78912260a | ||
|
|
c1e81c546f | ||
|
|
9a950ae37d | ||
|
|
6cec82abd5 | ||
|
|
26616b4cab | ||
|
|
178ec9226d | ||
|
|
0147f525fa | ||
|
|
f0ed6137d1 | ||
|
|
b4ab2c4423 | ||
|
|
5715343651 | ||
|
|
6550be0235 | ||
|
|
99b0dba79f | ||
|
|
2f8d5f1fc8 | ||
|
|
6969f5f93e | ||
|
|
7bbed3890e | ||
|
|
98290c7b28 | ||
|
|
d55006fdda | ||
|
|
b2cc0cb65a | ||
|
|
049827a133 | ||
|
|
b8e4dfdf26 | ||
|
|
8a9d5f92f3 | ||
|
|
b02ab585cb | ||
|
|
c8a5a8627d | ||
|
|
ecf0771f9e | ||
|
|
02c7040b39 | ||
|
|
2cb5d0c0d5 | ||
|
|
9f186afdff | ||
|
|
ec76014ce7 | ||
|
|
e7bc43b339 | ||
|
|
26be8d4565 | ||
|
|
17902c4824 | ||
|
|
115cb86968 | ||
|
|
4a898e40ac | ||
|
|
bdc0286253 | ||
|
|
8bdc305b82 | ||
|
|
7481691b4e | ||
|
|
0d635830f9 | ||
|
|
9b72a7b472 | ||
|
|
031f0d4cce |
@@ -21,5 +21,5 @@ public interface IEnvelopeReceiverRepository : ICRUDRepository<EnvelopeReceiver,
|
||||
|
||||
Task<IEnumerable<EnvelopeReceiver>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
|
||||
|
||||
Task<EnvelopeReceiver?> ReadLastByReceiver(string email);
|
||||
Task<EnvelopeReceiver?> ReadLastByReceiverAsync(string? email = null, int? id = null, string? signature = null);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IDocumentExecutor
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="base64"></param>
|
||||
/// <param name="envelope_uuid"></param>
|
||||
/// <param name="cancellation"></param>
|
||||
/// <returns></returns>
|
||||
Task<EnvelopeDocument> CreateDocumentAsync(string base64, string envelope_uuid, CancellationToken cancellation = default);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Dapper;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IEnvelopeExecutor : ISQLExecutor
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="tfaEnabled"></param>
|
||||
/// <param name="cancellation"></param>
|
||||
/// <returns></returns>
|
||||
Task<Envelope> CreateEnvelopeAsync(int userId, string title = "", string message = "", bool tfaEnabled = false, CancellationToken cancellation = default);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IEnvelopeReceiverExecutor
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelope_uuid"></param>
|
||||
/// <param name="emailAddress"></param>
|
||||
/// <param name="salutation"></param>
|
||||
/// <param name="phone"></param>
|
||||
/// <param name="cancellation"></param>
|
||||
/// <returns></returns>
|
||||
Task<EnvelopeReceiver?> AddEnvelopeReceiverAsync(string envelope_uuid, string emailAddress, string? salutation = null, string? phone = null, CancellationToken cancellation = default);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for executing common queries on a given entity type.
|
||||
/// This interface abstracts away the direct usage of ORM libraries (such as Entity Framework) for querying data
|
||||
/// and provides asynchronous and synchronous operations for querying a collection or single entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity being queried.</typeparam>
|
||||
public interface IQuery<TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves the first entity or a default value if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
|
||||
public Task<TEntity?> FirstOrDefaultAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a single entity or a default value if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
|
||||
public Task<TEntity?> SingleOrDefaultAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a list of entities.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the list of entities.</returns>
|
||||
public Task<IEnumerable<TEntity>> ToListAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves the first entity. Throws an exception if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the first entity.</returns>
|
||||
public Task<TEntity> FirstAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a single entity. Throws an exception if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the single entity.</returns>
|
||||
public Task<TEntity> SingleAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously retrieves the first entity or a default value if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>The first entity or a default value.</returns>
|
||||
public TEntity? FirstOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously retrieves a single entity or a default value if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>The single entity or a default value.</returns>
|
||||
public TEntity? SingleOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously retrieves a list of entities.
|
||||
/// </summary>
|
||||
/// <returns>The list of entities.</returns>
|
||||
public IEnumerable<TEntity> ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously retrieves the first entity. Throws an exception if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>The first entity.</returns>
|
||||
public TEntity First();
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously retrieves a single entity. Throws an exception if no entity is found.
|
||||
/// </summary>
|
||||
/// <returns>The single entity.</returns>
|
||||
public TEntity Single();
|
||||
}
|
||||
20
EnvelopeGenerator.Application/Contracts/SQLExecutor/ISQL.cs
Normal file
20
EnvelopeGenerator.Application/Contracts/SQLExecutor/ISQL.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a raw SQL query contract.
|
||||
/// </summary>
|
||||
public interface ISQL
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the raw SQL query string.
|
||||
/// </summary>
|
||||
string Raw { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a typed SQL query contract for a specific entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity associated with the SQL query.</typeparam>
|
||||
public interface ISQL<TEntity> : ISQL
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
/// Defines methods for executing raw SQL queries or custom SQL query classes and returning query executors for further operations.
|
||||
/// Provides abstraction for raw SQL execution as well as mapping the results to <typeparamref name="TEntity"/> objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
|
||||
public interface ISQLExecutor<TEntity>: ISQLExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <param name="sql">The raw SQL query to execute.</param>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <param name="parameters">Optional parameters for the SQL query.</param>
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
IQuery<TEntity> Execute(string sql, CancellationToken cancellation = default, params object[] parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <param name="parameters">Optional parameters for the SQL query.</param>
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
IQuery<TEntity> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<TEntity>;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Dapper;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface ISQLExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
|
||||
/// <param name="sql">The raw SQL query to execute.</param>
|
||||
/// <param name="parameters">Parameters for the SQL query.</param>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
Task<IEnumerable<TEntity>> Execute<TEntity>(string sql, DynamicParameters parameters, CancellationToken cancellation = default);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
|
||||
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
|
||||
/// <param name="parameters">Parameters for the SQL query.</param>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
Task<IEnumerable<TEntity>> Execute<TEntity, TSQL>(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ using static EnvelopeGenerator.Common.Constants;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
public interface IEnvelopeHistoryService : ICRUDService<EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>
|
||||
public interface IEnvelopeHistoryService : ICRUDService<EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistory, long>
|
||||
{
|
||||
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null);
|
||||
|
||||
|
||||
@@ -4,6 +4,6 @@ using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>
|
||||
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnly, long>
|
||||
{
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using CommandDotNet;
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||
using EnvelopeGenerator.Application.Envelopes;
|
||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||
@@ -25,13 +28,14 @@ public interface IEnvelopeReceiverService : IBasicCRUDService<EnvelopeReceiverDt
|
||||
|
||||
Task<DataResult<bool>> VerifyAccessCodeAsync(string uuid, string signature, string accessCode);
|
||||
|
||||
[Command("verify-access-code-async-by-id")]
|
||||
Task<DataResult<bool>> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode);
|
||||
|
||||
Task<DataResult<bool>> IsExisting(string envelopeReceiverId);
|
||||
|
||||
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
|
||||
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, EnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params int[] ignore_statuses);
|
||||
|
||||
Task<DataResult<string?>> ReadLastUsedReceiverNameByMail(string mail);
|
||||
Task<DataResult<string?>> ReadLastUsedReceiverNameByMailAsync(string? mail = null, int? id = null, string? signature = null);
|
||||
|
||||
Task<DataResult<SmsResponse>> SendSmsAsync(string envelopeReceiverId, string message);
|
||||
Task<DataResult<IEnumerable<EnvelopeReceiverSecretDto>>> ReadWithSecretByUuidAsync(string uuid);
|
||||
|
||||
@@ -6,7 +6,7 @@ using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
public interface IReceiverService : ICRUDService<ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>
|
||||
public interface IReceiverService : ICRUDService<ReceiverCreateDto, ReceiverReadDto, Receiver, int>
|
||||
{
|
||||
Task<DataResult<ReceiverReadDto>> ReadByAsync(string? emailAddress = null, string? signature = null);
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record ConfigDto(
|
||||
string DocumentPath,
|
||||
int SendingProfile,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record DocumentReceiverElementDto(
|
||||
int Id,
|
||||
int DocumentId,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record DocumentStatusDto(
|
||||
int Id,
|
||||
int EnvelopeId,
|
||||
|
||||
@@ -1,10 +1,32 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
public record EmailTemplateDto(
|
||||
int Id,
|
||||
string Name,
|
||||
string Body,
|
||||
string Subject) : IUnique<int>;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EmailTemplateDto : IUnique<int>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Id{ get; init; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Subject { get; set; }
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeCertificateDto(
|
||||
int Id,
|
||||
int EnvelopeId,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeDocumentDto
|
||||
(
|
||||
int Id,
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeDto() : IUnique<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
@@ -19,9 +21,9 @@ namespace EnvelopeGenerator.Application.DTOs
|
||||
|
||||
[TemplatePlaceholder("[MESSAGE]")]
|
||||
public string Message { get; set; }
|
||||
public DateTime? ExpiresWhen { get; set; }
|
||||
public DateTime? ExpiresWarningWhen { get; set; }
|
||||
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[TemplatePlaceholder("[DOCUMENT_TITLE]")]
|
||||
@@ -31,39 +33,24 @@ namespace EnvelopeGenerator.Application.DTOs
|
||||
|
||||
public string Language { get; set; }
|
||||
|
||||
public bool? SendReminderEmails { get; set; }
|
||||
|
||||
public int? FirstReminderDays { get; set; }
|
||||
|
||||
public int? ReminderIntervalDays { get; set; }
|
||||
|
||||
public int? EnvelopeTypeId { get; set; }
|
||||
|
||||
public int? CertificationType { get; set; }
|
||||
|
||||
public bool? UseAccessCode { get; set; }
|
||||
|
||||
public int? FinalEmailToCreator { get; set; }
|
||||
|
||||
public int? FinalEmailToReceivers { get; set; }
|
||||
|
||||
public int? ExpiresWhenDays { get; set; }
|
||||
|
||||
public int? ExpiresWarningWhenDays { get; set; }
|
||||
|
||||
public bool TFAEnabled { get; init; }
|
||||
|
||||
public bool DmzMoved { get; set; }
|
||||
public UserReadDto? User { get; set; }
|
||||
|
||||
public EnvelopeType? EnvelopeType { get; set; }
|
||||
|
||||
public string? EnvelopeTypeTitle { get; set; }
|
||||
|
||||
public bool IsAlreadySent { get; set; }
|
||||
|
||||
public string? StatusTranslated { get; set; }
|
||||
public byte[]? DocResult { get; init; }
|
||||
|
||||
public string? ContractTypeTranslated { get; set; }
|
||||
public IEnumerable<EnvelopeDocumentDto>? Documents { get; set; }
|
||||
public IEnumerable<EnvelopeDocumentDto>? Documents { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeHistoryCreateDto(
|
||||
int EnvelopeId,
|
||||
string UserReference,
|
||||
|
||||
@@ -2,20 +2,35 @@
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using static EnvelopeGenerator.Common.Constants;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||
{
|
||||
public record EnvelopeHistoryDto(
|
||||
long Id,
|
||||
int EnvelopeId,
|
||||
string UserReference,
|
||||
int Status,
|
||||
string? StatusName,
|
||||
DateTime AddedWhen,
|
||||
DateTime? ActionDate,
|
||||
UserCreateDto? Sender,
|
||||
ReceiverReadDto? Receiver,
|
||||
ReferenceType ReferenceType,
|
||||
string? Comment = null) : BaseDTO<long>(Id), IUnique<long>;
|
||||
}
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <param name="EnvelopeId"></param>
|
||||
/// <param name="UserReference"></param>
|
||||
/// <param name="Status"></param>
|
||||
/// <param name="StatusName"></param>
|
||||
/// <param name="AddedWhen"></param>
|
||||
/// <param name="ActionDate"></param>
|
||||
/// <param name="Sender"></param>
|
||||
/// <param name="Receiver"></param>
|
||||
/// <param name="ReferenceType"></param>
|
||||
/// <param name="Comment"></param>
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeHistoryDto(
|
||||
long Id,
|
||||
int EnvelopeId,
|
||||
string UserReference,
|
||||
int Status,
|
||||
string? StatusName,
|
||||
DateTime AddedWhen,
|
||||
DateTime? ActionDate,
|
||||
UserCreateDto? Sender,
|
||||
ReceiverReadDto? Receiver,
|
||||
ReferenceType ReferenceType,
|
||||
string? Comment = null) : BaseDTO<long>(Id), IUnique<long>;
|
||||
@@ -1,8 +1,10 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeReceiverBasicDto() : IUnique<(int Envelope, int Receiver)>
|
||||
{
|
||||
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto()
|
||||
{
|
||||
public EnvelopeDto? Envelope { get; set; }
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeReceiverSecretDto() : EnvelopeReceiverDto()
|
||||
{
|
||||
public string? AccessCode { get; init; }
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeReceiverReadOnlyCreateDto(
|
||||
DateTime DateValid)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeReceiverReadOnlyDto(
|
||||
long Id,
|
||||
long EnvelopeId,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeReceiverReadOnlyUpdateDto(
|
||||
long Id,
|
||||
DateTime DateValid,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EnvelopeTypeDto(
|
||||
int Id,
|
||||
string Title,
|
||||
|
||||
70
EnvelopeGenerator.Application/DTOs/MappingProfile.cs
Normal file
70
EnvelopeGenerator.Application/DTOs/MappingProfile.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the AutoMapper profile configuration for mapping between
|
||||
/// domain entities and data transfer objects (DTOs) used within the EnvelopeGenerator application.
|
||||
/// </summary>
|
||||
public class MappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MappingProfile"/> class.
|
||||
/// Configures the mappings between entities and DTOs used throughout the application.
|
||||
/// </summary>
|
||||
public MappingProfile()
|
||||
{
|
||||
// Entity to DTO mappings
|
||||
CreateMap<Config, ConfigDto>();
|
||||
CreateMap<DocumentReceiverElement, DocumentReceiverElementDto>();
|
||||
CreateMap<DocumentStatus, DocumentStatusDto>();
|
||||
CreateMap<EmailTemplate, EmailTemplateDto>();
|
||||
CreateMap<Envelope, EnvelopeDto>();
|
||||
CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>();
|
||||
CreateMap<EnvelopeDocument, EnvelopeDocumentDto>();
|
||||
CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryDto>();
|
||||
CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryCreateDto>();
|
||||
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverDto>();
|
||||
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverSecretDto>();
|
||||
CreateMap<EnvelopeType, EnvelopeTypeDto>();
|
||||
CreateMap<Domain.Entities.Receiver, ReceiverReadDto>();
|
||||
CreateMap<Domain.Entities.Receiver, ReceiverCreateDto>();
|
||||
CreateMap<Domain.Entities.Receiver, ReceiverUpdateDto>();
|
||||
CreateMap<UserReceiver, UserReceiverDto>();
|
||||
CreateMap<Domain.Entities.EnvelopeReceiverReadOnly, EnvelopeReceiverReadOnlyDto>();
|
||||
|
||||
// DTO to Entity mappings
|
||||
CreateMap<ConfigDto, Config>();
|
||||
CreateMap<DocumentReceiverElementDto, DocumentReceiverElement>();
|
||||
CreateMap<DocumentStatusDto, DocumentStatus>();
|
||||
CreateMap<EmailTemplateDto, EmailTemplate>();
|
||||
CreateMap<EnvelopeDto, Envelope>();
|
||||
CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>();
|
||||
CreateMap<EnvelopeDocumentDto, EnvelopeDocument>();
|
||||
CreateMap<EnvelopeHistoryDto, Domain.Entities.EnvelopeHistory>();
|
||||
CreateMap<EnvelopeHistoryCreateDto, Domain.Entities.EnvelopeHistory>();
|
||||
CreateMap<EnvelopeReceiverDto, Domain.Entities.EnvelopeReceiver>();
|
||||
CreateMap<EnvelopeTypeDto, EnvelopeType>();
|
||||
CreateMap<ReceiverReadDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
|
||||
CreateMap<ReceiverCreateDto, Domain.Entities.Receiver>();
|
||||
CreateMap<ReceiverUpdateDto, Domain.Entities.Receiver>();
|
||||
CreateMap<UserReceiverDto, UserReceiver>();
|
||||
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
|
||||
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
||||
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
||||
|
||||
// Messaging mappings
|
||||
// for GTX messaging
|
||||
CreateMap<GtxMessagingResponse, SmsResponse>()
|
||||
.ConstructUsing(gtxRes => gtxRes.Ok()
|
||||
? new SmsResponse() { Ok = true }
|
||||
: new SmsResponse() { Ok = false, Errors = gtxRes });
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public class GtxMessagingResponse : Dictionary<string, object?> { }
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record SmsResponse
|
||||
{
|
||||
public required bool Ok { get; init; }
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.Receiver
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record ReceiverCreateDto([EmailAddress] string EmailAddress, string? TotpSecretkey = null)
|
||||
{
|
||||
public string Signature => sha256HexOfMail.Value;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record ReceiverReadDto(
|
||||
int Id,
|
||||
string EmailAddress,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record ReceiverUpdateDto(int Id, string? TotpSecretkey = null, DateTime? TfaRegDeadline = null) : IUnique<int>;
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record UserReceiverDto(
|
||||
int Id,
|
||||
int UserId,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using DigitalData.UserManager.Application.MappingProfiles;
|
||||
using EnvelopeGenerator.Application.MappingProfiles;
|
||||
using EnvelopeGenerator.Application.Configurations;
|
||||
using EnvelopeGenerator.Application.Configurations;
|
||||
using EnvelopeGenerator.Application.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -8,11 +6,22 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using DigitalData.Core.Client;
|
||||
using QRCoder;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using System.Reflection;
|
||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Extensions;
|
||||
namespace EnvelopeGenerator.Application;
|
||||
|
||||
public static class DIExtensions
|
||||
/// <summary>
|
||||
/// Extensions method for dependency injection
|
||||
/// </summary>
|
||||
public static class DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds all required services for envelope generator application
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
//Inject CRUD Service and repositoriesad
|
||||
@@ -32,8 +41,8 @@ public static class DIExtensions
|
||||
services.TryAddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
|
||||
|
||||
//Auto mapping profiles
|
||||
services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
||||
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
|
||||
services.AddAutoMapper(Assembly.GetExecutingAssembly());
|
||||
services.AddAutoMapper(typeof(DigitalData.UserManager.Application.DIExtensions));
|
||||
|
||||
services.Configure<DispatcherParams>(config.GetSection(nameof(DispatcherParams)));
|
||||
services.Configure<MailParams>(config.GetSection(nameof(MailParams)));
|
||||
@@ -47,6 +56,12 @@ public static class DIExtensions
|
||||
services.TryAddSingleton<IAuthenticator, Authenticator>();
|
||||
services.TryAddSingleton<QRCodeGenerator>();
|
||||
|
||||
services.AddMediatR(cfg =>
|
||||
{
|
||||
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
|
||||
cfg.RegisterServicesFromAssembly(typeof(CreateEnvelopeReceiverCommandHandler).Assembly);
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadDocumentMappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ReadDocumentMappingProfile()
|
||||
{
|
||||
CreateMap<EnvelopeDocument, ReadDocumentResponse>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a query to read a document based on its unique identifier or associated envelope identifier.
|
||||
/// </summary>
|
||||
/// <param name="Id">The unique identifier of the document. Optional.</param>
|
||||
/// <param name="EnvelopeId">The identifier of the envelope associated with the document. Optional.</param>
|
||||
public record ReadDocumentQuery(int? Id = null, int? EnvelopeId = null) : IRequest<ReadDocumentResponse?>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Handles queries for reading <see cref="EnvelopeDocument"/> data based on either the document ID or the envelope ID.
|
||||
/// </summary>
|
||||
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, ReadDocumentResponse?>
|
||||
{
|
||||
/// <summary>
|
||||
/// Repository for accessing <see cref="EnvelopeDocument"/> entities.
|
||||
/// </summary>
|
||||
private readonly IRepository<EnvelopeDocument> _repo;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReadDocumentQueryHandler"/> class.
|
||||
/// </summary>
|
||||
/// <param name="envelopeDocumentRepository">The repository used to access <see cref="EnvelopeDocument"/> entities.</param>
|
||||
public ReadDocumentQueryHandler(IRepository<EnvelopeDocument> envelopeDocumentRepository)
|
||||
{
|
||||
_repo = envelopeDocumentRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the <see cref="ReadDocumentQuery"/> and returns a <see cref="ReadDocumentResponse"/> based on the provided identifiers.
|
||||
/// </summary>
|
||||
/// <param name="query">The query containing the document ID or envelope ID to search for.</param>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="ReadDocumentResponse"/> if a matching document is found; otherwise, <c>null</c>.
|
||||
/// </returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown when neither <see cref="ReadDocumentQuery.Id"/> nor <see cref="ReadDocumentQuery.EnvelopeId"/> is provided.
|
||||
/// </exception>
|
||||
public async Task<ReadDocumentResponse?> Handle(ReadDocumentQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
if (query.Id is not null)
|
||||
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.Id == query.Id);
|
||||
else if (query.EnvelopeId is not null)
|
||||
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.EnvelopeId == query.EnvelopeId);
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"Invalid {nameof(ReadDocumentQuery)}: either {nameof(query.Id)} or {nameof(query.EnvelopeId)} must be provided.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the response for reading a document.
|
||||
/// </summary>
|
||||
public class ReadDocumentResponse : ReadDocumentResponseBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The binary data of the document, if available.
|
||||
/// </summary>
|
||||
public byte[]? ByteData { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the response for reading a document.
|
||||
/// </summary>
|
||||
public class ReadDocumentResponseBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the document.
|
||||
/// </summary>
|
||||
public int Guid { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The identifier of the associated envelope.
|
||||
/// </summary>
|
||||
public int EnvelopeId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time when the document was added.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using EnvelopeGenerator.Common;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
|
||||
|
||||
/// <summary>
|
||||
/// Ein Befehl zum Zurücksetzen einer E-Mail-Vorlage auf die Standardwerte.
|
||||
/// Erbt von <see cref="EmailTemplateQuery"/> und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage.
|
||||
/// </summary>
|
||||
/// Beispiele:
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.
|
||||
/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.
|
||||
/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.
|
||||
/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </param>
|
||||
public record ResetEmailTemplateCommand : EmailTemplateQuery, IRequest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="orginal"></param>
|
||||
public ResetEmailTemplateCommand(EmailTemplateQuery? orginal = null) : base(orginal ?? new())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Id">Die optionale ID der E-Mail-Vorlage, die zurückgesetzt werden soll.</param>
|
||||
/// <param name="Type">Der Typ der E-Mail-Vorlage, z. B. <see cref="Constants.EmailTemplateType"/> (optional).
|
||||
public ResetEmailTemplateCommand(int? Id = null, Constants.EmailTemplateType? Type = null) : base(Id, Type)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ResetEmailTemplateCommandHandler : IRequestHandler<ResetEmailTemplateCommand>
|
||||
{
|
||||
private readonly IRepository<EmailTemplate> _repository;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public ResetEmailTemplateCommandHandler(IRepository<EmailTemplate> repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task Handle(ResetEmailTemplateCommand request, CancellationToken cancel)
|
||||
{
|
||||
var temps = request.Id is not null
|
||||
? await _repository.ReadAllAsync<EmailTemplateDto>(t => t.Id == request.Id, cancel)
|
||||
: request.Type is not null
|
||||
? await _repository.ReadAllAsync<EmailTemplateDto>(t => t.Name == request.Type.ToString(), cancel)
|
||||
: await _repository.ReadAllAsync<EmailTemplateDto>(ct: cancel);
|
||||
|
||||
foreach (var temp in temps)
|
||||
{
|
||||
var def = Defaults.Where(t => t.Name == temp.Name).FirstOrDefault();
|
||||
if(def is not null)
|
||||
await _repository.UpdateAsync(def, t => t.Id == temp.Id, cancel);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly IEnumerable<EmailTemplateDto> Defaults = new List<EmailTemplateDto>()
|
||||
{
|
||||
new(){
|
||||
Id = 1,
|
||||
Name = "DocumentReceived",
|
||||
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br /><B><I>\r\n[NAME_SENDER]</I></B> hat Ihnen ein Dokument zum [SIGNATURE_TYPE] gesendet.<br />\r\n<br />\r\nÜber den folgenden Link können Sie das Dokument einsehen und elektronisch unterschreiben: <a href=\"[LINK_TO_DOCUMENT]\">[LINK_TO_DOCUMENT_TEXT]</a><br />\r\n<br />\r\n[MESSAGE]<br />\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "Dokument erhalten: '[DOCUMENT_TITLE]'"
|
||||
},
|
||||
new(){
|
||||
Id = 2,
|
||||
Name = "DocumentDeleted",
|
||||
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br /><B><I>\r\n[NAME_SENDER]</I></B> hat den Umschlag <B><I>'[DOCUMENT_TITLE]'</I></B> gelöscht/zurückgezogen.<br /><p>\rBegründung: <br /> <I>[REASON]</I> <p>\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "Umschlag zurückgezogen: '[DOCUMENT_TITLE]'"
|
||||
},
|
||||
new(){
|
||||
Id = 3,
|
||||
Name = "DocumentSigned",
|
||||
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br />\r\nhiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'[DOCUMENT_TITLE]'</I></B>.<br />\r\nWenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "Dokument unterschrieben: '[DOCUMENT_TITLE]'"
|
||||
},
|
||||
new(){
|
||||
Id = 4,
|
||||
Name = "DocumentCompleted",
|
||||
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br />\r\nDer Signaturvorgang <B><I>'[DOCUMENT_TITLE]'</I></B> wurde erfolgreich abgeschlossen.<br />\r\n<br />\r\nSie erhalten das Dokument mit einem detaillierten Ergebnisbericht als Anhang zu dieser Email.<br />\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "Umschlag abgeschlossen: '[DOCUMENT_TITLE]'"
|
||||
},
|
||||
new(){
|
||||
Id = 5,
|
||||
Name = "DocumentAccessCodeReceived",
|
||||
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br /><B><I>\r\n[NAME_SENDER]</I></B> hat Ihnen ein Dokument zum [SIGNATURE_TYPE] gesendet. <br />\r\n<br />\r\nVerwenden Sie den folgenden Zugriffscode, um das Dokument einzusehen:<br />\r\n<br />\r\n[DOCUMENT_ACCESS_CODE]<br />\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "Zugriffscode für Dokument erhalten: '[DOCUMENT_TITLE]'"
|
||||
},
|
||||
new(){
|
||||
Id = 6,
|
||||
Name = "DocumentRejected_ADM",
|
||||
Body = "Guten Tag [NAME_SENDER],<p><B><I>[NAME_RECEIVER]</I></B> hat den Umschlag <B><I>'[DOCUMENT_TITLE]'</I></B> mit folgendem Grund abgelehnt: <p>\r\n[REASON] \r\n<p>Der Umschlag wurde auf den Status Rejected gesetzt. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "'[DOCUMENT_TITLE]' - Unterzeichnungsvorgang zurückgezogen"
|
||||
},
|
||||
new(){
|
||||
Id = 9,
|
||||
Name = "DocumentRejected_REC",
|
||||
Body = "Guten Tag [NAME_RECEIVER],\r\n<p>Hiermit bestätigen wir Ihnen die Ablehnung des Unterzeichnungsvorganges <B><I>'[DOCUMENT_TITLE]'</I></B>!<p>Der Vertragsinhaber <B><I>[NAME_SENDER]</I></B> wurde über die Ablehnung informiert. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "'[DOCUMENT_TITLE]' - Bestätigung Ablehnung"
|
||||
},
|
||||
new(){
|
||||
Id = 10,
|
||||
Name = "DocumentRejected_REC_2",
|
||||
Body = "Guten Tag [NAME_RECEIVER],\r\n<p>Der Unterzeichnungsvorganges <B><I>'[DOCUMENT_TITLE]'</I></B> wurde durch einen anderen Vertragspartner abgelehnt! Ihre notwendige Unterzeichnung wurde verworfen.<p> Der Vertragsinhaber <B><I>[NAME_SENDER]</I></B> wird sich bei Bedarf mit Ihnen in Verbindung setzen. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
|
||||
Subject = "'[DOCUMENT_TITLE]' - Unterzeichnungsvorgang abgelehnt."
|
||||
},
|
||||
new(){
|
||||
Id = 11,
|
||||
Name = "DocumentShared",
|
||||
Body = "Guten Tag,<br /> <br /><B><I> [NAME_RECEIVER]</I></B> hat Ihnen ein Dokument zum Ansehen gesendet.<br /> <br /> Über den folgenden Link können Sie das Dokument einsehen: <a href=\"[LINK_TO_DOCUMENT]\">[LINK_TO_DOCUMENT_TEXT]</a><br /> <br /> <br /> Mit freundlichen Grüßen<br /> <br /> [NAME_PORTAL]",
|
||||
Subject = "Dokument geteilt: '[DOCUMENT_TITLE]'"
|
||||
},
|
||||
new(){
|
||||
Id = 12,
|
||||
Name = "TotpSecret",
|
||||
Body = "Guten Tag,<br /> <br />Sie können auf Ihren Zwei-Faktor-Authentifizierungscode zugreifen, indem Sie den unten stehenden QR-Code mit einer beliebigen Authentifizierungs-App auf Ihrem Telefon scannen (Google Authenticator, Microsoft Authenticator usw.). Dieser Code ist bis zum [TFA_EXPIRATION] gültig.<br /> <br /> <img src=\"data:image/png;base64,[TFA_QR_CODE]\" style=\"width: 13rem; height: 13rem;\"><br /> <br />\r\n<br /> Mit freundlichen Grüßen<br /> <br /> [NAME_PORTAL]",
|
||||
Subject = "2-Faktor-Verifizierung QR-Code"
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using MediatR;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zum Aktualisieren einer E-Mail-Vorlage.
|
||||
/// </summary>
|
||||
/// <param name="Body">
|
||||
/// (Optional)Der neue Inhalt des E-Mail-Textkörpers. Wenn null, bleibt der vorhandene Inhalt unverändert.
|
||||
/// </param>
|
||||
/// <param name="Subject">
|
||||
/// (Optional) Der neue Betreff der E-Mail. Wenn null, bleibt der vorhandene Betreff unverändert.
|
||||
/// </param>
|
||||
public record UpdateEmailTemplateCommand(string? Body = null, string? Subject = null) : IRequest
|
||||
{
|
||||
/// <param>
|
||||
/// Die Abfrage, die die E-Mail-Vorlage darstellt, die aktualisiert werden soll.
|
||||
/// </param>
|
||||
[JsonIgnore]
|
||||
public EmailTemplateQuery? EmailTemplateQuery { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public DateTime ChangedWhen { get; init; } = DateTime.Now;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Application.Exceptions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemplateCommand>
|
||||
{
|
||||
private readonly IRepository<EmailTemplate> _repository;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
/// <exception cref="NotFoundException"></exception>
|
||||
public async Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel)
|
||||
{
|
||||
EmailTemplateDto? temp;
|
||||
|
||||
if (request.EmailTemplateQuery?.Id is int id)
|
||||
{
|
||||
temp = await _repository.ReadOrDefaultAsync<EmailTemplateDto>(t => t.Id == id, single: false, cancel);
|
||||
}
|
||||
else if (request!.EmailTemplateQuery!.Type is Common.Constants.EmailTemplateType type)
|
||||
{
|
||||
temp = await _repository.ReadOrDefaultAsync<EmailTemplateDto>(t => t.Name == type.ToString(), single: false, cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Both id and type is null. Id: " + request.EmailTemplateQuery.Id +". Type: " + request.EmailTemplateQuery.Type.ToString());
|
||||
}
|
||||
|
||||
if (temp == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (request.Body is not null)
|
||||
temp.Body = request.Body;
|
||||
|
||||
if (request.Subject is not null)
|
||||
temp.Subject = request.Subject;
|
||||
|
||||
await _repository.UpdateAsync(temp, t => t.Id == temp.Id, cancel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using EnvelopeGenerator.Common;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates;
|
||||
|
||||
/// <summary>
|
||||
/// Repräsentiert eine Abfrage für E-Mail-Vorlagen, die für Absender und Empfänger von Umschlägen verwendet werden.
|
||||
/// Die Standardkultur ist "de-DE".
|
||||
/// </summary>
|
||||
/// <param name="Id">Die eindeutige Kennung der E-Mail-Vorlage (optional).</param>
|
||||
/// <param name="Type">Der Typ der E-Mail-Vorlage, z. B. <see cref="Constants.EmailTemplateType"/> (optional). Beispiele:
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.
|
||||
/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.
|
||||
/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.
|
||||
/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </param>
|
||||
public record EmailTemplateQuery(int? Id = null, Constants.EmailTemplateType? Type = null)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadEmailTemplateMappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ReadEmailTemplateMappingProfile()
|
||||
{
|
||||
CreateMap<EmailTemplate, ReadEmailTemplateResponse>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen.
|
||||
/// Diese Klasse erbt von <see cref="EmailTemplateQuery"/>.
|
||||
/// </summary>
|
||||
public record ReadEmailTemplateQuery : EmailTemplateQuery, IRequest<ReadEmailTemplateResponse?>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Common;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQuery, ReadEmailTemplateResponse?>
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly IEmailTemplateRepository _repository;
|
||||
|
||||
/// <summary>
|
||||
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||
/// </summary>
|
||||
/// <param name="mapper">
|
||||
/// <param name="repository">
|
||||
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
||||
/// </param>
|
||||
public ReadEmailTemplateQueryHandler(IMapper mapper, IEmailTemplateRepository repository)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public async Task<ReadEmailTemplateResponse?> Handle(ReadEmailTemplateQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var temp = request.Id is int id
|
||||
? await _repository.ReadByIdAsync(id)
|
||||
: request.Type is Constants.EmailTemplateType type
|
||||
? await _repository.ReadByNameAsync(type)
|
||||
: throw new InvalidOperationException("Either a valid integer ID or a valid EmailTemplateType must be provided in the request.");
|
||||
|
||||
var res = _mapper.Map<ReadEmailTemplateResponse>(temp);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt die Antwort für eine Abfrage von E-Mail-Vorlagen bereit.
|
||||
/// </summary>
|
||||
public class ReadEmailTemplateResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung der E-Mail-Vorlage.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name des Typs
|
||||
/// </summary>
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.
|
||||
/// </summary>
|
||||
public string? Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Betreff der E-Mail-Vorlage. Kann null sein.
|
||||
/// </summary>
|
||||
public string? Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.
|
||||
/// </summary>
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -11,22 +13,25 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.2.1" />
|
||||
<PackageReference Include="DigitalData.Core.Application" Version="2.0.0" />
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
|
||||
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||
<PackageReference Include="DigitalData.Core.Client" Version="2.0.3" />
|
||||
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.0" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="2.0.0" />
|
||||
<PackageReference Include="MediatR" Version="11.1.0" />
|
||||
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
||||
<PackageReference Include="MediatR" Version="12.5.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.1" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
<PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" />
|
||||
<PackageReference Include="UserManager.Application" Version="2.0.0" />
|
||||
<PackageReference Include="UserManager.Infrastructure" Version="2.0.0" />
|
||||
<PackageReference Include="UserManager" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Extensions\EnvelopeGenerator.Extensions.csproj" />
|
||||
</ItemGroup>
|
||||
@@ -58,4 +63,25 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="CommandDotNet">
|
||||
<Version>7.0.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="CommandDotNet">
|
||||
<Version>8.1.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="CommandDotNet">
|
||||
<Version>8.1.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
using MediatR;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
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="Name">Der Name, mit dem der Käufer 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 ReceiverGetOrCreateDto([Required] IEnumerable<Signature> Signatures, string? Name = 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.ToLower(); }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// DTO für die Erstellung eines Dokuments.
|
||||
/// </summary>
|
||||
public record DocumentCreateDto(byte[]? DataAsByte = null, string? DataAsBase64 = null);
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zur Erstellung eines Umschlags.
|
||||
/// </summary>
|
||||
public record CreateEnvelopeCommand(
|
||||
[Required] string Title,
|
||||
[Required] string Message,
|
||||
[Required] DocumentCreateDto Document,
|
||||
[Required] IEnumerable<ReceiverGetOrCreateDto> Receivers,
|
||||
string Language = "de-DE",
|
||||
DateTime? ExpiresWhen = null,
|
||||
DateTime? ExpiresWarningWhen = null,
|
||||
int ContractType = (int)Common.Constants.ContractType.Contract,
|
||||
bool TFAEnabled = false
|
||||
) : IRequest;
|
||||
@@ -0,0 +1,21 @@
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
using MediatR;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zur Erstellung eines Umschlags.
|
||||
/// </summary>
|
||||
/// <param name="Title">Der Titel des Umschlags. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="Message">Die Nachricht, die im Umschlag enthalten sein soll. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="Document">Das mit dem Umschlag verknüpfte Dokument. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="Receivers">Eine Sammlung von Empfängern, die den Umschlag erhalten. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung für den Umschlag aktiviert ist. Standardmäßig false.</param>
|
||||
public record CreateEnvelopeReceiverCommand(
|
||||
[Required] string Title,
|
||||
[Required] string Message,
|
||||
[Required] DocumentCreateCommand Document,
|
||||
[Required] IEnumerable<ReceiverGetOrCreateCommand> Receivers,
|
||||
bool TFAEnabled = false
|
||||
) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest<CreateEnvelopeReceiverResponse?>;
|
||||
@@ -0,0 +1,67 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the creation of an envelope along with its associated document and recipients.
|
||||
/// This command processes the envelope data, including title, message, document content,
|
||||
/// recipient list, and optional two-factor authentication settings.
|
||||
/// </summary>
|
||||
public class CreateEnvelopeReceiverCommandHandler : IRequestHandler<CreateEnvelopeReceiverCommand, CreateEnvelopeReceiverResponse>
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly IEnvelopeExecutor _envelopeExecutor;
|
||||
|
||||
private readonly IEnvelopeReceiverExecutor _erExecutor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="envelopeExecutor"></param>
|
||||
/// <param name="erExecutor"></param>
|
||||
public CreateEnvelopeReceiverCommandHandler(IMapper mapper, IEnvelopeExecutor envelopeExecutor, IEnvelopeReceiverExecutor erExecutor)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_envelopeExecutor = envelopeExecutor;
|
||||
_erExecutor = erExecutor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the execution of the <see cref="CreateEnvelopeReceiverCommand"/>.
|
||||
/// Responsible for validating input data, creating or retrieving recipients, associating signatures,
|
||||
/// and storing the envelope and document details.
|
||||
/// </summary>
|
||||
/// <param name="request">The command containing all necessary information to create an envelope.</param>
|
||||
/// <param name="cancel">Token to observe while waiting for the task to complete.</param>
|
||||
/// <returns>A task representing the asynchronous operation.</returns>
|
||||
public async Task<CreateEnvelopeReceiverResponse> Handle(CreateEnvelopeReceiverCommand request, CancellationToken cancel)
|
||||
{
|
||||
int userId = request.UserId ?? throw new InvalidOperationException("UserId cannot be null when creating an envelope.");
|
||||
|
||||
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.UnsentReceivers = unsentRecipients;
|
||||
res.SentReceiver = _mapper.Map<IEnumerable<ReceiverReadDto>>(sentRecipients);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
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] double X, [Required] double 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 string EmailAddress { get => _emailAddress.ToLower(); init => _emailAddress = value.ToLower(); }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// DTO zum Erstellen eines Dokuments.
|
||||
/// </summary>
|
||||
public record DocumentCreateCommand()
|
||||
{
|
||||
/// <summary>
|
||||
/// Die Dokumentdaten im Base64-String-Format. Wird verwendet, wenn das Dokument als Base64-codierter String bereitgestellt wird.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string DataAsBase64 { get; init; }
|
||||
};
|
||||
#endregion
|
||||
@@ -0,0 +1,21 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateEnvelopeReceiverMappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public CreateEnvelopeReceiverMappingProfile()
|
||||
{
|
||||
CreateMap<Envelope, CreateEnvelopeResponse>();
|
||||
CreateMap<Receiver, ReceiverReadDto>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record CreateEnvelopeReceiverResponse : CreateEnvelopeResponse
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <param name="UserId"></param>
|
||||
/// <param name="Status"></param>
|
||||
/// <param name="Uuid"></param>
|
||||
/// <param name="Message"></param>
|
||||
/// <param name="AddedWhen"></param>
|
||||
/// <param name="ChangedWhen"></param>
|
||||
/// <param name="Title"></param>
|
||||
/// <param name="Language"></param>
|
||||
/// <param name="TFAEnabled"></param>
|
||||
/// <param name="User"></param>
|
||||
public CreateEnvelopeReceiverResponse(int Id, int UserId, int Status, string Uuid, string? Message, DateTime AddedWhen, DateTime? ChangedWhen, string? Title, string Language, bool TFAEnabled, User User) : base(Id, UserId, Status, Uuid, Message, AddedWhen, ChangedWhen, Title, Language, TFAEnabled, User)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<ReceiverReadDto> SentReceiver { get; set; } = new List<ReceiverReadDto>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<ReceiverGetOrCreateCommand> UnsentReceivers { get; set; } = new List<ReceiverGetOrCreateCommand>();
|
||||
}
|
||||
@@ -1,16 +1,47 @@
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
using EnvelopeGenerator.Application.Histories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Abfrage zum Lesen eines Envelope-Empfängers dar.
|
||||
/// Stellt eine Abfrage für einen Envelope-Empfänger dar.
|
||||
/// </summary>
|
||||
/// <param name="MinStatus"></param>
|
||||
/// <param name="MaxStatus"></param>
|
||||
/// <param name="IgnoreStatus"></param>
|
||||
/// <param name="Receiver"></param>
|
||||
public record EnvelopeReceiverQuery(
|
||||
int? MinStatus = null,
|
||||
int? MaxStatus = null,
|
||||
int[]? IgnoreStatus = null);
|
||||
/// <param name="Status">Der Status der Abfrage, optional.</param>
|
||||
public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null);
|
||||
|
||||
/// <summary>
|
||||
/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Common.Constants.EnvelopeStatus"/>
|
||||
/// Invalid (0): Ungültiger Status.
|
||||
/// EnvelopeCreated (1001): Der Umschlag wurde erstellt.
|
||||
/// EnvelopeSaved (1002): Der Umschlag wurde gespeichert.
|
||||
/// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant.
|
||||
/// EnvelopeSent (1004): Der Umschlag wurde versendet. (Nicht verwendet)
|
||||
/// EnvelopePartlySigned (1005): Der Umschlag wurde teilweise unterschrieben.
|
||||
/// EnvelopeCompletelySigned (1006): Der Umschlag wurde vollständig unterschrieben.
|
||||
/// EnvelopeReportCreated (1007): Ein Abschlussbericht wurde für den Umschlag erstellt.
|
||||
/// EnvelopeArchived (1008): Der Umschlag wurde archiviert.
|
||||
/// EnvelopeDeleted (1009): Der Umschlag wurde gelöscht.
|
||||
/// AccessCodeRequested (2001): Der Zugriffscode wurde angefordert.
|
||||
/// AccessCodeCorrect (2002): Der Zugriffscode war korrekt.
|
||||
/// AccessCodeIncorrect (2003): Der Zugriffscode war falsch.
|
||||
/// DocumentOpened (2004): Das Dokument wurde geöffnet.
|
||||
/// DocumentSigned (2005): Ein Dokument wurde unterschrieben.
|
||||
/// SignatureConfirmed (2006): Die Signatur wurde bestätigt.
|
||||
/// DocumentRejected (2007): Ein Dokument wurde abgelehnt.
|
||||
/// EnvelopeShared (2008): Der Umschlag wurde geteilt.
|
||||
/// EnvelopeViewed (2009): Der Umschlag wurde angesehen.
|
||||
/// DocumentForwarded (4001): Das Dokument wurde weitergeleitet.
|
||||
/// MessageInvitationSent (3001): Einladung wurde gesendet (vom Trigger verwendet).
|
||||
/// MessageAccessCodeSent (3002): Zugriffscode wurde gesendet.
|
||||
/// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet.
|
||||
/// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet.
|
||||
/// MessageCompletionSent (3005): Abschlussbenachrichtigung wurde gesendet.
|
||||
/// <param name="Min">Der minimale Statuswert, der berücksichtigt werden soll.</param>
|
||||
/// <param name="Max">Der maximale Statuswert, der berücksichtigt werden soll.</param>
|
||||
/// <param name="Ignore">Eine Liste von Statuswerten, die ignoriert werden sollen.</param>
|
||||
/// </summary>
|
||||
public record EnvelopeStatusQuery(
|
||||
int? Min = null,
|
||||
int? Max = null,
|
||||
int[]? Ignore = null)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
using EnvelopeGenerator.Application.Histories;
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Abfrage zum Lesen eines Envelope-Empfängers dar.
|
||||
/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers.
|
||||
/// </summary>
|
||||
public record ReadEnvelopeReceiverQuery : EnvelopeReceiverQuery, IRequest<ReadEnvelopeReceiverResponse>
|
||||
/// <remarks>
|
||||
/// Diese Abfrage kombiniert Informationen über einen Umschlag (<see cref="ReadEnvelopeQuery"/>)
|
||||
/// und einen Empfänger (<see cref="ReadReceiverQuery"/>), um eine vollständige Antwort
|
||||
/// (<see cref="ReadEnvelopeReceiverResponse"/>) zu generieren.
|
||||
/// Die Antwort enthält Details wie den Status, die Zuordnung zwischen Umschlag und Empfänger
|
||||
/// sowie zusätzliche Metadaten.
|
||||
/// </remarks>
|
||||
/// <param name="Status">Umschlag oder Empfängerstatus.</param>
|
||||
public record ReadEnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null) : EnvelopeReceiverQuery(Status), IRequest<ReadEnvelopeReceiverResponse>
|
||||
{
|
||||
/// <summary>
|
||||
/// Der Umschlag, der mit dem Empfänger verknüpft ist.
|
||||
/// </summary>
|
||||
public ReadEnvelopeQuery? Envelope { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Empfänger, der mit dem Umschlag verknüpft ist.
|
||||
/// </summary>
|
||||
public ReadReceiverQuery? Receiver { get; init; }
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,40 +7,88 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Antwort auf die Abfrage zum Lesen eines Envelope-Empfängers dar.
|
||||
/// Repräsentiert die Antwort für das Lesen eines Envelope-Empfängers.
|
||||
/// </summary>
|
||||
/// <param name="Receiver">Der angeforderte Empfänger.</param>
|
||||
/// <remarks>
|
||||
/// Diese Klasse enthält Informationen über einen spezifischen Empfänger eines Umschlags (Envelope).
|
||||
/// Sie verknüpft die Empfängerinformationen mit den zugehörigen Umschlagsdaten und bietet zusätzliche Metadaten.
|
||||
/// </remarks>
|
||||
/// <param name="UserId">Die eindeutige Kennung des Benutzers, der den Empfänger erstellt hat.</param>
|
||||
/// <param name="Status">Der Status des Empfängers als numerischer Wert.</param>
|
||||
public record ReadEnvelopeReceiverResponse(int UserId, int Status)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gibt die zusammengesetzte Kennung des Empfängers zurück, bestehend aus der Umschlags-ID und der Empfänger-ID.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Diese Eigenschaft kombiniert die eindeutige Kennung des Umschlags (EnvelopeId) und die des Empfängers (ReceiverId)
|
||||
/// zu einer einzigen, leicht zugänglichen Struktur.
|
||||
/// </remarks>
|
||||
[NotMapped]
|
||||
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
||||
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung des zugehörigen Umschlags.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int EnvelopeId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung des Empfängers.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int ReceiverId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Die Reihenfolge des Empfängers innerhalb des Umschlags.
|
||||
/// </summary>
|
||||
public int Sequence { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Name des Empfängers. Kann als Platzhalter verwendet werden.
|
||||
/// </summary>
|
||||
[TemplatePlaceholder("[NAME_RECEIVER]")]
|
||||
public string? Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Die Berufsbezeichnung des Empfängers.
|
||||
/// </summary>
|
||||
public string? JobTitle { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Firmenname des Empfängers.
|
||||
/// </summary>
|
||||
public string? CompanyName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Eine private Nachricht, die mit dem Empfänger verknüpft ist.
|
||||
/// </summary>
|
||||
public string? PrivateMessage { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann der Empfänger zuletzt geändert wurde (falls vorhanden).
|
||||
/// </summary>
|
||||
public DateTime? ChangedWhen { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gibt an, ob der Empfänger eine Telefonnummer hat.
|
||||
/// </summary>
|
||||
public bool HasPhoneNumber { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Die zugehörigen Umschlagsdaten.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required ReadEnvelopeResponse Envelope { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Die Liste der Empfängerinformationen.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public IEnumerable<ReadReceiverResponse> Receiver { get; init; } = new List<ReadReceiverResponse>();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zur Erstellung eines Umschlags.
|
||||
/// </summary>
|
||||
/// <param name="Title">Der Titel des Umschlags. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="Message">Die Nachricht, die im Umschlag enthalten sein soll. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung für den Umschlag aktiviert ist. Standardmäßig false.</param>
|
||||
public record CreateEnvelopeCommand(
|
||||
[Required] string Title,
|
||||
[Required] string Message,
|
||||
bool TFAEnabled = false
|
||||
) : IRequest<CreateEnvelopeResponse?>
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of receiver
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[BindNever]
|
||||
public int? UserId { get; set; }
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?>
|
||||
{
|
||||
private readonly IEnvelopeExecutor _envelopeExecutor;
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeExecutor"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public CreateEnvelopeCommandHandler(IEnvelopeExecutor envelopeExecutor, IMapper mapper)
|
||||
{
|
||||
_envelopeExecutor = envelopeExecutor;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<CreateEnvelopeResponse?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
int userId = request.UserId ?? throw new InvalidOperationException("UserId cannot be null when creating an envelope.");
|
||||
|
||||
var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancellationToken);
|
||||
|
||||
return _mapper.Map<CreateEnvelopeResponse>(envelope);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateEnvelopeMappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public CreateEnvelopeMappingProfile()
|
||||
{
|
||||
CreateMap<Envelope, CreateEnvelopeReceiverResponse>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Id"><inheritdoc/></param>
|
||||
/// <param name="UserId"><inheritdoc/></param>
|
||||
/// <param name="Status"><inheritdoc/></param>
|
||||
/// <param name="Uuid"><inheritdoc/></param>
|
||||
/// <param name="Message"><inheritdoc/></param>
|
||||
/// <param name="AddedWhen"><inheritdoc/></param>
|
||||
/// <param name="ChangedWhen"><inheritdoc/></param>
|
||||
/// <param name="Title"><inheritdoc/></param>
|
||||
/// <param name="Language"><inheritdoc/></param>
|
||||
/// <param name="TFAEnabled"><inheritdoc/></param>
|
||||
/// <param name="User"><inheritdoc/></param>
|
||||
public record CreateEnvelopeResponse(int Id, int UserId, int Status, string Uuid, string? Message, DateTime AddedWhen, DateTime? ChangedWhen, string? Title, string Language, bool TFAEnabled, DigitalData.UserManager.Domain.Entities.User User)
|
||||
: ReadEnvelopeResponse(Id, UserId, Status, Uuid, Message, AddedWhen, ChangedWhen, Title, Language, TFAEnabled, User);
|
||||
@@ -6,15 +6,11 @@ namespace EnvelopeGenerator.Application.Envelopes;
|
||||
/// Repräsentiert eine Abfrage für Umschläge.
|
||||
/// </summary>
|
||||
/// <param name="Id">Die eindeutige Kennung des Umschlags.</param>
|
||||
/// <param name="UserId">Die Kennung des Benutzers, der den Umschlag erstellt hat.</param>
|
||||
/// <param name="Username">Der Benutzername des Benutzers, der den Umschlag erstellt hat.</param>
|
||||
/// <param name="Email">Die E-Mail-Adresse des Benutzers, der den Umschlag erstellt hat.</param>
|
||||
/// <param name="Status">Der Status des Umschlags.</param>
|
||||
/// <param name="Uuid">Die universell eindeutige Kennung des Umschlags.</param>
|
||||
public record EnvelopeQuery(
|
||||
int? Id = null,
|
||||
int? UserId = null,
|
||||
string? Username = null,
|
||||
string? Email = null,
|
||||
int? Status = null,
|
||||
string? Uuid = null) : IRequest;
|
||||
string? Uuid = null) : IRequest
|
||||
{
|
||||
};
|
||||
@@ -2,7 +2,35 @@
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
|
||||
public record ReadEnvelopeResponse(int Id, int UserId, int Status, string Uuid, string? Message, DateTime AddedWhen, DateTime? ChangedWhen, string? Title, string Language, bool TFAEnabled, DigitalData.UserManager.Domain.Entities.User User)
|
||||
/// <summary>
|
||||
/// Repräsentiert die Antwort für das Lesen eines Umschlags.
|
||||
/// </summary>
|
||||
/// <param name="Id">Die eindeutige Kennung des Umschlags.</param>
|
||||
/// <param name="UserId">Die Kennung des Benutzers, der den Umschlag erstellt hat.</param>
|
||||
/// <param name="Status">Der Status des Umschlags als numerischer Wert.</param>
|
||||
/// <param name="Uuid">Die universelle eindeutige Kennung (UUID) des Umschlags.</param>
|
||||
/// <param name="Message">Eine optionale Nachricht, die mit dem Umschlag verknüpft ist.</param>
|
||||
/// <param name="AddedWhen">Das Datum und die Uhrzeit, wann der Umschlag hinzugefügt wurde.</param>
|
||||
/// <param name="ChangedWhen">Das Datum und die Uhrzeit, wann der Umschlag zuletzt geändert wurde (falls vorhanden).</param>
|
||||
/// <param name="Title">Ein optionaler Titel des Umschlags.</param>
|
||||
/// <param name="Language">Die Sprache, die mit dem Umschlag verknüpft ist.</param>
|
||||
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung (TFA) aktiviert ist.</param>
|
||||
/// <param name="User">Das Benutzerobjekt, das mit dem Umschlag verknüpft ist.</param>
|
||||
public record ReadEnvelopeResponse(
|
||||
int Id,
|
||||
int UserId,
|
||||
int Status,
|
||||
string Uuid,
|
||||
string? Message,
|
||||
DateTime AddedWhen,
|
||||
DateTime? ChangedWhen,
|
||||
string? Title,
|
||||
string Language,
|
||||
bool TFAEnabled,
|
||||
DigitalData.UserManager.Domain.Entities.User User)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gibt den Namen des Status zurück, der dem numerischen Statuswert entspricht.
|
||||
/// </summary>
|
||||
public string StatusName => ((Constants.EnvelopeStatus)Status).ToString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Queries.ReceiverName;
|
||||
|
||||
/// <summary>
|
||||
/// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln,
|
||||
/// damit diese für zukünftige Umschläge wiederverwendet werden kann.
|
||||
/// </summary>
|
||||
public record ReadReceiverNameQuery() : ReadReceiverQuery
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace EnvelopeGenerator.Application.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an exception that is thrown when a bad request is encountered.
|
||||
/// </summary>
|
||||
public class BadRequestException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BadRequestException"/> class.
|
||||
/// </summary>
|
||||
public BadRequestException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BadRequestException"/> class with a specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public BadRequestException(string? message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace EnvelopeGenerator.Application.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an exception that is thrown when a requested resource is not found.
|
||||
/// </summary>
|
||||
public class NotFoundException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotFoundException"/> class.
|
||||
/// </summary>
|
||||
public NotFoundException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotFoundException"/> class with a specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public NotFoundException(string? message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Histories.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadHistoryMappingProfile: Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ReadHistoryMappingProfile()
|
||||
{
|
||||
CreateMap<EnvelopeHistory, ReadHistoryResponse>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using EnvelopeGenerator.Common;
|
||||
using MediatR;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Histories.Queries.Read;
|
||||
|
||||
//TODO: Add sender query
|
||||
/// <summary>
|
||||
/// Repräsentiert eine Abfrage für die Verlaufshistorie eines Umschlags.
|
||||
/// </summary>
|
||||
/// <param name="EnvelopeId">Die eindeutige Kennung des Umschlags.</param>
|
||||
/// <param name="Status">Der Status des Umschlags, der abgefragt werden soll. Kann optional angegeben werden, um die Ergebnisse zu filtern.</param>
|
||||
/// <param name="OnlyLast">Abfrage zur Steuerung, ob nur der aktuelle Status oder der gesamte Datensatz zurückgegeben wird.</param>
|
||||
public record ReadHistoryQuery(
|
||||
[Required]
|
||||
int EnvelopeId,
|
||||
Constants.EnvelopeStatus? Status = null,
|
||||
bool? OnlyLast = true) : IRequest<IEnumerable<ReadHistoryResponse>>
|
||||
{
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using EnvelopeGenerator.Application.Exceptions;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Histories.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadHistoryQueryHandler : IRequestHandler<ReadHistoryQuery, IEnumerable<ReadHistoryResponse>>
|
||||
{
|
||||
private readonly IEnvelopeHistoryRepository _repository;
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public ReadHistoryQueryHandler(IEnvelopeHistoryRepository repository, IMapper mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotFoundException"></exception>
|
||||
public async Task<IEnumerable<ReadHistoryResponse>> Handle(ReadHistoryQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var hists = await _repository.ReadAsync(request.EnvelopeId, status: request.Status is null ? null : (int) request.Status);
|
||||
|
||||
if (!hists.Any())
|
||||
throw new NotFoundException();
|
||||
|
||||
return _mapper.Map<IEnumerable<ReadHistoryResponse>>(hists);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using EnvelopeGenerator.Common;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Histories.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the history of an envelope, including its status, user actions, and references.
|
||||
/// </summary>
|
||||
public class ReadHistoryResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique identifier of the envelope history record.
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier of the associated envelope.
|
||||
/// </summary>
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reference identifier of the user who performed the action.
|
||||
/// </summary>
|
||||
public string UserReference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status code of the envelope.
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Common.Constants.ReferenceType ReferenceType => Status.ToString().FirstOrDefault() switch
|
||||
{
|
||||
'1' => Constants.ReferenceType.Sender,
|
||||
'2' => Constants.ReferenceType.Receiver,
|
||||
_ => Constants.ReferenceType.System,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date and time when the record was added.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date and time when the action occurred.
|
||||
/// </summary>
|
||||
public DateTime? ActionDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the optional comment about the envelope history record.
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.MappingProfiles
|
||||
{
|
||||
public class BasicDtoMappingProfile : Profile
|
||||
{
|
||||
public BasicDtoMappingProfile()
|
||||
{
|
||||
// Entity to DTO mappings
|
||||
CreateMap<Config, ConfigDto>();
|
||||
CreateMap<DocumentReceiverElement, DocumentReceiverElementDto>();
|
||||
CreateMap<DocumentStatus, DocumentStatusDto>();
|
||||
CreateMap<EmailTemplate, EmailTemplateDto>();
|
||||
CreateMap<Envelope, EnvelopeDto>();
|
||||
CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>();
|
||||
CreateMap<EnvelopeDocument, EnvelopeDocumentDto>();
|
||||
CreateMap<EnvelopeHistory, EnvelopeHistoryDto>();
|
||||
CreateMap<EnvelopeHistory, EnvelopeHistoryCreateDto>();
|
||||
CreateMap<EnvelopeReceiver, EnvelopeReceiverDto>();
|
||||
CreateMap<EnvelopeReceiver, EnvelopeReceiverSecretDto>();
|
||||
CreateMap<EnvelopeType, EnvelopeTypeDto>();
|
||||
CreateMap<Receiver, ReceiverReadDto>();
|
||||
CreateMap<Receiver, ReceiverCreateDto>();
|
||||
CreateMap<Receiver, ReceiverUpdateDto>();
|
||||
CreateMap<UserReceiver, UserReceiverDto>();
|
||||
CreateMap<EnvelopeReceiverReadOnly, EnvelopeReceiverReadOnlyDto>();
|
||||
|
||||
// DTO to Entity mappings
|
||||
CreateMap<ConfigDto, Config>();
|
||||
CreateMap<DocumentReceiverElementDto, DocumentReceiverElement>();
|
||||
CreateMap<DocumentStatusDto, DocumentStatus>();
|
||||
CreateMap<EmailTemplateDto, EmailTemplate>();
|
||||
CreateMap<EnvelopeDto, Envelope>();
|
||||
CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>();
|
||||
CreateMap<EnvelopeDocumentDto, EnvelopeDocument>();
|
||||
CreateMap<EnvelopeHistoryDto, EnvelopeHistory>();
|
||||
CreateMap<EnvelopeHistoryCreateDto, EnvelopeHistory>();
|
||||
CreateMap<EnvelopeReceiverDto, EnvelopeReceiver>();
|
||||
CreateMap<EnvelopeTypeDto, EnvelopeType>();
|
||||
CreateMap<ReceiverReadDto, Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
|
||||
CreateMap<ReceiverCreateDto, Receiver>();
|
||||
CreateMap<ReceiverUpdateDto, Receiver>();
|
||||
CreateMap<UserReceiverDto, UserReceiver>();
|
||||
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
|
||||
CreateMap<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnly>();
|
||||
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly>();
|
||||
|
||||
// Messaging mappings
|
||||
// for GTX messaging
|
||||
CreateMap<GtxMessagingResponse, SmsResponse>()
|
||||
.ConstructUsing(gtxRes => gtxRes.Ok()
|
||||
? new SmsResponse() { Ok = true }
|
||||
: new SmsResponse() { Ok = false, Errors = gtxRes });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Abfrage dar, um die Details eines Empfängers zu lesen.
|
||||
/// Diese Abfrage erbt von <see cref="ReceiverQuery"/> und wird verwendet,
|
||||
/// um spezifische Informationen über einen Empfänger abzurufen.
|
||||
/// </summary>
|
||||
public record ReadReceiverQuery : ReceiverQuery
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Repräsentiert die Antwort auf eine Abfrage, um einen Empfänger zu lesen.
|
||||
/// </summary>
|
||||
/// <param name="Id">Die eindeutige Identifikationsnummer des Empfängers.</param>
|
||||
/// <param name="EmailAddress">Die E-Mail-Adresse des Empfängers.</param>
|
||||
/// <param name="AddedWhen">Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde.</param>
|
||||
/// <param name="Signature">Die Signatur des Empfängers.</param>
|
||||
public record ReadReceiverResponse(int Id, string EmailAddress, DateTime AddedWhen, string Signature)
|
||||
{
|
||||
}
|
||||
|
||||
50
EnvelopeGenerator.Application/SQL/DocumentCreateReadSQL.cs
Normal file
50
EnvelopeGenerator.Application/SQL/DocumentCreateReadSQL.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Dapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using EnvelopeGenerator.Application.Exceptions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.SQL;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DocumentCreateReadSQL : ISQL<EnvelopeDocument>
|
||||
{
|
||||
/// <summary>
|
||||
/// Base64, OUT_UID
|
||||
/// </summary>
|
||||
public string Raw => @"
|
||||
DECLARE @BYTE_DATA1 as VARBINARY(MAX)
|
||||
SET @BYTE_DATA1 = @ByteData
|
||||
DECLARE @OUT_DOCID int
|
||||
|
||||
EXEC [dbo].[PRSIG_API_ADD_DOC]
|
||||
{0},
|
||||
@BYTE_DATA1,
|
||||
@OUT_DOCID OUTPUT
|
||||
|
||||
SELECT TOP(1) *
|
||||
FROM [dbo].[TBSIG_ENVELOPE_DOCUMENT]
|
||||
WHERE [GUID] = @OUT_DOCID
|
||||
";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="base64"></param>
|
||||
/// <returns></returns>
|
||||
public static DynamicParameters CreateParmas(string base64)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parameters = new DynamicParameters();
|
||||
byte[] byteData = Convert.FromBase64String(base64);
|
||||
parameters.Add("ByteData", byteData, System.Data.DbType.Binary);
|
||||
return parameters;
|
||||
}
|
||||
catch(FormatException ex)
|
||||
{
|
||||
throw new BadRequestException(ex.Message.Replace("input", "dataAsBase64"));
|
||||
}
|
||||
}
|
||||
}
|
||||
49
EnvelopeGenerator.Application/SQL/EnvelopeCreateReadSQL.cs
Normal file
49
EnvelopeGenerator.Application/SQL/EnvelopeCreateReadSQL.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Dapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using System.Data;
|
||||
|
||||
namespace EnvelopeGenerator.Application.SQL;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EnvelopeCreateReadSQL : ISQL<Envelope>
|
||||
{
|
||||
/// <summary>
|
||||
/// USER_ID, TITLE, TFAEnabled, MESSAGE
|
||||
/// </summary>
|
||||
public string Raw => @"
|
||||
DECLARE @OUT_UID varchar(36);
|
||||
|
||||
EXEC [dbo].[PRSIG_API_CREATE_ENVELOPE]
|
||||
{0},
|
||||
{1},
|
||||
{2},
|
||||
{3},
|
||||
@OUT_UID OUTPUT;
|
||||
|
||||
SELECT TOP(1) *
|
||||
FROM [dbo].[TBSIG_ENVELOPE]
|
||||
WHERE [ENVELOPE_UUID] = @OUT_UID;
|
||||
";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="tfaEnabled"></param>
|
||||
/// <returns></returns>
|
||||
public static DynamicParameters CreateParams(int userId, string title = "", string message = "", bool tfaEnabled = false)
|
||||
{
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("@UserId", userId);
|
||||
parameters.Add("@Title", title);
|
||||
parameters.Add("@TfaEnabled", tfaEnabled ? 1 : 0);
|
||||
parameters.Add("@Message", message);
|
||||
parameters.Add("@OutUid", dbType: DbType.String, size: 36, direction: ParameterDirection.Output);
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Dapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.SQL;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EnvelopeReceiverAddReadSQL : ISQL<Envelope>
|
||||
{
|
||||
/// <summary>
|
||||
/// ENV_UID, EMAIL_ADRESS, SALUTATION, PHONE,
|
||||
/// </summary>
|
||||
public string Raw => @"
|
||||
DECLARE @OUT_RECEIVER_ID int
|
||||
|
||||
EXEC [dbo].[PRSIG_API_CREATE_RECEIVER]
|
||||
{0},
|
||||
{1},
|
||||
{2},
|
||||
{3},
|
||||
@OUT_RECEIVER_ID OUTPUT
|
||||
|
||||
SELECT TOP(1) [ENVELOPE_ID] As EnvelopeId, [RECEIVER_ID] As ReceiverId
|
||||
FROM [dbo].[TBSIG_ENVELOPE_RECEIVER]
|
||||
WHERE [GUID] = @OUT_RECEIVER_ID;
|
||||
";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelope_uuid"></param>
|
||||
/// <param name="emailAddress"></param>
|
||||
/// <param name="salutation"></param>
|
||||
/// <param name="phone"></param>
|
||||
/// <returns></returns>
|
||||
public static DynamicParameters CreateParameters(string envelope_uuid, string emailAddress, string? salutation = null, string? phone = null)
|
||||
{
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("@ENV_UID", envelope_uuid);
|
||||
parameters.Add("@EMAIL_ADRESS", emailAddress);
|
||||
parameters.Add("@SALUTATION", salutation);
|
||||
parameters.Add("@PHONE", phone);
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
30
EnvelopeGenerator.Application/SQL/ParamsExtensions.cs
Normal file
30
EnvelopeGenerator.Application/SQL/ParamsExtensions.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.SQL;
|
||||
|
||||
/// <summary>
|
||||
/// Extension method for converting objects to SQL parameter strings.
|
||||
/// </summary>
|
||||
public static class ParamsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a .NET object to its corresponding SQL-safe parameter string.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to convert.</param>
|
||||
/// <returns>A string representing the SQL parameter.</returns>
|
||||
public static string ToSqlParam(this object? obj)
|
||||
{
|
||||
if (obj is null)
|
||||
return "NULL";
|
||||
else if (obj is string strVal)
|
||||
return $"'{strVal}'";
|
||||
else if (obj is bool boolVal)
|
||||
return boolVal ? "1" : "0";
|
||||
else if (obj is double doubleVal)
|
||||
return $"'{doubleVal.ToString(CultureInfo.InvariantCulture)}'";
|
||||
else if (obj is int intVal)
|
||||
return intVal.ToString();
|
||||
else
|
||||
throw new NotSupportedException($"Type '{obj.GetType().FullName}' is not supported for SQL parameter conversion.");
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
|
||||
public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
|
||||
{
|
||||
public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace EnvelopeGenerator.Application.Services
|
||||
{
|
||||
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||
{
|
||||
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMail(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMailAsync(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||
var erReadOnlyId = (readOnlyDto.Id).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}";
|
||||
|
||||
@@ -7,7 +7,7 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
public class EnvelopeReceiverReadOnlyService : CRUDService<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>, IEnvelopeReceiverReadOnlyService
|
||||
public class EnvelopeReceiverReadOnlyService : CRUDService<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnly, long>, IEnvelopeReceiverReadOnlyService
|
||||
{
|
||||
public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,8 @@ using Microsoft.Extensions.Logging;
|
||||
using EnvelopeGenerator.Extensions;
|
||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using EnvelopeGenerator.Application.Envelopes;
|
||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
@@ -137,16 +139,32 @@ public class EnvelopeReceiverService : BasicCRUDService<IEnvelopeReceiverReposit
|
||||
: Result.Success(code);
|
||||
}
|
||||
|
||||
public async Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses)
|
||||
public async Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, EnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params int[] ignore_statuses)
|
||||
{
|
||||
var er_list = await _repository.ReadByUsernameAsync(username: username, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses);
|
||||
|
||||
if(envelopeQuery?.Id is int eId)
|
||||
er_list = er_list.Where(er => er.EnvelopeId == eId);
|
||||
|
||||
if (envelopeQuery?.Uuid is string uuid)
|
||||
er_list = er_list.Where(er => er.Envelope?.Uuid == uuid);
|
||||
|
||||
if (envelopeQuery?.Status is int status)
|
||||
er_list = er_list.Where(er => er.Envelope?.Status == status);
|
||||
|
||||
if(receiverQuery?.Id is int id)
|
||||
er_list = er_list.Where(er => er.Receiver?.Id == id);
|
||||
|
||||
if (receiverQuery?.Signature is string signature)
|
||||
er_list = er_list.Where(er => er.Receiver?.Signature == signature);
|
||||
|
||||
var dto_list = _mapper.Map<IEnumerable<EnvelopeReceiverDto>>(er_list);
|
||||
return Result.Success(dto_list);
|
||||
}
|
||||
|
||||
public async Task<DataResult<string?>> ReadLastUsedReceiverNameByMail(string mail)
|
||||
public async Task<DataResult<string?>> ReadLastUsedReceiverNameByMailAsync(string? mail = null, int? id = null, string? signature = null)
|
||||
{
|
||||
var er = await _repository.ReadLastByReceiver(mail);
|
||||
var er = await _repository.ReadLastByReceiverAsync(mail, id, signature);
|
||||
return er is null ? Result.Fail<string?>().Notice(LogLevel.None, Flag.NotFound) : Result.Success(er.Name);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ using EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>, IReceiverService
|
||||
public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDto, ReceiverReadDto, Receiver, int>, IReceiverService
|
||||
{
|
||||
public ReceiverService(IReceiverRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
|
||||
@@ -4,6 +4,7 @@ Imports GdPicture14
|
||||
Imports Newtonsoft.Json.Linq
|
||||
Imports EnvelopeGenerator.Common.Jobs
|
||||
Imports System.IO
|
||||
Imports EnvelopeGenerator.Common.Jobs.FinalizeDocument
|
||||
|
||||
Public Class frmFinalizePDF
|
||||
Private Const CONNECTIONSTRING = "Server=sDD-VMP04-SQL17\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=+bk8oAbbQP1AzoHtvZUbd+Mbok2f8Fl4miEx1qssJ5yEaEWoQJ9prg4L14fURpPnqi1WMNs9fE4=;"
|
||||
@@ -15,14 +16,14 @@ Public Class frmFinalizePDF
|
||||
Private Manager As AnnotationManager
|
||||
Private PDFBurner As FinalizeDocument.PDFBurner
|
||||
Private pGDPictureLicenseKey As String = "kG1Qf9PwmqgR8aDmIW2zI_ebj48RzqAJegRxcystEmkbTGQqfkNBdFOXIb6C_A00Ra8zZkrHdfjqzOPXK7kgkF2YDhvrqKfqh4WDug2vOt0qO31IommzkANSuLjZ4zmraoubyEVd25rE3veQ2h_j7tGIoH_LyIHmy24GaXsxdG0yCzIBMdiLbMMMDwcPY-809KeZ83Grv76OVhFvcbBWyYc251vou1N-kGg5_ZlHDgfWoY85gTLRxafjD3KS_i9ARW4BMiy36y8n7UP2jN8kGRnW_04ubpFtfjJqvtsrP_J9D0x7bqV8xtVtT5JI6dpKsVTiMgDCrIcoFSo5gCC1fw9oUopX4TDCkBQttO4-WHBlOeq9dG5Yb0otonVmJKaQA2tP6sMR-lZDs3ql_WI9t91yPWgpssrJUxSHDd27_LMTH_owJIqkF3NOJd9mYQuAv22oNKFYbH8e41pVKb8cT33Y9CgcQ_sy6YDA5PTuIRi67mjKge_nD9rd0IN213Ir9M_EFWqg9e4haWzIdHXQUo0md70kVhPX4UIH_BKJnxEEnFfoFRNMh77bB0N4jkcBEHPl-ghOERv8dOztf4vCnNpzzWvcLD2cqWIm6THy8XGGq9h4hp8aEreRleSMwv9QQAC7mjLwhQ1rBYkpUHlpTjhTLnMwHknl6HH0Z6zzmsgkRKVyfquv94Pd7QbQfZrRka0ss_48pf9p8hAywEn81Q=="
|
||||
Private ReadOnly _ignoredLabels As New List(Of String) From {"Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung"}
|
||||
Private ReadOnly _pdfBurnerParams As New PDFBurnerParams()
|
||||
|
||||
Private Sub frmFinalizePDF_Load(sender As Object, e As EventArgs) Handles MyBase.Load
|
||||
LogConfig = New LogConfig(LogConfig.PathType.CustomPath, Application.StartupPath)
|
||||
Database = New MSSQLServer(LogConfig, MSSQLServer.DecryptConnectionString(CONNECTIONSTRING))
|
||||
|
||||
|
||||
PDFBurner = New FinalizeDocument.PDFBurner(LogConfig, pGDPictureLicenseKey, _ignoredLabels)
|
||||
PDFBurner = New FinalizeDocument.PDFBurner(LogConfig, pGDPictureLicenseKey, _pdfBurnerParams)
|
||||
|
||||
Viewer = New GdViewer()
|
||||
Manager = New AnnotationManager()
|
||||
@@ -77,6 +78,8 @@ Public Class frmFinalizePDF
|
||||
Dim oNewPath = Path.Combine(desktopPath, $"E{txtEnvelope.Text}R{txtReceiver.Text}.burned.pdf")
|
||||
|
||||
File.WriteAllBytes(oNewPath, oNewBuffer)
|
||||
|
||||
Process.Start(oNewPath)
|
||||
Catch ex As Exception
|
||||
MsgBox(ex.Message, MsgBoxStyle.Critical)
|
||||
End Try
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
EnvelopeReportCreated = 1007
|
||||
EnvelopeArchived = 1008
|
||||
EnvelopeDeleted = 1009
|
||||
EnvelopeRejected = 10007
|
||||
EnvelopeWithdrawn = 10009
|
||||
AccessCodeRequested = 2001
|
||||
AccessCodeCorrect = 2002
|
||||
AccessCodeIncorrect = 2003
|
||||
DocumentOpened = 2004
|
||||
DocumentSigned = 2005
|
||||
DocumentForwarded = 4001
|
||||
SignatureConfirmed = 2006
|
||||
DocumentForwarded = 2006
|
||||
DocumentRejected = 2007
|
||||
EnvelopeShared = 2008
|
||||
EnvelopeViewed = 2009
|
||||
@@ -28,12 +29,27 @@
|
||||
MessageConfirmationSent = 3003
|
||||
MessageDeletionSent = 3004
|
||||
MessageCompletionSent = 3005
|
||||
DocumentMod_Rotation = 4001
|
||||
End Enum
|
||||
|
||||
Public Class Status
|
||||
Public Shared ReadOnly NonHist As IReadOnlyList(Of EnvelopeStatus) = New List(Of EnvelopeStatus) From {
|
||||
EnvelopeStatus.Invalid,
|
||||
EnvelopeStatus.EnvelopeSaved,
|
||||
EnvelopeStatus.EnvelopeSent,
|
||||
EnvelopeStatus.EnvelopePartlySigned
|
||||
}
|
||||
|
||||
Public Shared ReadOnly RelatedToFormApp As IReadOnlyList(Of EnvelopeStatus) = New List(Of EnvelopeStatus) From {
|
||||
EnvelopeStatus.EnvelopeCreated,
|
||||
EnvelopeStatus.DocumentMod_Rotation
|
||||
}
|
||||
End Class
|
||||
|
||||
'TODO: standardize in xwiki
|
||||
Public Enum ReferenceType
|
||||
Sender = 1
|
||||
Receiver
|
||||
Sender
|
||||
System
|
||||
Unknown
|
||||
End Enum
|
||||
@@ -94,13 +110,16 @@
|
||||
End Enum
|
||||
|
||||
Public Enum EmailTemplateType
|
||||
DocumentReceived
|
||||
DocumentReceived = 0
|
||||
DocumentSigned
|
||||
DocumentDeleted
|
||||
DocumentCompleted
|
||||
DocumentAccessCodeReceived
|
||||
DocumentShared
|
||||
TotpSecret
|
||||
DocumentRejected_ADM
|
||||
DocumentRejected_REC
|
||||
DocumentRejected_REC_2
|
||||
End Enum
|
||||
|
||||
Public Enum EncodeType
|
||||
@@ -124,7 +143,7 @@
|
||||
Public Const DATABASE = "DATABASE"
|
||||
Public Const LOGCONFIG = "LOGCONFIG"
|
||||
Public Const GDPICTURE = "GDPICTURE"
|
||||
Public Const IGNORED_LABELS = "IgnoredLabels"
|
||||
Public Const PDF_BURNER_PARAMS = "PDFBurnerParams"
|
||||
|
||||
Public Const GREEN_300 = "#bbf7d0"
|
||||
Public Const RED_300 = "#fecaca"
|
||||
|
||||
@@ -19,6 +19,7 @@ Public Class EmailData
|
||||
Public Property EmailAttachment As String = ""
|
||||
Public Property ATT1_RELATED_ID As Long
|
||||
Public Property ATT1_REL_TYPE As String = ""
|
||||
Public Property ADDED_WHO_PROCESS As String = "DDEnvelopGenerator"
|
||||
|
||||
''' <summary>
|
||||
''' Constructor for sending email to receiver
|
||||
@@ -31,7 +32,7 @@ Public Class EmailData
|
||||
EmailSubject = String.Empty
|
||||
EmailType = pStatus
|
||||
|
||||
Message = pEnvelope.Message
|
||||
Message = TextToHtml(pEnvelope.Message)
|
||||
ReferenceID = pEnvelope.Id
|
||||
ReferenceString = pEnvelope.Uuid
|
||||
ReceiverName = pReceiver.Name
|
||||
@@ -40,6 +41,22 @@ Public Class EmailData
|
||||
SenderName = pEnvelope.User.FullName
|
||||
EnvelopeTitle = pEnvelope.Title
|
||||
End Sub
|
||||
Public Function TextToHtml(input As String) As String
|
||||
If String.IsNullOrEmpty(input) Then Return ""
|
||||
|
||||
' HTML-Encodierung der Sonderzeichen
|
||||
Dim encoded As String = System.Net.WebUtility.HtmlEncode(input)
|
||||
|
||||
' Tabs in umwandeln (z.B. 4 non-breaking spaces)
|
||||
encoded = encoded.Replace(vbTab, " ")
|
||||
|
||||
' Zeilenumbrüche in <br /> umwandeln
|
||||
encoded = encoded.Replace(vbCrLf, "<br />") ' Windows
|
||||
encoded = encoded.Replace(vbCr, "<br />") ' Mac alt
|
||||
encoded = encoded.Replace(vbLf, "<br />") ' Unix/Linux
|
||||
|
||||
Return encoded
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Constructor for sending email to creator
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
Public Property Message As String = My.Resources.Envelope.Please_read_and_sign_this_document
|
||||
|
||||
Public Property AddedWhen As Date
|
||||
Public Property ChangedWhen As Date
|
||||
Public Property User As New User()
|
||||
|
||||
Public Property Documents As New List(Of EnvelopeDocument)
|
||||
@@ -32,6 +33,7 @@
|
||||
Public Property History As New List(Of EnvelopeHistoryEntry)
|
||||
Public Property EnvelopeType As EnvelopeType
|
||||
Public Property DOC_RESULT As Byte()
|
||||
Public Property CURRENT_WORK_APP As String = "signFLOW GUI"
|
||||
Public ReadOnly Property EnvelopeTypeTitle As String
|
||||
Get
|
||||
Return EnvelopeType?.Title
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
Public Property HasAccess As Boolean
|
||||
Public Property IsAdmin As Boolean
|
||||
Public Property GhostModeActive As Boolean
|
||||
|
||||
Public ReadOnly Property FullName() As String
|
||||
Get
|
||||
|
||||
@@ -281,6 +281,8 @@
|
||||
<Compile Include="Entities\ElementStatus.vb" />
|
||||
<Compile Include="Entities\EmailData.vb" />
|
||||
<Compile Include="Entities\EmailTemplate.vb" />
|
||||
<Compile Include="Jobs\APIBackendJobs\APIEnvelopeJob.vb" />
|
||||
<Compile Include="Jobs\FinalizeDocument\PDFBurnerParams.vb" />
|
||||
<Compile Include="Services\TemplateService.vb" />
|
||||
<Compile Include="Entities\Envelope.vb" />
|
||||
<Compile Include="Entities\EnvelopeDocument.vb" />
|
||||
|
||||
@@ -52,6 +52,7 @@ Public Class Helpers
|
||||
End Function
|
||||
|
||||
Public Shared Function GetEnvelopeURL(pHost As String, pEnvelopeUuid As String, pReceiverSignature As String) As String
|
||||
|
||||
Dim oEnvelopeUserReference As String = EncodeEnvelopeReceiverId(pEnvelopeUuid, pReceiverSignature)
|
||||
Dim oURL As String = String.Format("{0}/EnvelopeKey/{1}", pHost.Trim(), oEnvelopeUserReference)
|
||||
Return oURL
|
||||
|
||||
221
EnvelopeGenerator.Common/Jobs/APIBackendJobs/APIEnvelopeJob.vb
Normal file
221
EnvelopeGenerator.Common/Jobs/APIBackendJobs/APIEnvelopeJob.vb
Normal file
@@ -0,0 +1,221 @@
|
||||
Imports DigitalData.Modules.Database
|
||||
Imports DigitalData.Modules.Logging
|
||||
Imports DigitalData.Modules.Base
|
||||
Imports GdPicture14
|
||||
Imports Quartz
|
||||
Imports System.Security.Cryptography
|
||||
Imports System.IO
|
||||
Imports EnvelopeGenerator.Common.Jobs.FinalizeDocument.FinalizeDocumentExceptions
|
||||
Imports EnvelopeGenerator.Common.Jobs.FinalizeDocument
|
||||
Imports EnvelopeGenerator.Common.Constants
|
||||
Imports DevExpress.DataProcessing
|
||||
Imports System.Data.SqlClient
|
||||
Imports DevExpress.XtraRichEdit.Layout.Engine
|
||||
|
||||
Namespace Jobs
|
||||
Public Class APIEnvelopeJob
|
||||
Implements IJob
|
||||
|
||||
|
||||
Private LogConfig As LogConfig
|
||||
Private Logger As Logger
|
||||
Private Database As MSSQLServer
|
||||
Private Config As DbConfig
|
||||
|
||||
Private ConfigModel As ConfigModel
|
||||
Private EnvelopeModel As EnvelopeModel
|
||||
Private ReceiverModel As ReceiverModel
|
||||
Private ActionService As ActionService
|
||||
|
||||
|
||||
Private ReadOnly CompleteWaitTime As Integer = 1
|
||||
|
||||
Private myTempFiles As TempFiles
|
||||
|
||||
Private Class EnvelopeData
|
||||
Public EnvelopeId As Integer
|
||||
Public EnvelopeUUID As String
|
||||
Public DocumentPath As String
|
||||
End Class
|
||||
|
||||
Public Function Execute(pContext As IJobExecutionContext) As Task Implements IJob.Execute
|
||||
LogConfig = pContext.MergedJobDataMap.Item(Constants.LOGCONFIG)
|
||||
Logger = LogConfig.GetLogger()
|
||||
myTempFiles = New TempFiles(LogConfig)
|
||||
myTempFiles.Create()
|
||||
Dim JobId = pContext.JobDetail.Key
|
||||
Logger.Debug("API Envelopes - Starting job {0}", JobId)
|
||||
|
||||
Try
|
||||
Logger.Debug("API Envelopes - Loading Database..")
|
||||
Database = GetDatabase(pContext, LogConfig)
|
||||
|
||||
Logger.Debug("API Envelopes - Loading Models & Services")
|
||||
Dim oState = GetState()
|
||||
InitializeModels(oState)
|
||||
|
||||
Logger.Debug("API Envelopes - Loading Configuration..")
|
||||
Config = ConfigModel.LoadConfiguration()
|
||||
oState.DbConfig = Config
|
||||
|
||||
InitializeServices(oState)
|
||||
Config.DocumentPath = Config.DocumentPath
|
||||
|
||||
Logger.Debug("API Envelopes - ExportPath: [{0}]", Config.ExportPath)
|
||||
|
||||
Dim oSql = $"SELECT * FROM TBSIG_ENVELOPE where SOURCE = 'API' AND STATUS = 1003 order by guid"
|
||||
Dim oDTEnv_invitations = Database.GetDatatable(oSql)
|
||||
|
||||
Dim oEnvelopeIds As List(Of Integer) = oDTEnv_invitations.Rows.Cast(Of DataRow).
|
||||
Select(Function(r) r.Item("GUID")).
|
||||
Cast(Of Integer).
|
||||
ToList()
|
||||
|
||||
If oEnvelopeIds.Count > 0 Then
|
||||
Logger.Info("SendInvMail - Found [{0}] envelopes.", oEnvelopeIds.Count)
|
||||
End If
|
||||
|
||||
Dim oTotal As Integer = oEnvelopeIds.Count
|
||||
Dim oCurrent As Integer = 1
|
||||
|
||||
For Each oId In oEnvelopeIds
|
||||
Logger.Info("SendInvMail - Gathering Info for Envelope [{0}] ({1}/{2})", oId, oCurrent, oTotal)
|
||||
Try
|
||||
Dim oEnvelope = EnvelopeModel.GetById(oId)
|
||||
|
||||
If oEnvelope Is Nothing Then
|
||||
Logger.Warn("SendInvMail - Envelope could not be loaded for Id [{0}]!", oId)
|
||||
Throw New ArgumentNullException("EnvelopeData")
|
||||
End If
|
||||
oEnvelope.CURRENT_WORK_APP = "signFLOW_API_EnvJob_InvMail"
|
||||
Logger.Debug("SendInvMail - Loading Envelope Data..")
|
||||
Dim oEnvelopeData = GetEnvelopeData(oId)
|
||||
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id).ToList()
|
||||
Logger.Debug("SendInvMail - Created Reveivers!")
|
||||
If oEnvelopeData Is Nothing Then
|
||||
Logger.Warn("SendInvMail - EnvelopeData could not be loaded for Id [{0}]!", oId)
|
||||
Throw New ArgumentNullException("EnvelopeData")
|
||||
End If
|
||||
Logger.Info("SendInvMail - Sending InvitationMails for Envelope [{0}]", oId)
|
||||
If ActionService.SendEnvelope(oEnvelope) = False Then
|
||||
Logger.Warn("SendInvMail - Could not send the InvitationMails for Envelope [{0}]", oId)
|
||||
Throw New ArgumentNullException("EnvelopeData")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Logger.Warn(ex, $"SendInvMail - Unhandled exception while working envelope [{oId}]")
|
||||
End Try
|
||||
|
||||
oCurrent += 1
|
||||
Logger.Info("SendInvMail - Envelope finalized!")
|
||||
|
||||
Next
|
||||
'Hier nun der Teil um zurückgezogene Envelopes abzuarbeiten
|
||||
oSql = $"SELECT ENV.GUID,REJ.COMMENT REJECTION_REASON FROM
|
||||
(SELECT * FROM TBSIG_ENVELOPE where STATUS = 1009 AND SOURCE = 'API') ENV INNER JOIN
|
||||
(SELECT MAX(GUID) GUID,ENVELOPE_ID,MAX(ADDED_WHEN) ADDED_WHEN,MAX(ACTION_DATE) ACTION_DATE, COMMENT FROM TBSIG_ENVELOPE_HISTORY where STATUS = 1009 GROUP BY ENVELOPE_ID,COMMENT ) REJ ON ENV.GUID = REJ.ENVELOPE_ID LEFT JOIN
|
||||
(SELECT * FROM TBSIG_ENVELOPE_HISTORY where STATUS = 3004 ) M_Send ON ENV.GUID = M_Send.ENVELOPE_ID
|
||||
where M_Send.GUID IS NULL"
|
||||
Dim oDT_EnvWithdrawn = Database.GetDatatable(oSql)
|
||||
|
||||
oEnvelopeIds = oDTEnv_invitations.Rows.Cast(Of DataRow).
|
||||
Select(Function(r) r.Item("GUID")).
|
||||
Cast(Of Integer).
|
||||
ToList()
|
||||
|
||||
If oEnvelopeIds.Count > 0 Then
|
||||
Logger.Info("WithdrawnEnv - Found [{0}] envelopes.", oEnvelopeIds.Count)
|
||||
End If
|
||||
|
||||
oTotal = oEnvelopeIds.Count
|
||||
oCurrent = 1
|
||||
Dim oEnvID As Integer
|
||||
For Each oRow As DataRow In oDT_EnvWithdrawn.Rows
|
||||
oEnvID = oRow.Item("GUID")
|
||||
Dim oReason = oRow.Item("REJECTION_REASON")
|
||||
Logger.Info("WithdrawnEnv - Gathering Info for Envelope [{0}] ({1}/{2})", oEnvID, oCurrent, oTotal)
|
||||
Try
|
||||
Dim oEnvelope = EnvelopeModel.GetById(oEnvID)
|
||||
If oEnvelope Is Nothing Then
|
||||
Logger.Warn("WithdrawnEnv - Envelope could not be loaded for Id [{0}]!", oEnvID)
|
||||
Throw New ArgumentNullException("EnvelopeData")
|
||||
End If
|
||||
oEnvelope.CURRENT_WORK_APP = "signFLOW_API_EnvJob_Withdrawn"
|
||||
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id).ToList()
|
||||
|
||||
Logger.Debug("WithdrawnEnv - Sending Withdrawn Mails..")
|
||||
|
||||
If ActionService.API_SendWithdrawn_Mails(oEnvelope, oReason) = False Then
|
||||
Logger.Warn("Could not send the Mails for withdrawn Envelope")
|
||||
Else
|
||||
Dim oStatInsert = $"INSERT INTO TBSIG_ENVELOPE_HISTORY (ENVELOPE_ID,STATUS,USER_REFERENCE,ADDED_WHEN,ACTION_DATE) VALUES ('{oEnvelope.Id}',3004,'API',GETDATE(),GETDATE())"
|
||||
Database.ExecuteNonQuery(oStatInsert)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Logger.Warn(ex, $"WithdrawnEnv - Unhandled exception while working envelope [{oEnvID}]")
|
||||
End Try
|
||||
|
||||
oCurrent += 1
|
||||
Logger.Info("WithdrawnEnv - Envelope finalized!")
|
||||
|
||||
Next
|
||||
|
||||
|
||||
Logger.Debug("API Envelopes - Completed job {0} successfully!", JobId)
|
||||
Catch ex As Exception
|
||||
Logger.Warn("API Envelopes job failed!")
|
||||
Logger.Error(ex)
|
||||
Finally
|
||||
Logger.Debug("API Envelopes execution for [{0}] ended", JobId)
|
||||
End Try
|
||||
|
||||
Return Task.FromResult(True)
|
||||
End Function
|
||||
Private Sub InitializeModels(pState As State)
|
||||
ConfigModel = New ConfigModel(pState)
|
||||
EnvelopeModel = New EnvelopeModel(pState)
|
||||
ReceiverModel = New ReceiverModel(pState)
|
||||
End Sub
|
||||
Private Sub InitializeServices(pState As State)
|
||||
ActionService = New ActionService(pState, Database)
|
||||
End Sub
|
||||
Private Function GetDatabase(pContext As IJobExecutionContext, pLogConfig As LogConfig) As MSSQLServer
|
||||
Dim oConnectionString As String = pContext.MergedJobDataMap.Item(Constants.DATABASE)
|
||||
Dim Database = New MSSQLServer(pLogConfig, MSSQLServer.DecryptConnectionString(oConnectionString))
|
||||
|
||||
Return Database
|
||||
End Function
|
||||
Private Function GetEnvelopeData(pEnvelopeId As Integer) As EnvelopeData
|
||||
Dim oSql = $"SELECT T.GUID, T.ENVELOPE_UUID,T2.FILEPATH, T2.BYTE_DATA FROM [dbo].[TBSIG_ENVELOPE] T
|
||||
JOIN TBSIG_ENVELOPE_DOCUMENT T2 ON T.GUID = T2.ENVELOPE_ID
|
||||
WHERE T.GUID = {pEnvelopeId}"
|
||||
Dim oTable As DataTable = Database.GetDatatable(oSql)
|
||||
Dim oRow As DataRow = oTable.Rows.Cast(Of DataRow).SingleOrDefault()
|
||||
If oRow Is Nothing Then
|
||||
Return Nothing
|
||||
End If
|
||||
|
||||
Dim oData As New EnvelopeData With {
|
||||
.EnvelopeId = pEnvelopeId,
|
||||
.DocumentPath = oRow.ItemEx("FILEPATH", ""),
|
||||
.EnvelopeUUID = oRow.ItemEx("ENVELOPE_UUID", "")
|
||||
}
|
||||
|
||||
Logger.Debug("Document path: [{0}]", oData.DocumentPath)
|
||||
|
||||
Return oData
|
||||
End Function
|
||||
|
||||
|
||||
|
||||
|
||||
Private Function GetState() As State
|
||||
Return New State With {
|
||||
.LogConfig = LogConfig,
|
||||
.Database = Database,
|
||||
.UserId = 0,
|
||||
.Config = Nothing,
|
||||
.DbConfig = Nothing
|
||||
}
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -53,7 +53,7 @@ Namespace Jobs
|
||||
myTempFiles = New TempFiles(LogConfig)
|
||||
myTempFiles.Create()
|
||||
Dim JobId = pContext.JobDetail.Key
|
||||
Logger.Info("Starting job {0}", JobId)
|
||||
Logger.Debug("Starting job {0}", JobId)
|
||||
|
||||
Try
|
||||
Logger.Debug("Loading GdViewer..")
|
||||
@@ -74,8 +74,8 @@ Namespace Jobs
|
||||
InitializeServices(oState)
|
||||
|
||||
Logger.Debug("Loading PDFBurner..")
|
||||
Dim ignoredLabels As List(Of String) = pContext.MergedJobDataMap.Item(Constants.IGNORED_LABELS)
|
||||
PDFBurner = New PDFBurner(LogConfig, oGdPictureKey, ignoredLabels)
|
||||
Dim pdfBurnerParams As PDFBurnerParams = pContext.MergedJobDataMap.Item(Constants.PDF_BURNER_PARAMS)
|
||||
PDFBurner = New PDFBurner(LogConfig, oGdPictureKey, pdfBurnerParams)
|
||||
|
||||
Logger.Debug("Loading PDFMerger..")
|
||||
PDFMerger = New PDFMerger(LogConfig, oGdPictureKey)
|
||||
@@ -108,7 +108,6 @@ Namespace Jobs
|
||||
|
||||
For Each oId In oEnvelopeIds
|
||||
Logger.Info("Finalizing Envelope [{0}] ({1}/{2})", oId, oCurrent, oTotal)
|
||||
Logger.Debug("Loading Envelope..")
|
||||
Try
|
||||
Dim oEnvelope = EnvelopeModel.GetById(oId)
|
||||
If oEnvelope Is Nothing Then
|
||||
@@ -147,7 +146,7 @@ Namespace Jobs
|
||||
Directory.CreateDirectory(oOutputDirectoryPath)
|
||||
End If
|
||||
Dim oOutputFilePath = Path.Combine(oOutputDirectoryPath, $"{oEnvelope.Uuid}.pdf")
|
||||
Logger.Info("Writing finalized Pdf to disk..")
|
||||
Logger.Debug("Writing finalized Pdf to disk..")
|
||||
Logger.Info("Output path is [{0}]", oOutputFilePath)
|
||||
|
||||
Try
|
||||
@@ -157,12 +156,14 @@ Namespace Jobs
|
||||
Throw New ExportDocumentException("Could not export final document to disk!", ex)
|
||||
End Try
|
||||
|
||||
Logger.Info("Writing EB-bytes to database...")
|
||||
Logger.Debug("Writing EB-bytes to database...")
|
||||
Update_File_DB(oOutputFilePath, oEnvelope.Id)
|
||||
|
||||
Logger.Info("Sending finalized report-mails..")
|
||||
|
||||
If SendFinalEmails(oEnvelope) = False Then ', oOutputFilePath
|
||||
Throw New ApplicationException("Final emails could not be sent!")
|
||||
Else
|
||||
Logger.Info("Report-mails successfully sent!")
|
||||
End If
|
||||
Logger.Debug("Setting envelope status..")
|
||||
If ActionService.FinalizeEnvelope(oEnvelope) = False Then
|
||||
@@ -170,12 +171,12 @@ Namespace Jobs
|
||||
Throw New ApplicationException("Envelope could not be finalized")
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Logger.Warn($"Unhandled exception while working envelope [{oId}] - [{ex.Message}]")
|
||||
Logger.Warn(ex, $"Unhandled exception while working envelope [{oId}]")
|
||||
End Try
|
||||
|
||||
|
||||
oCurrent += 1
|
||||
Logger.Info("Envelope finalized!")
|
||||
Logger.Info($"Envelope [{oId}] finalized!")
|
||||
|
||||
Next
|
||||
|
||||
@@ -192,7 +193,7 @@ Namespace Jobs
|
||||
Logger.Warn("Certificate Document job failed!")
|
||||
Logger.Error(ex)
|
||||
Finally
|
||||
Logger.Info("Job execution for [{0}] ended", JobId)
|
||||
Logger.Debug("Job execution for [{0}] ended", JobId)
|
||||
End Try
|
||||
|
||||
Return Task.FromResult(True)
|
||||
@@ -290,11 +291,15 @@ Namespace Jobs
|
||||
If oMailToCreator <> FinalEmailType.No Then
|
||||
Logger.Debug("Sending email to creator ...")
|
||||
SendFinalEmailToCreator(pEnvelope) ', pAttachment
|
||||
Else
|
||||
Logger.Warn($"No SendFinalEmailToCreator - oMailToCreator [{oMailToCreator}] <> [{FinalEmailType.No}] ")
|
||||
End If
|
||||
|
||||
If oMailToReceivers <> FinalEmailType.No Then
|
||||
Logger.Debug("Sending emails to receivers..")
|
||||
SendFinalEmailToReceivers(pEnvelope) ', pAttachment
|
||||
Else
|
||||
Logger.Warn($"No SendFinalEmailToReceivers - oMailToCreator [{oMailToReceivers}] <> [{FinalEmailType.No}] ")
|
||||
End If
|
||||
|
||||
Return True
|
||||
@@ -355,9 +360,9 @@ Namespace Jobs
|
||||
oInputPath = pEnvelopeData.DocumentPath
|
||||
Logger.Info($"Input path: [{oInputPath}]")
|
||||
Else
|
||||
Logger.Info($"we got bytes..")
|
||||
Logger.Debug($"we got bytes..")
|
||||
oInputPath = Config.DocumentPathOrigin
|
||||
Logger.Info($"oInputPath: {Config.DocumentPathOrigin}")
|
||||
Logger.Debug($"oInputPath: {Config.DocumentPathOrigin}")
|
||||
End If
|
||||
|
||||
|
||||
@@ -378,12 +383,10 @@ Namespace Jobs
|
||||
Try
|
||||
oInputDocumentBuffer = File.ReadAllBytes(oInputPath)
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
Throw New BurnAnnotationException("Source document could not be read from disk!", ex)
|
||||
End Try
|
||||
End If
|
||||
|
||||
|
||||
Return PDFBurner.BurnInstantJSONAnnotationsToPDF(oInputDocumentBuffer, oAnnotations)
|
||||
End Function
|
||||
|
||||
@@ -423,7 +426,7 @@ Namespace Jobs
|
||||
End Function
|
||||
|
||||
Private Sub InitializeServices(pState As State)
|
||||
ActionService = New ActionService(pState)
|
||||
ActionService = New ActionService(pState, Database)
|
||||
End Sub
|
||||
|
||||
Private Sub InitializeModels(pState As State)
|
||||
|
||||
@@ -16,9 +16,9 @@ Namespace Jobs.FinalizeDocument
|
||||
Private Const ANNOTATION_TYPE_IMAGE = "pspdfkit/image"
|
||||
Private Const ANNOTATION_TYPE_INK = "pspdfkit/ink"
|
||||
Private Const ANNOTATION_TYPE_WIDGET = "pspdfkit/widget"
|
||||
Private Property _ignoredLabels As List(Of String)
|
||||
Private Property _pdfBurnerParams As PDFBurnerParams
|
||||
|
||||
Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String, ignoredLabels As List(Of String))
|
||||
Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String, pdfBurnerParams As PDFBurnerParams)
|
||||
MyBase.New(pLogConfig)
|
||||
|
||||
LicenseManager = New LicenseManager()
|
||||
@@ -26,56 +26,50 @@ Namespace Jobs.FinalizeDocument
|
||||
|
||||
Manager = New AnnotationManager()
|
||||
|
||||
_ignoredLabels = ignoredLabels
|
||||
_pdfBurnerParams = pdfBurnerParams
|
||||
End Sub
|
||||
|
||||
Public Function BurnInstantJSONAnnotationsToPDF(pSourceBuffer As Byte(), pInstantJSONList As List(Of String)) As Byte()
|
||||
Dim oResult As GdPictureStatus
|
||||
Using oSourceStream As New MemoryStream(pSourceBuffer)
|
||||
' Open PDF
|
||||
oResult = Manager.InitFromStream(oSourceStream)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]")
|
||||
End If
|
||||
|
||||
Try
|
||||
Using oSourceStream As New MemoryStream(pSourceBuffer)
|
||||
' Open PDF
|
||||
oResult = Manager.InitFromStream(oSourceStream)
|
||||
' Add annotation to PDF
|
||||
For Each oJSON In pInstantJSONList
|
||||
If AddInstantJSONAnnotationToPDF(oJSON) = False Then
|
||||
Logger.Warn($"Error in AddInstantJSONAnnotationToPDF - oJson: ")
|
||||
Logger.Warn(oJSON)
|
||||
Throw New BurnAnnotationException($"Adding Annotation failed")
|
||||
End If
|
||||
Next
|
||||
oResult = Manager.BurnAnnotationsToPage(RemoveInitialAnnots:=True, VectorMode:=True)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not burn annotations to file: [{oResult}]")
|
||||
End If
|
||||
|
||||
'Save PDF
|
||||
Using oNewStream As New MemoryStream()
|
||||
oResult = Manager.SaveDocumentToPDF(oNewStream)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]")
|
||||
Throw New BurnAnnotationException($"Could not save document to stream: [{oResult}]")
|
||||
End If
|
||||
|
||||
' Add annotation to PDF
|
||||
For Each oJSON In pInstantJSONList
|
||||
If AddInstantJSONAnnotationToPDF(oJSON) = False Then
|
||||
Logger.Warn($"Error in AddInstantJSONAnnotationToPDF - oJson: ")
|
||||
Logger.Warn(oJSON)
|
||||
Throw New BurnAnnotationException($"Adding Annotation failed")
|
||||
End If
|
||||
Next
|
||||
oResult = Manager.BurnAnnotationsToPage(RemoveInitialAnnots:=True, VectorMode:=True)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not burn annotations to file: [{oResult}]")
|
||||
End If
|
||||
Manager.Close()
|
||||
|
||||
'Save PDF
|
||||
Using oNewStream As New MemoryStream()
|
||||
oResult = Manager.SaveDocumentToPDF(oNewStream)
|
||||
If oResult <> GdPictureStatus.OK Then
|
||||
Throw New BurnAnnotationException($"Could not save document to stream: [{oResult}]")
|
||||
End If
|
||||
|
||||
Manager.Close()
|
||||
|
||||
Return oNewStream.ToArray()
|
||||
End Using
|
||||
Return oNewStream.ToArray()
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
|
||||
Return Nothing
|
||||
End Try
|
||||
End Using
|
||||
End Function
|
||||
|
||||
Private Function AddInstantJSONAnnotationToPDF(pInstantJSON As String) As Boolean
|
||||
Try
|
||||
Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON)
|
||||
|
||||
oAnnotationData.annotations.Reverse()
|
||||
Dim formFieldIndex = 0
|
||||
For Each oAnnotation In oAnnotationData.annotations
|
||||
Logger.Debug("Adding AnnotationID: " + oAnnotation.id)
|
||||
Select Case oAnnotation.type
|
||||
@@ -88,10 +82,12 @@ Namespace Jobs.FinalizeDocument
|
||||
Case ANNOTATION_TYPE_WIDGET
|
||||
'Add form field values
|
||||
Dim formFieldValue = oAnnotationData.formFieldValues.FirstOrDefault(Function(fv) fv.name = oAnnotation.id)
|
||||
If formFieldValue IsNot Nothing AndAlso Not _ignoredLabels.Contains(formFieldValue.value) Then
|
||||
AddFormFieldValue(oAnnotation, formFieldValue)
|
||||
If formFieldValue IsNot Nothing AndAlso Not _pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.value) Then
|
||||
AddFormFieldValue(oAnnotation, formFieldValue, formFieldIndex)
|
||||
formFieldIndex += 1
|
||||
End If
|
||||
End Select
|
||||
|
||||
Next
|
||||
|
||||
Return True
|
||||
@@ -151,13 +147,13 @@ Namespace Jobs.FinalizeDocument
|
||||
|
||||
End Function
|
||||
|
||||
Private Function AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue) As Boolean
|
||||
Private Function AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue, index As Integer) As Boolean
|
||||
Try
|
||||
' Convert pixels to Inches
|
||||
Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList()
|
||||
|
||||
Dim oX = oBounds.Item(0)
|
||||
Dim oY = oBounds.Item(1)
|
||||
Dim oY = oBounds.Item(1) + _pdfBurnerParams.YOffset * index + _pdfBurnerParams.TopMargin
|
||||
Dim oWidth = oBounds.Item(2)
|
||||
Dim oHeight = oBounds.Item(3)
|
||||
|
||||
@@ -166,9 +162,9 @@ Namespace Jobs.FinalizeDocument
|
||||
Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, formFieldValue.value)
|
||||
|
||||
' Set the font properties
|
||||
ant.FontName = "Arial"
|
||||
ant.FontSize = 8
|
||||
ant.FontStyle = FontStyle.Italic
|
||||
ant.FontName = _pdfBurnerParams.FontName
|
||||
ant.FontSize = _pdfBurnerParams.FontSize
|
||||
ant.FontStyle = _pdfBurnerParams.FontStyle
|
||||
Manager.SaveAnnotationsToPage()
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
Imports System.Drawing
|
||||
Namespace Jobs.FinalizeDocument
|
||||
Public Class PDFBurnerParams
|
||||
Public Property IgnoredLabels As New List(Of String) From {"Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung"}
|
||||
|
||||
Public Property TopMargin As Double = 0.1
|
||||
|
||||
Public Property YOffset As Double = -0.3
|
||||
|
||||
Public Property FontName As String = "Arial"
|
||||
|
||||
Public Property FontSize As Integer = 8
|
||||
|
||||
Public Property FontStyle As FontStyle = FontStyle.Italic
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -18,7 +18,7 @@ Public Class EmailModel
|
||||
oCommand.Parameters.Add("EMAIL_ADRESS", SqlDbType.NVarChar).Value = pEmail.EmailAdress
|
||||
oCommand.Parameters.Add("EMAIL_SUBJ", SqlDbType.NVarChar).Value = pEmail.EmailSubject
|
||||
oCommand.Parameters.Add("EMAIL_BODY", SqlDbType.NVarChar).Value = pEmail.EmailBody
|
||||
oCommand.Parameters.Add("ADDED_WHO", SqlDbType.NVarChar).Value = "DDEnvelopGenerator"
|
||||
oCommand.Parameters.Add("ADDED_WHO", SqlDbType.NVarChar).Value = pEmail.ADDED_WHO_PROCESS
|
||||
oCommand.Parameters.Add("SENDING_PROFILE", SqlDbType.Int).Value = State.DbConfig.SendingProfile
|
||||
oCommand.Parameters.Add("REFERENCE_ID", SqlDbType.Int).Value = pEmail.ReferenceID
|
||||
oCommand.Parameters.Add("REFERENCE_STRING", SqlDbType.NVarChar).Value = pEmail.ReferenceString
|
||||
|
||||
@@ -35,6 +35,7 @@ Public Class EnvelopeModel
|
||||
.Language = pRow.ItemEx("LANGUAGE", "de-DE"),
|
||||
.Status = ObjectEx.ToEnum(Of Constants.EnvelopeStatus)(pRow.ItemEx("STATUS", Constants.EnvelopeStatus.EnvelopeCreated.ToString())),
|
||||
.AddedWhen = pRow.Item("ADDED_WHEN"),
|
||||
.ChangedWhen = pRow.ItemEx(Of Date)("CHANGED_WHEN", Nothing),
|
||||
.CertificationType = ObjectEx.ToEnum(Of Constants.CertificationType)(pRow.ItemEx("CERTIFICATION_TYPE", Constants.CertificationType.AdvancedElectronicSignature.ToString())),
|
||||
.User = New User(),
|
||||
.ExpiresWhen = pRow.ItemEx(Of Date)("EXPIRES_WHEN", Nothing),
|
||||
|
||||
@@ -57,7 +57,8 @@ Public Class ReceiverModel
|
||||
|
||||
Public Function Insert(pReceiver As EnvelopeReceiver, pTransaction As SqlTransaction) As Boolean
|
||||
Try
|
||||
Dim oCheck = $"SELECT COUNT(GUID) FROM [dbo].[TBSIG_RECEIVER] WHERE SIGNATURE = '{pReceiver.GetSignature()}'"
|
||||
Dim oSignature As String = pReceiver.GetSignature()
|
||||
Dim oCheck = $"SELECT COUNT(GUID) FROM [dbo].[TBSIG_RECEIVER] WHERE SIGNATURE = '{oSignature}'"
|
||||
Dim oExists = Database.GetScalarValue(oCheck)
|
||||
|
||||
If oExists = 0 Then
|
||||
@@ -77,7 +78,7 @@ Public Class ReceiverModel
|
||||
Return False
|
||||
End If
|
||||
Else
|
||||
Logger.Warn($"Receiver [{pReceiver.Email}] already existing! Check collecting not existing Receivers!")
|
||||
Logger.Warn($"Receiver [{pReceiver.Email}] already existing! SignatureID: {oSignature} Check SQL {oCheck}")
|
||||
Return True
|
||||
End If
|
||||
Catch ex As Exception
|
||||
|
||||
@@ -33,10 +33,10 @@ Public Class UserModel
|
||||
Dim oRow = oTable.Rows.Item(0)
|
||||
Dim oHasAccess = oRow.ItemEx("MODULE_ACCESS", False)
|
||||
Dim oIsAdmin = oRow.ItemEx("IS_ADMIN", False)
|
||||
|
||||
Dim oGhostmode = oRow.ItemEx("GHOST_MODE_OVERRIDE", False)
|
||||
pUser.HasAccess = oHasAccess
|
||||
pUser.IsAdmin = oIsAdmin
|
||||
|
||||
pUser.GhostModeActive = oGhostmode
|
||||
Return pUser
|
||||
Catch ex As Exception
|
||||
Logger.Error(ex)
|
||||
@@ -70,9 +70,9 @@ Public Class UserModel
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Public Function SelectUserId() As Integer
|
||||
Public Function SelectUserId(oUserName As String) As Integer
|
||||
Try
|
||||
Dim oUserId As Integer = Database.GetScalarValue($"SELECT GUID FROM TBDD_USER WHERE USERNAME = '{Environment.UserName}'")
|
||||
Dim oUserId As Integer = Database.GetScalarValue($"SELECT GUID FROM TBDD_USER WHERE USERNAME = '{oUserName}'")
|
||||
Return oUserId
|
||||
|
||||
Catch ex As Exception
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user