Compare commits

...

116 Commits

Author SHA1 Message Date
811656c4ca create UpdateDocStatusCommand 2025-08-25 10:36:35 +02:00
7e90d25f0b create CreateDocStatusCommand 2025-08-25 10:24:15 +02:00
20751aa708 update to remove loadEnvelope-metod 2025-08-23 01:15:51 +02:00
51b96e2a81 move extension extensions dir 2025-08-23 00:57:55 +02:00
7a011930df remvoe sanitzer from views and use extensions instead of keys 2025-08-23 00:54:27 +02:00
a080aaec95 refactor(ViewControllerBase): remvoe sanitzer 2025-08-23 00:17:59 +02:00
d390802305 refactor(HomeController): remove culture binding as viewdata; bind via string localizer 2025-08-23 00:14:43 +02:00
0b33ba0fd8 update to use ClaimsPrincipal instead of ControllerBase 2025-08-22 22:29:51 +02:00
6778d8e3e7 refactor add culture midleware 2025-08-22 22:26:23 +02:00
3394a580f4 refactor(DocumentController): remvoe Open endpoint and its client method 2025-08-22 21:54:25 +02:00
82a63b0dae remove envelopeOldService 2025-08-22 21:44:49 +02:00
e61d626bf3 implement receiver already signed method 2025-08-22 21:38:53 +02:00
bd7c1d4e36 feat(ReceiverAlreadySignedQuery): create with handler 2025-08-22 21:34:33 +02:00
30e2ac602d change LoadEnvelope method 2025-08-22 20:05:53 +02:00
1577440b77 refactor(EnvelopeStatus); arrange naming 2025-08-22 19:34:04 +02:00
68a6a23a20 refactor(TestEnvelopeReceiverController): remove observed inhearence and rename.
- Add related attributes
2025-08-22 19:29:16 +02:00
5e5458d87c fix conflicts after updates 2025-08-22 19:19:59 +02:00
eae83adee4 refactor(ReadEnvelopeReceiverQuery): update response to return list instate of sigel instance 2025-08-22 18:01:31 +02:00
a29785f7c7 feat(EnvelopeReceiverControler): add test endpoint for ReadEnvelopeReceiverQuery 2025-08-22 17:37:55 +02:00
cb641fd33a feat: add TaskExtensions with null and empty result checks
- Introduced ThrowIfNull<T>(Task<T?>) extension method to ensure awaited result is not null, throwing NotFoundException otherwise
- Added ThrowIfNull<T>(Task<IEnumerable<T>?>) extension method to validate collections, throwing NotFoundException if null or empty
- Supports optional custom exception messages for better error context
2025-08-22 16:33:30 +02:00
9434832261 refactor(Application.Contracts): rename Application.Interfaces 2025-08-22 15:42:38 +02:00
b7e19db0f1 update to use Constants.EnvelopeStatus instead of int 2025-08-22 15:26:37 +02:00
290e87048c add logic for status query 2025-08-22 15:24:34 +02:00
c0a5b57668 refactor(ReadEnvelopeQuery): move EnvelopeStatusQuery from ReadEnvelopeReceiverQuery 2025-08-22 14:54:36 +02:00
02ef05f054 feat(envelope-receivers): add query handler for reading envelope receiver with filtering
- Implemented ReadEnvelopeReceiverQueryHandler using MediatR
- Added filtering support for Envelope (Id, Status, Uuid) and Receiver (Id, EmailAddress, Signature)
- Included related navigation properties (Envelope, Documents, Elements, History, User, Receiver)
- Mapped result to EnvelopeReceiverDto using AutoMapper
2025-08-21 18:32:41 +02:00
72134c3d3b add IRepository<EnvelopeReceiver> to ReadEnvelopeReceiverQueryHandler 2025-08-21 17:42:02 +02:00
a4fffaa9b9 init the handler of ReadEnvelopeReceiverQuery 2025-08-21 17:37:37 +02:00
3a62f5317f feat(ReadEnvelopeReceiverQuery): add Key-property 2025-08-21 17:36:18 +02:00
59c93de8b7 feat(ReceiverQuery): merge ReadReceiverQuery 2025-08-21 17:14:45 +02:00
5122a2099d remove ReadReceiverQuery and Read-dir 2025-08-21 17:12:36 +02:00
95ec19d816 rempve Read dir 2025-08-21 17:09:24 +02:00
c7b3d97b2e refactor: remove CreateEnvelopeReceiverResponse 2025-08-21 17:07:22 +02:00
196941f73f remove EnvelopeQuery 2025-08-21 16:56:22 +02:00
415fe646b2 simplify ReadDocumentQuery 2025-08-21 16:52:04 +02:00
f42218802d Standardisierung der Struktur von Mapping-Profildateien 2025-08-21 16:43:50 +02:00
fcf00171de move CreateEnvelopeResponse to CreateEnvelopeCommand file 2025-08-21 16:39:16 +02:00
ca28c4cca4 refactor(CreateEnvelopeResponse): update to use getter-initters 2025-08-21 16:36:34 +02:00
a48e4988d6 Verschieben die Klassen von CreateEnvelopeReceiverDtos nach CreateEnvelopeReceiverCommand. 2025-08-21 16:26:23 +02:00
ec513716ff remove read dir and move files 2025-08-21 16:24:04 +02:00
f39b761412 remove create folder and move the files 2025-08-21 16:04:06 +02:00
70d122d2ff refactor(EnvelopeGenerator.Application.DTOs): Umbenennen in EnvelopeGenerator.Application.Dto 2025-08-21 15:55:15 +02:00
5bc5fcf764 refactor(EnvelopeOldService): remove LoadEnvelopes-method 2025-08-21 15:47:04 +02:00
8db62b41ba refactor(EnvelopeReceiver): remove companyName property 2025-08-21 14:54:48 +02:00
0f27600c5b feat(ReceiverVM): add From method to be able to generate from EnvelopeReceiver 2025-08-21 14:43:56 +02:00
9045655262 fix(Designer): Nicht verfügbare Datenquelle entfernen 2025-08-21 14:18:28 +02:00
5bcac264a7 refactor(CommonServices): updated to use ReveiverVM 2025-08-21 14:13:31 +02:00
c7bf800cd5 feat(ReceiverVM): Handles the combination of the envelope and receiver for common services and submodules as a view model. 2025-08-21 13:52:03 +02:00
5fb4d03ee7 refactor(Receiver): bring related props from EnvelopeReceiver 2025-08-21 13:36:48 +02:00
ac70aaa527 refactor(EnvelopeReceiver): remove not-mapped attribute 2025-08-21 12:44:01 +02:00
e877000b14 fix(Receiver): Entfernen Sie unnötige Eigenschaften und/oder verschieben Sie sie nach EnvelopeReceiver. 2025-08-21 11:54:47 +02:00
305422688e add todo 2025-08-21 11:23:17 +02:00
9c6135d208 refactor(ReadOnlyController): Globale try-catch-Anweisungen entfernen 2025-08-21 11:06:06 +02:00
903e4678ed refactor(Document-, EnvelopeController): Globale try-catch-Anweisungen entfernen 2025-08-21 11:03:41 +02:00
730a318b56 feat(ExceptionHandlingMiddleware): Hinzufügen, um Ausnahmen global zu behandeln 2025-08-21 10:57:34 +02:00
55c0f44954 Refactor(EnvelopeModel): Entfernen Sie den unnötigen try-catch-Block in der Methode GetByUuid des EnvelopeModel. 2025-08-21 10:52:46 +02:00
dbb745338c Entfernen unnötige try-catch-Anweisungen. 2025-08-21 10:47:16 +02:00
419f421d52 refactor(DocResult): remove framework condition_ 2025-08-20 17:43:30 +02:00
e64ac4b5e7 fix(Envelope): remove farmework condition of tfa enabled 2025-08-20 17:21:19 +02:00
d8200993af feat(appsettings.Dev): remove wrong cnn string 2025-08-20 15:04:48 +02:00
ee98142405 refactor(Envelope): EnvelopeType in Type umbenennen 2025-08-19 15:37:12 +02:00
c27337a6f5 refactor(Envelope): make EnvelopeType nullable for only .net 2025-08-19 15:36:28 +02:00
a09ea990ab Revert "refactor(Envelope): remove EnvelopeType-property"
This reverts commit f4c61e3bc7.
2025-08-19 15:34:43 +02:00
05888bc57d revert(EnvelopeDocument): Add Filepath for .net framework
revert(EnvelopeHistory): Add AddedWhen, ActionDate and Comment for .net framework
2025-08-19 15:32:15 +02:00
39af0fe4fd feat(EnvelopeDocument): add System.Drawing-reference for .net-framework 2025-08-19 15:21:13 +02:00
f4c61e3bc7 refactor(Envelope): remove EnvelopeType-property 2025-08-19 15:20:00 +02:00
3f5a584399 refactor: Anpassung der Klassen-Definition für EnvelopeHistory zur Unterstützung von NET und NETFRAMEWORK 2025-08-19 15:11:42 +02:00
6aec854a64 refactor(EnvelopeHistory): Anpassung der Klassen-Definition für EnvelopeHistory zur Unterstützung von NET und NETFRAMEWORK 2025-08-19 15:06:00 +02:00
c360bde103 remove unnecessary references 2025-08-19 15:02:36 +02:00
82d4b0e740 refactor(EnvelopeDocument): Überarbeitung der Klasse EnvelopeDocument für .NET/Framework Kompatibilität
- Hinzugefügt: bedingte Namensraum-Deklaration für NET und NETFRAMEWORK
- Konstruktor eingeführt mit Initialisierung von Elements (nur .NET Framework)
- Entfernt: Property AddedWhen
- Verschoben: FileNameOriginal, IsTempFile, Filename, Filepath, Thumbnail, PageCount
  → nur verfügbar unter .NET Framework
- Entfernt Standardinitialisierung von Elements, stattdessen abhängig von Laufzeitumgebung
2025-08-19 15:02:05 +02:00
12519f06f7 refactor(EnvelopeCertificate): Entfernen Sie die Domäne, das Repository, die DTOs und den Dienst mit allen Schnittstellen. 2025-08-19 14:48:15 +02:00
a2471a0c35 refactor(EmailTemplate): adjust namespace declaration for EmailTemplate to support NET and NETFRAMEWORK 2025-08-19 14:35:35 +02:00
4251a24fe9 refactor(DocumentStatus): DocumentStatus-Klasse für plattformübergreifende Kompilierung angepasst
- Status-Default-Wert in Konstruktor verschoben, nur für NETFRAMEWORK gesetzt
- Klasse für NET/NETFRAMEWORK conditional compilation angepasst
- Unnötige Properties (StatusChangedWhen, AddedWhen, ChangedWhen, Navigation Properties) entfernt
- TODO-Kommentar für Status-Überprüfung erhalten
2025-08-19 14:31:11 +02:00
63a830c8e3 refactor(DocumentReceiverElement): Trenne .NET- und .NET Framework-spezifische Initialisierung in DocumentReceiverElement
- Verschiebe Standardwerte für Id, Required, ReadOnly und AnnotationIndex in den Konstruktor für .NET Framework
- Passe #if-Direktiven an, um Namensräume und NotMapped-Eigenschaften korrekt zu handhaben
- Entferne redundante Standardwert-Zuweisungen bei Property-Deklarationen
- Bereite Klasse für plattformübergreifende Nutzung vor
2025-08-19 14:26:14 +02:00
acee28ffce refactor: add conditional compilation for .NET and .NET Framework 2025-08-19 14:18:01 +02:00
50a541c5bf refactor: Plattform-spezifische Anpassungen an der Receiver-Klasse
- `NotMapped` Properties nur für NETFRAMEWORK verfügbar gemacht
- Klasse und Namespaces für NET- und NETFRAMEWORK-Bedingungen angepasst
- Redundant in NET definierten Code entfernt
2025-08-19 14:14:10 +02:00
d43877db62 refactor(Envelope): Standardwerte in der Envelope-Entity in den Konstruktor verschoben 2025-08-19 14:06:17 +02:00
242e66cd8d refactor(Receiver): make TfaRegDeadline nullable 2025-08-19 12:47:57 +02:00
e44fa0b7bd chore Upg UserManager 2025-08-19 12:13:30 +02:00
4201f7820a refactor(Envelope): Envelope-Entitätseigenschaften für NET/NETFRAMEWORK nullfähig und bedingt machen
- Mehrere DateTime- und int-Eigenschaften in nullfähige Typen geändert
- Bedingte Kompilierung für Message, Title, ContractTypeTranslated und StatusTranslated angewendet
- Einige Standardwerte entfernt, um die Kompatibilität mit verschiedenen Frameworks zu verbessern
- Flexibilität der Entitätszuordnung für Envelope verbessert
2025-08-19 11:12:41 +02:00
e095074c22 chore(Application): Aktualisierung zur Verwendung der bedingten Versionsverwaltung für Abhängigkeiten 2025-08-19 09:43:37 +02:00
412f19547f fix(Envelope): Entfernen das Attribut „NotMapped“. 2025-08-19 09:27:27 +02:00
b8c00884a9 Merge EnvelopeReceiver and EnvelopeReceiverBase 2025-08-13 16:35:51 +02:00
51d49d68ba fix(Envelope): Fügen Nicht-relationalen Eigenschaften NotMapped-Attribute hinzu. 2025-08-13 16:07:26 +02:00
4d5ee2b461 fix(MailParams): make Placeholders Dictionary 2025-08-13 13:03:56 +02:00
8a79ee4126 Stil: BaseController auf Datei-Namensraumformat umstellen 2025-08-12 11:24:38 +02:00
cde9896c01 Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-08-07 17:01:51 +02:00
c7d26a87b0 fix(EnvelopeMailService): Vermeiden Sie gemeinsam genutzte veränderbare Zustände in EnvelopeMailService-Platzhaltern
EnvelopeMailService wurde umgestaltet, um gemeinsam genutzte Veränderungen des _placeholders-Wörterbuchs zu vermeiden.
Die Konfigurationseigenschaft MailParams.Placeholders wurde von einem veränderbaren Dictionary<string, string>
zu einem ImmutableDictionary<string, string> geändert, und _placeholders wird nun bei der Dienstkonstruktion als neues Wörterbuch instanziiert.
2025-08-07 17:01:32 +02:00
17ceb1f72a Update EnvelopeGenerator.Web/wwwroot/README.md 2025-08-06 09:48:34 +02:00
b2c396c3b2 Add EnvelopeGenerator.Web/wwwroot/README.md 2025-08-06 09:45:11 +02:00
Developer01
286e17a900 layout specihern 2025-07-18 15:42:07 +02:00
Developer01
a21db6d6c5 Button AccessCode manuell versenden 2025-07-15 07:27:01 +02:00
Developer01
fe7030b9d7 Resend AccessCode Manually 2025-07-14 15:19:05 +02:00
Developer01
888c04b5c9 EnvelopeDomain Add Comment 2025-07-14 13:45:14 +02:00
de2cc62f95 Merge branch 'master' of http://git.dd:3000/AppStd/EnvelopeGenerator 2025-07-02 14:26:08 +02:00
0cfa732d87 Fix StatusTranslated property for correct enum translation
Updated the `StatusTranslated` property to cast the `Status` integer to the `Constants.EnvelopeStatus` enum before calling `ToString()`. This ensures accurate string representation based on the enum rather than the integer value.
2025-07-02 14:25:14 +02:00
Developer01
b14d9169f2 Fild editor msgbox 2025-07-02 13:18:01 +02:00
be51ca31dd Add initial migration for database schema setup
This commit introduces the `InitialCreate` migration class, establishing the initial database schema with multiple tables including `TBDD_CLIENT_USER`, `TBDD_GROUPS`, `TBDD_MODULES`, and `TBDD_USER`. Foreign key relationships are defined to ensure referential integrity, and a `Down` method is included for rollback functionality.

Additionally, the `InitialCreate.Designer.cs` file is generated to capture the model snapshot post-migration, while the `EGDbContextModelSnapshot.cs` file is updated to reflect the current state of the database model for future migrations.
2025-07-01 17:22:13 +02:00
bb8d7cd208 Update AddedWho property in EnvelopeReceiverReadOnly
Modified the `AddedWho` property to use `nvarchar(250)`
and increased the string length constraint from 100 to 250
characters, allowing for more extensive data storage.
2025-07-01 17:17:24 +02:00
b6588db615 Increase email address length in data models
Updated `ReceiverMail` and `EmailAddress` columns to
support `nvarchar(250)` for longer email addresses.
Retained `[NotMapped]` attribute for `Envelope` in
`EnvelopeReceiverReadOnly.cs` with a note for future
standardization of `EnvelopeId` data type.
2025-07-01 17:08:30 +02:00
9a9aa2608b Refactor EnvelopeHistory and update DbContext for migrations
Removed Sender and Receiver properties from EnvelopeHistory.
Added ActionDate and Comment properties. Introduced IsMigration
property in EGDbContext to conditionally configure foreign key
relationships for EnvelopeHistory. Updated EGDbContextFactory
to set IsMigration during context creation for migration operations.
2025-07-01 16:38:42 +02:00
349d65d050 Update DbTriggerParams and EF Core package versions
- Changed DbTriggerParams to use ICollection<string> for flexibility.
- Updated Microsoft.EntityFrameworkCore.SqlServer to version 9.0.6.
- Made _logger in EGDbContext nullable and optional in constructor.
- Updated logging statements to prevent null reference exceptions.
- Added Microsoft.EntityFrameworkCore.SqlServer package for net8.0 and net9.0.
- Introduced appsettings.migration.json for connection strings and trigger parameters.
- Added EGDbContextFactory for design-time DbContext creation.
2025-07-01 13:07:40 +02:00
93593226e2 Add conditional DB connection string selection
Updated `Program.cs` to conditionally select the database connection string based on an environment variable or configuration setting. Introduced a new variable `cnnStrName` for determining the use of a migration test database.

Added a new setting `"UseDbMigration": true` in `appsettings.json` to enable the migration test database, and included the corresponding connection string as `"DbMigrationTest"`. Removed the previous `"Dev"` connection string.
2025-06-30 16:19:22 +02:00
351cead423 Update Entity Framework packages and add Design package
The project file `EnvelopeGenerator.Infrastructure.csproj` has been modified to include the `Microsoft.EntityFrameworkCore.Design` package for net7.0, net8.0, and net9.0, with appropriate configurations for `PrivateAssets` and `IncludeAssets`. Additionally, the versions of `Microsoft.EntityFrameworkCore` and `Microsoft.EntityFrameworkCore.Relational` have been updated for net8.0 (from 8.0.15 to 8.0.17) and net9.0 (from 9.0.5 to 9.0.6).
2025-06-30 15:59:35 +02:00
07cab88e0d Refactor service registration with lambda expression 2025-06-30 15:53:38 +02:00
faa019355a Add DbMigrationTest key and update connection logic
Introduced a new static readonly string `DbMigrationTest` in the `Key` class for database migration tests. Updated connection string logic in `Program.cs` to use `DbMigrationTest` when `useDbMigration` is true, allowing for dynamic connection string selection based on environment configuration.
2025-06-30 15:38:01 +02:00
df9bcf3221 Remove IUserReceiverService registration 2025-06-30 15:29:57 +02:00
cda19e2b83 Add migration support and update launch settings
Introduce `useDbMigration` variable in `Program.cs` to conditionally manage database migrations based on environment settings. Update `launchSettings.json` to include a new `httpsDbMigration` profile for testing with Swagger UI. Modify `appsettings.json` to add `UseDbMigration` setting and replace the "Dev" connection string with "DbMigrationTest" for migration testing.
2025-06-30 15:29:47 +02:00
1586009a72 Add development connection string to appsettings.json 2025-06-30 15:07:04 +02:00
408b1e9f0d Merge branch 'refactor/split-common' 2025-06-30 14:59:37 +02:00
9158933333 Refactor security key handling and culture info setup
Updated `IssuerSigningKeyResolver` to use array syntax for returning security keys. Changed supported culture names declaration to use square brackets and modified the creation of the `CultureInfo` list to utilize the spread operator. Adjusted exception handling to throw `InvalidOperationException` when no supported culture is found.
2025-06-30 14:36:55 +02:00
902848958d Refactor empty array initialization 2025-06-30 14:26:26 +02:00
f5418499a7 Refactor envelope generator service registration 2025-06-30 14:25:32 +02:00
47d190d9ea Remove UserReceiver repository registration 2025-06-30 14:23:20 +02:00
35f46d3182 Remove UserReceiver repository and related entities
This commit removes the `IUserReceiverRepository` service registration from `DIExtensions`, indicating it is no longer needed. The `UserReceiver` and `Config` DbSet properties have been eliminated from the `EGDbContext`, along with their initialization in the constructor. Additionally, the `UserReceiver` entity has been removed from the model builder configuration and the associated trigger has been deleted. These changes reflect a refactoring of the data model to simplify the architecture and improve maintainability.
2025-06-30 14:23:00 +02:00
f5733228bf Merge branch 'refactor/split-common' 2025-06-30 11:28:32 +02:00
Developer01
260c1c174d Merge Master 2025-06-30 11:26:46 +02:00
252 changed files with 6693 additions and 2457 deletions

View File

@@ -3,6 +3,6 @@
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class DbTriggerParams : Dictionary<string, IEnumerable<string>> public class DbTriggerParams : Dictionary<string, ICollection<string>>
{ {
} }

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public interface IEnvelopeCertificateRepository : ICRUDRepository<EnvelopeCertificate, int>
{
}

View File

@@ -1,13 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeCertificateService : IBasicCRUDService<EnvelopeCertificateDto, EnvelopeCertificate, int>
{
}

View File

@@ -1,50 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing certificate information for an envelope.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class EnvelopeCertificateDto
{
/// <summary>
/// Gets the unique identifier of the certificate.
/// </summary>
public int Id { get; init; }
/// <summary>
/// Gets the envelope ID associated with the certificate.
/// </summary>
public int EnvelopeId { get; init; }
/// <summary>
/// Gets the UUID of the envelope.
/// </summary>
public string EnvelopeUuid { get; init; } = string.Empty;
/// <summary>
/// Gets the subject of the envelope.
/// </summary>
public string EnvelopeSubject { get; init; } = string.Empty;
/// <summary>
/// Gets the ID of the creator of the envelope.
/// </summary>
public int CreatorId { get; init; }
/// <summary>
/// Gets the name of the creator.
/// </summary>
public string CreatorName { get; init; } = string.Empty;
/// <summary>
/// Gets the email address of the creator.
/// </summary>
public string CreatorEmail { get; init; } = string.Empty;
/// <summary>
/// Gets the current status of the envelope.
/// </summary>
public int EnvelopeStatus { get; init; }
}

View File

@@ -5,9 +5,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using DigitalData.Core.Client; using DigitalData.Core.Client;
using QRCoder; using QRCoder;
using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.Interfaces.Services;
using System.Reflection; using System.Reflection;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create; using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
namespace EnvelopeGenerator.Application; namespace EnvelopeGenerator.Application;
@@ -33,12 +33,10 @@ public static class DependencyInjection
services.TryAddScoped<IDocumentStatusService, DocumentStatusService>(); services.TryAddScoped<IDocumentStatusService, DocumentStatusService>();
services.TryAddScoped<IEmailTemplateService, EmailTemplateService>(); services.TryAddScoped<IEmailTemplateService, EmailTemplateService>();
services.TryAddScoped<IEnvelopeService, EnvelopeService>(); services.TryAddScoped<IEnvelopeService, EnvelopeService>();
services.TryAddScoped<IEnvelopeCertificateService, EnvelopeCertificateService>();
services.TryAddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>(); services.TryAddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
services.TryAddScoped<IEnvelopeReceiverService, EnvelopeReceiverService>(); services.TryAddScoped<IEnvelopeReceiverService, EnvelopeReceiverService>();
services.TryAddScoped<IEnvelopeTypeService, EnvelopeTypeService>(); services.TryAddScoped<IEnvelopeTypeService, EnvelopeTypeService>();
services.TryAddScoped<IReceiverService, ReceiverService>(); services.TryAddScoped<IReceiverService, ReceiverService>();
services.TryAddScoped<IUserReceiverService, UserReceiverService>();
services.TryAddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>(); services.TryAddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
//Auto mapping profiles //Auto mapping profiles

View File

@@ -0,0 +1,19 @@
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.DocStatus.Commands;
/// <summary>
///
/// </summary>
public class CreateDocStatusCommand : UpdateDocStatusCommand
{
/// <summary>
/// Gets timestamp when this record was added. Returns the current date and time.
/// </summary>
public DateTime AddedWhen => StatusChangedWhen;
/// <summary>
/// Gets timestamp when this record was added. Returns the current date and time.
/// </summary>
public override DateTime? ChangedWhen { get; } = null;
}

View File

@@ -0,0 +1,39 @@
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.DocStatus.Commands;
/// <summary>
///
/// </summary>
public class UpdateDocStatusCommand
{
/// <summary>
/// Gets or sets the ID of the associated envelope.
/// </summary>
public int EnvelopeId { get; set; }
/// <summary>
/// Gets or sets the ID of the receiver associated with this status.
/// </summary>
public int ReceiverId { get; set; }
/// <summary>
/// Gets the current status code.
/// </summary>
public Constants.DocumentStatus Status => Value is null ? Constants.DocumentStatus.Created : Constants.DocumentStatus.Signed;
/// <summary>
/// Gets the timestamp when the status was changed. Retrns the AddedWhen value.
/// </summary>
public DateTime StatusChangedWhen { get; } = DateTime.Now;
/// <summary>
/// Gets or sets the display value associated with the status.
/// </summary>
public string? Value { get; set; }
/// <summary>
/// Gets timestamp when this record was added. Returns the current date and time.
/// </summary>
public virtual DateTime? ChangedWhen { get; } = DateTime.Now;
}

View File

@@ -1,18 +0,0 @@
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>();
}
}

View File

@@ -1,12 +0,0 @@
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?>
{
}

View File

@@ -1,12 +0,0 @@
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; }
}

View File

@@ -1,22 +0,0 @@
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; }
}

View File

@@ -1,46 +1,67 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Application.Dto;
using MediatR; using MediatR;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using AutoMapper;
namespace EnvelopeGenerator.Application.Documents.Queries.Read; namespace EnvelopeGenerator.Application.Documents.Queries;
/// <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<EnvelopeDocumentDto?>
{
}
/// <summary> /// <summary>
/// Handles queries for reading <see cref="EnvelopeDocument"/> data based on either the document ID or the envelope ID. /// Handles queries for reading <see cref="EnvelopeDocument"/> data based on either the document ID or the envelope ID.
/// </summary> /// </summary>
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, ReadDocumentResponse?> public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, EnvelopeDocumentDto?>
{ {
/// <summary> /// <summary>
/// Repository for accessing <see cref="EnvelopeDocument"/> entities. /// Repository for accessing <see cref="EnvelopeDocument"/> entities.
/// </summary> /// </summary>
private readonly IRepository<EnvelopeDocument> _repo; private readonly IRepository<EnvelopeDocument> _repo;
private readonly IMapper _mapper;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ReadDocumentQueryHandler"/> class. /// Initializes a new instance of the <see cref="ReadDocumentQueryHandler"/> class.
/// </summary> /// </summary>
/// <param name="envelopeDocumentRepository">The repository used to access <see cref="EnvelopeDocument"/> entities.</param> /// <param name="envelopeDocumentRepository">The repository used to access <see cref="EnvelopeDocument"/> entities.</param>
public ReadDocumentQueryHandler(IRepository<EnvelopeDocument> envelopeDocumentRepository) public ReadDocumentQueryHandler(IRepository<EnvelopeDocument> envelopeDocumentRepository, IMapper mapper)
{ {
_repo = envelopeDocumentRepository; _repo = envelopeDocumentRepository;
_mapper = mapper;
} }
/// <summary> /// <summary>
/// Handles the <see cref="ReadDocumentQuery"/> and returns a <see cref="ReadDocumentResponse"/> based on the provided identifiers. /// Handles the <see cref="ReadDocumentQuery"/> and returns a <see cref="EnvelopeDocumentDto"/> based on the provided identifiers.
/// </summary> /// </summary>
/// <param name="query">The query containing the document ID or envelope ID to search for.</param> /// <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> /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns> /// <returns>
/// A <see cref="ReadDocumentResponse"/> if a matching document is found; otherwise, <c>null</c>. /// A <see cref="EnvelopeDocumentDto"/> if a matching document is found; otherwise, <c>null</c>.
/// </returns> /// </returns>
/// <exception cref="InvalidOperationException"> /// <exception cref="InvalidOperationException">
/// Thrown when neither <see cref="ReadDocumentQuery.Id"/> nor <see cref="ReadDocumentQuery.EnvelopeId"/> is provided. /// Thrown when neither <see cref="ReadDocumentQuery.Id"/> nor <see cref="ReadDocumentQuery.EnvelopeId"/> is provided.
/// </exception> /// </exception>
[Obsolete("Use MediatR")] [Obsolete("Use MediatR")]
public async Task<ReadDocumentResponse?> Handle(ReadDocumentQuery query, CancellationToken cancellationToken) public async Task<EnvelopeDocumentDto?> Handle(ReadDocumentQuery query, CancellationToken cancellationToken)
{ {
if (query.Id is not null) if (query.Id is not null)
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.Id == query.Id); {
var doc = await _repo.ReadOnly().Where(d => d.Id == query.Id).FirstOrDefaultAsync();
return _mapper.Map<EnvelopeDocumentDto>(doc);
}
else if (query.EnvelopeId is not null) else if (query.EnvelopeId is not null)
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.EnvelopeId == query.EnvelopeId); {
var doc = await _repo.ReadOnly().Where(d => d.EnvelopeId == query.EnvelopeId).FirstOrDefaultAsync();
return _mapper.Map<EnvelopeDocumentDto>(doc);
}
throw new InvalidOperationException( throw new InvalidOperationException(
$"Invalid {nameof(ReadDocumentQuery)}: either {nameof(query.Id)} or {nameof(query.EnvelopeId)} must be provided."); $"Invalid {nameof(ReadDocumentQuery)}: either {nameof(query.Id)} or {nameof(query.EnvelopeId)} must be provided.");

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// Data Transfer Object representing configuration settings. /// Data Transfer Object representing configuration settings.

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// Data Transfer Object representing a positioned element assigned to a document receiver. /// Data Transfer Object representing a positioned element assigned to a document receiver.

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// Data Transfer Object representing the status of a document for a specific receiver. /// Data Transfer Object representing the status of a document for a specific receiver.

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs namespace EnvelopeGenerator.Application.Dto
{ {
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// Data Transfer Object representing a document within an envelope, including optional binary data and form elements. /// Data Transfer Object representing a document within an envelope, including optional binary data and form elements.

View File

@@ -3,7 +3,7 @@ using DigitalData.UserManager.Application.DTOs.User;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory; namespace EnvelopeGenerator.Application.Dto.EnvelopeHistory;
/// <summary> /// <summary>
/// Data Transfer Object for creating a new envelope history record. /// Data Transfer Object for creating a new envelope history record.

View File

@@ -1,8 +1,8 @@
using DigitalData.UserManager.Application.DTOs.User; using DigitalData.UserManager.Application.DTOs.User;
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using static EnvelopeGenerator.Domain.Constants; using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory; namespace EnvelopeGenerator.Application.Dto.EnvelopeHistory;
/// <summary> /// <summary>
/// Data Transfer Object representing the history of an envelope, including status, sender, receiver, and related metadata. /// Data Transfer Object representing the history of an envelope, including status, sender, receiver, and related metadata.
@@ -25,7 +25,7 @@ public record EnvelopeHistoryDto
public required string UserReference { get; set; } public required string UserReference { get; set; }
/// <summary> /// <summary>
/// Status code of the envelope at this history point. /// Include code of the envelope at this history point.
/// </summary> /// </summary>
public int Status { get; set; } public int Status { get; set; }

View File

@@ -1,7 +1,7 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; namespace EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; namespace EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; namespace EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
/// <summary> /// <summary>
/// ///

View File

@@ -2,7 +2,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; namespace EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; namespace EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
/// <summary> /// <summary>
/// Represents a read-only Data Transfer Object (DTO) for an envelope receiver. /// Represents a read-only Data Transfer Object (DTO) for an envelope receiver.

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; namespace EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
/// <summary> /// <summary>
/// Data Transfer Object for updating a read-only envelope receiver. /// Data Transfer Object for updating a read-only envelope receiver.

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// Data Transfer Object representing a type of envelope with its configuration settings. /// Data Transfer Object representing a type of envelope with its configuration settings.

View File

@@ -1,13 +1,13 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Application.Dto.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Dto.Messaging;
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Application.Extensions; using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.DTOs; namespace EnvelopeGenerator.Application.Dto;
/// <summary> /// <summary>
/// Represents the AutoMapper profile configuration for mapping between /// Represents the AutoMapper profile configuration for mapping between
@@ -27,7 +27,6 @@ public class MappingProfile : Profile
CreateMap<DocumentStatus, DocumentStatusDto>(); CreateMap<DocumentStatus, DocumentStatusDto>();
CreateMap<EmailTemplate, EmailTemplateDto>(); CreateMap<EmailTemplate, EmailTemplateDto>();
CreateMap<Envelope, EnvelopeDto>(); CreateMap<Envelope, EnvelopeDto>();
CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>();
CreateMap<EnvelopeDocument, EnvelopeDocumentDto>(); CreateMap<EnvelopeDocument, EnvelopeDocumentDto>();
CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryDto>(); CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryDto>();
CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryCreateDto>(); CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryCreateDto>();
@@ -45,7 +44,6 @@ public class MappingProfile : Profile
CreateMap<DocumentStatusDto, DocumentStatus>(); CreateMap<DocumentStatusDto, DocumentStatus>();
CreateMap<EmailTemplateDto, EmailTemplate>(); CreateMap<EmailTemplateDto, EmailTemplate>();
CreateMap<EnvelopeDto, Envelope>(); CreateMap<EnvelopeDto, Envelope>();
CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>();
CreateMap<EnvelopeDocumentDto, EnvelopeDocument>(); CreateMap<EnvelopeDocumentDto, EnvelopeDocument>();
CreateMap<EnvelopeHistoryDto, Domain.Entities.EnvelopeHistory>(); CreateMap<EnvelopeHistoryDto, Domain.Entities.EnvelopeHistory>();
CreateMap<EnvelopeHistoryCreateDto, Domain.Entities.EnvelopeHistory>(); CreateMap<EnvelopeHistoryCreateDto, Domain.Entities.EnvelopeHistory>();
@@ -54,7 +52,7 @@ public class MappingProfile : Profile
CreateMap<ReceiverReadDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore()); CreateMap<ReceiverReadDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
CreateMap<ReceiverCreateDto, Domain.Entities.Receiver>(); CreateMap<ReceiverCreateDto, Domain.Entities.Receiver>();
CreateMap<ReceiverUpdateDto, Domain.Entities.Receiver>(); CreateMap<ReceiverUpdateDto, Domain.Entities.Receiver>();
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>(); CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverBasicDto>();
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>(); CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>(); CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.Messaging; namespace EnvelopeGenerator.Application.Dto.Messaging;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.Messaging; namespace EnvelopeGenerator.Application.Dto.Messaging;
/// <summary> /// <summary>
/// ///

View File

@@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
namespace EnvelopeGenerator.Application.DTOs.Receiver; namespace EnvelopeGenerator.Application.Dto.Receiver;
/// <summary> /// <summary>
/// ///

View File

@@ -1,8 +1,8 @@
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.DTOs.Receiver; namespace EnvelopeGenerator.Application.Dto.Receiver;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.Receiver; namespace EnvelopeGenerator.Application.Dto.Receiver;
/// <summary> /// <summary>
/// Data Transfer Object for updating a receiver's information. /// Data Transfer Object for updating a receiver's information.

View File

@@ -1,7 +1,9 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using MediatR; using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset; namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
@@ -31,10 +33,10 @@ public class ResetEmailTemplateCommandHandler : IRequestHandler<ResetEmailTempla
public async Task Handle(ResetEmailTemplateCommand request, CancellationToken cancel) public async Task Handle(ResetEmailTemplateCommand request, CancellationToken cancel)
{ {
var temps = request.Id is not null var temps = request.Id is not null
? await _repository.ReadAllAsync<EmailTemplateDto>(t => t.Id == request.Id, cancel) ? await _repository.ReadOnly().Where(t => t.Id == request.Id).ToListAsync(cancel)
: request.Type is not null : request.Type is not null
? await _repository.ReadAllAsync<EmailTemplateDto>(t => t.Name == request.Type.ToString(), cancel) ? await _repository.ReadOnly().Where(t => t.Name == request.Type.ToString()).ToListAsync(cancel)
: await _repository.ReadAllAsync<EmailTemplateDto>(cancellation: cancel); : await _repository.ReadOnly().ToListAsync(cancel);
foreach (var temp in temps) foreach (var temp in temps)
{ {
@@ -82,7 +84,7 @@ public class ResetEmailTemplateCommandHandler : IRequestHandler<ResetEmailTempla
new(){ new(){
Id = 6, Id = 6,
Name = "DocumentRejected_ADM", 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]", 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 Include Rejected gesetzt. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "'[DOCUMENT_TITLE]' - Unterzeichnungsvorgang zurückgezogen" Subject = "'[DOCUMENT_TITLE]' - Unterzeichnungsvorgang zurückgezogen"
}, },
new(){ new(){

View File

@@ -1,9 +1,11 @@
using DigitalData.Core.Abstraction.Application.Repository; using AutoMapper;
using EnvelopeGenerator.Application.DTOs; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Application.Exceptions; using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Domain; using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using MediatR; using MediatR;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update; namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
@@ -14,13 +16,16 @@ public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemp
{ {
private readonly IRepository<EmailTemplate> _repository; private readonly IRepository<EmailTemplate> _repository;
private readonly IMapper _mapper;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="repository"></param> /// <param name="repository"></param>
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository) public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository, IMapper mapper)
{ {
_repository = repository; _repository = repository;
_mapper = mapper;
} }
/// <summary> /// <summary>
@@ -34,32 +39,34 @@ public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemp
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")] [Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public async Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel) public async Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel)
{ {
EmailTemplateDto? temp; EmailTemplateDto? tempDto;
if (request.EmailTemplateQuery?.Id is int id) if (request.EmailTemplateQuery?.Id is int id)
{ {
temp = await _repository.ReadOrDefaultAsync<EmailTemplateDto>(t => t.Id == id, single: false, cancel); var temp = await _repository.ReadOnly().Where(t => t.Id == id).FirstOrDefaultAsync(cancel);
tempDto = _mapper.Map<EmailTemplateDto>(temp);
} }
else if (request!.EmailTemplateQuery!.Type is Constants.EmailTemplateType type) else if (request!.EmailTemplateQuery!.Type is Constants.EmailTemplateType type)
{ {
temp = await _repository.ReadOrDefaultAsync<EmailTemplateDto>(t => t.Name == type.ToString(), single: false, cancel); var temp = await _repository.ReadOnly().Where(t => t.Name == type.ToString()).FirstOrDefaultAsync(cancel);
tempDto = _mapper.Map<EmailTemplateDto>(temp);
} }
else else
{ {
throw new InvalidOperationException("Both id and type is null. Id: " + request.EmailTemplateQuery.Id +". Type: " + request.EmailTemplateQuery.Type.ToString()); throw new InvalidOperationException("Both id and type is null. Id: " + request.EmailTemplateQuery.Id +". Type: " + request.EmailTemplateQuery.Type.ToString());
} }
if (temp == null) if (tempDto == null)
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
if (request.Body is not null) if (request.Body is not null)
temp.Body = request.Body; tempDto.Body = request.Body;
if (request.Subject is not null) if (request.Subject is not null)
temp.Subject = request.Subject; tempDto.Subject = request.Subject;
await _repository.UpdateAsync(temp, t => t.Id == temp.Id, cancel); await _repository.UpdateAsync(tempDto, t => t.Id == tempDto.Id, cancel);
} }
} }

View File

@@ -1,4 +1,5 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -6,17 +7,17 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read; namespace EnvelopeGenerator.Application.EmailTemplates;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ReadEmailTemplateMappingProfile : Profile public class MappingProfile : Profile
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ReadEmailTemplateMappingProfile() public MappingProfile()
{ {
CreateMap<EmailTemplate, ReadEmailTemplateResponse>(); CreateMap<EmailTemplate, ReadEmailTemplateResponse>();
} }

View File

@@ -1,5 +1,5 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.Contracts.Repositories; using EnvelopeGenerator.Application.Interfaces.Repositories;
using EnvelopeGenerator.Domain; using EnvelopeGenerator.Domain;
using MediatR; using MediatR;

View File

@@ -14,17 +14,28 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.0.0" /> <PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.1.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.3.4" /> <PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />
<PackageReference Include="DigitalData.Core.Client" Version="2.1.0" /> <PackageReference Include="DigitalData.Core.Client" Version="2.1.0" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" /> <PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" />
<PackageReference Include="MediatR" Version="12.5.0" /> <PackageReference Include="MediatR" Version="12.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
<PackageReference Include="Otp.NET" Version="1.4.0" /> <PackageReference Include="Otp.NET" Version="1.4.0" />
<PackageReference Include="QRCoder" Version="1.6.0" /> <PackageReference Include="QRCoder" Version="1.6.0" />
<PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" /> <PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" />
<PackageReference Include="UserManager" Version="1.1.1" /> <PackageReference Include="UserManager" Version="1.1.3" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,21 +0,0 @@
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>;

View File

@@ -1,21 +0,0 @@
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>();
}
}

View File

@@ -1,39 +0,0 @@
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>();
}

View File

@@ -1,13 +1,26 @@
using System; using EnvelopeGenerator.Application.Envelopes.Commands;
using System.Collections.Generic; using MediatR;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create; namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
#region DTOs /// <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>;
#region Subcommands
/// <summary> /// <summary>
/// Signaturposition auf einem Dokument. /// Signaturposition auf einem Dokument.
/// </summary> /// </summary>

View File

@@ -1,10 +1,10 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor; using EnvelopeGenerator.Application.Interfaces.SQLExecutor;
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using MediatR; using MediatR;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create; namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
/// <summary> /// <summary>
/// Handles the creation of an envelope along with its associated document and recipients. /// Handles the creation of an envelope along with its associated document and recipients.

View File

@@ -0,0 +1,20 @@
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Application.Dto.Receiver;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
/// <summary>
///
/// </summary>
public record CreateEnvelopeReceiverResponse : EnvelopeDto
{
/// <summary>
///
/// </summary>
public IEnumerable<ReceiverReadDto> SentReceiver { get; set; } = new List<ReceiverReadDto>();
/// <summary>
///
/// </summary>
public IEnumerable<ReceiverGetOrCreateCommand> UnsentReceivers { get; set; } = new List<ReceiverGetOrCreateCommand>();
}

View File

@@ -0,0 +1,20 @@
using AutoMapper;
using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.EnvelopeReceivers;
/// <summary>
///
/// </summary>
public class MappingProfile : Profile
{
/// <summary>
///
/// </summary>
public MappingProfile()
{
CreateMap<Receiver, ReceiverReadDto>();
}
}

View File

@@ -1,30 +0,0 @@
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>
/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers.
/// </summary>
/// <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; }
};

View File

@@ -1,94 +0,0 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
using EnvelopeGenerator.Application.Receivers.Queries.Read;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
/// <summary>
/// Repräsentiert die Antwort für das Lesen eines Envelope-Empfängers.
/// </summary>
/// <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>();
}

View File

@@ -0,0 +1,105 @@
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Application.Receivers.Queries;
using EnvelopeGenerator.Extensions;
using MediatR;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
/// <summary>
/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers.
/// Invalid (0): Ungültiger Include.
/// 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.
/// </summary>
/// <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="EnvelopeReceiverDto"/>) zu generieren.
/// Die Antwort enthält Details wie den Include, die Zuordnung zwischen Umschlag und Empfänger
/// sowie zusätzliche Metadaten.
/// </remarks>
public record ReadEnvelopeReceiverQuery : IRequest<IEnumerable<EnvelopeReceiverDto>>
{
/// <summary>
///
/// </summary>
public string? Key
{
get => Envelope?.Uuid is string uuid && Receiver?.Signature is string signature
? (uuid, signature).EncodeEnvelopeReceiverId()
: null;
init
{
if (value is null)
return;
(string? EnvelopeUuid, string? ReceiverSignature) = value.DecodeEnvelopeReceiverId();
if(string.IsNullOrEmpty(EnvelopeUuid) || string.IsNullOrEmpty(ReceiverSignature))
{
throw new BadRequestException("Der EnvelopeReceiverKey muss ein gültiger Base64-kodierter String sein, der die EnvelopeUuid und die ReceiverSignature enthält.");
}
Envelope = new ReadEnvelopeQuery()
{
Uuid = EnvelopeUuid
};
Receiver = new ReadReceiverQuery()
{
Signature = ReceiverSignature
};
}
}
/// <summary>
/// Der Umschlag, der mit dem Empfänger verknüpft ist.
/// </summary>
public ReadEnvelopeQuery? Envelope { get; set; }
/// <summary>
/// Der Empfänger, der mit dem Umschlag verknüpft ist.
/// </summary>
public ReadReceiverQuery? Receiver { get; set; }
};
/// <summary>
///
/// </summary>
public static class Extensions
{
/// <summary>
///
/// </summary>
/// <param name="mediator"></param>
/// <param name="key"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<EnvelopeReceiverDto?> ReadEnvelopeReceiverAsync(this IMediator mediator, string key, CancellationToken cancel = default)
{
var q = new ReadEnvelopeReceiverQuery() { Key = key };
return mediator.Send(q, cancel).Then(envRcvs => envRcvs.FirstOrDefault());
}
}

View File

@@ -0,0 +1,87 @@
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
/// <summary>
///
/// </summary>
public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeReceiverQuery, IEnumerable<EnvelopeReceiverDto>>
{
private readonly IRepository<EnvelopeReceiver> _repo;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiver"></param>
/// <param name="mapper"></param>
public ReadEnvelopeReceiverQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiver, IMapper mapper)
{
_repo = envelopeReceiver;
_mapper = mapper;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<IEnumerable<EnvelopeReceiverDto>> Handle(ReadEnvelopeReceiverQuery request, CancellationToken cancel)
{
var q = _repo.Read();
if(request.Envelope is not null)
{
var env = request.Envelope;
if (env.Id is not null)
q = q.Where(er => er.EnvelopeId == env.Id);
if (env.Status is not null)
{
if(env.Status.Min is not null)
q = q.Where(er => er.Envelope.Status >= env.Status.Min);
if(env.Status.Max is not null)
q = q.Where(er => er.Envelope.Status <= env.Status.Max);
if(env.Status .Include?.Length > 0)
q = q.Where(er => env.Status.Include.Contains(er.Envelope.Status));
if(env.Status.Ignore is not null)
q = q.Where(er => !env.Status.Ignore.Contains(er.Envelope.Status));
}
if (env.Uuid is not null)
q = q.Where(er => er.Envelope.Uuid == env.Uuid);
}
if (request.Receiver is not null)
{
var rcv = request.Receiver;
if (rcv.Id is not null)
q = q.Where(r => r.ReceiverId == rcv.Id);
if (rcv.EmailAddress is not null)
q = q.Where(r => r.Receiver.EmailAddress == rcv.EmailAddress);
if (rcv.Signature is not null)
q = q.Where(er => er.Receiver.Signature == rcv.Signature);
}
var envRcvs = await q.Include(er => er.Envelope).ThenInclude(e => e.Documents).ThenInclude(d => d.Elements)
.Include(er => er.Envelope).ThenInclude(e => e.History)
.Include(er => er.Envelope).ThenInclude(e => e.User)
.Include(er => er.Receiver)
.ToListAsync(cancel);
return _mapper.Map<IEnumerable<EnvelopeReceiverDto>>(envRcvs);
}
}

View File

@@ -0,0 +1,83 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Extensions;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
/// <summary>
///
/// </summary>
public record ReceiverAlreadySignedQuery : IRequest<bool>
{
/// <summary>
///
/// </summary>
public required string Key
{
get => (EnvelopeUuid, ReceiverSignature).EncodeEnvelopeReceiverId();
init
{
(string? EnvelopeUuid, string? ReceiverSignature) = value.DecodeEnvelopeReceiverId();
if (string.IsNullOrEmpty(EnvelopeUuid) || string.IsNullOrEmpty(ReceiverSignature))
{
throw new BadRequestException("Der EnvelopeReceiverKey muss ein gültiger Base64-kodierter String sein, der die EnvelopeUuid und die ReceiverSignature enthält.");
}
}
}
internal string EnvelopeUuid { get; set; } = null!;
internal string ReceiverSignature { get; set; } = null!;
}
/// <summary>
///
/// </summary>
public static class ReceiverAlreadySignedQueryExtensions
{
/// <summary>
///
/// </summary>
/// <param name="mediator"></param>
/// <param name="key"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<bool> ReceiverAlreadySigned(this IMediator mediator, string key, CancellationToken cancel = default)
=> mediator.Send(new ReceiverAlreadySignedQuery { Key = key }, cancel);
}
/// <summary>
///
/// </summary>
public class ReceiverAlreadySignedQueryHandler : IRequestHandler<ReceiverAlreadySignedQuery, bool>
{
private readonly IRepository<EnvelopeReceiver> _repo;
/// <summary>
///
/// </summary>
/// <param name="repo"></param>
public ReceiverAlreadySignedQueryHandler(IRepository<EnvelopeReceiver> repo)
{
_repo = repo;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<bool> Handle(ReceiverAlreadySignedQuery request, CancellationToken cancel = default)
{
return await _repo.Read()
.Where(er => er.Envelope.Uuid == request.EnvelopeUuid)
.Where(er => er.Receiver.Signature == request.ReceiverSignature)
.Where(er => er.Envelope.History.Any(hist => hist.Status == Constants.EnvelopeStatus.DocumentSigned))
.AnyAsync(cancel);
}
}

View File

@@ -1,4 +1,6 @@
using MediatR; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Application.Envelopes.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@@ -15,7 +17,7 @@ public record CreateEnvelopeCommand(
[Required] string Title, [Required] string Title,
[Required] string Message, [Required] string Message,
bool TFAEnabled = false bool TFAEnabled = false
) : IRequest<CreateEnvelopeResponse?> ) : IRequest<EnvelopeDto?>
{ {
/// <summary> /// <summary>
/// Id of receiver /// Id of receiver

View File

@@ -1,5 +1,6 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor; using EnvelopeGenerator.Application.Interfaces.SQLExecutor;
using EnvelopeGenerator.Application.Dto;
using MediatR; using MediatR;
namespace EnvelopeGenerator.Application.Envelopes.Commands; namespace EnvelopeGenerator.Application.Envelopes.Commands;
@@ -7,7 +8,7 @@ namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?> public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, EnvelopeDto?>
{ {
private readonly IEnvelopeExecutor _envelopeExecutor; private readonly IEnvelopeExecutor _envelopeExecutor;
@@ -30,12 +31,12 @@ public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeComman
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
public async Task<CreateEnvelopeResponse?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken) public async Task<EnvelopeDto?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken)
{ {
int userId = request.UserId ?? throw new InvalidOperationException("UserId cannot be null when creating an envelope."); 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); var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancellationToken);
return _mapper.Map<CreateEnvelopeResponse>(envelope); return _mapper.Map<EnvelopeDto>(envelope);
} }
} }

View File

@@ -1,19 +0,0 @@
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>();
}
}

View File

@@ -1,20 +0,0 @@
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);

View File

@@ -1,16 +0,0 @@
using MediatR;
namespace EnvelopeGenerator.Application.Envelopes;
/// <summary>
/// Repräsentiert eine Abfrage für Umschläge.
/// </summary>
/// <param name="Id">Die eindeutige Kennung des Umschlags.</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? Status = null,
string? Uuid = null) : IRequest
{
};

View File

@@ -0,0 +1,19 @@
using AutoMapper;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Envelopes;
/// <summary>
///
/// </summary>
public class MappingProfile : Profile
{
/// <summary>
///
/// </summary>
public MappingProfile()
{
CreateMap<Envelope, CreateEnvelopeReceiverResponse>();
}
}

View File

@@ -1,8 +0,0 @@
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
/// <summary>
/// Stellt eine Abfrage zum Lesen von Briefumschlägen dar.
/// </summary>
public record ReadEnvelopeQuery : EnvelopeQuery
{
}

View File

@@ -1,36 +0,0 @@
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
/// <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();
}

View File

@@ -1,16 +1,32 @@
using EnvelopeGenerator.Application.Histories; using MediatR;
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.EnvelopeReceivers; namespace EnvelopeGenerator.Application.Envelopes.Queries;
/// <summary> /// <summary>
/// Stellt eine Abfrage für einen Envelope-Empfänger dar. /// Repräsentiert eine Abfrage für Umschläge.
/// </summary> /// </summary>
/// <param name="Status">Der Status der Abfrage, optional.</param> public class ReadEnvelopeQuery : IRequest
public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null); {
/// <summary>
/// Die eindeutige Kennung des Umschlags.
/// </summary>
public int? Id { get; init; }
/// <summary>
/// Die universell eindeutige Kennung des Umschlags.
/// </summary>
public string? Uuid { get; init; }
/// <summary>
/// Abfrage des Include des Umschlags
/// </summary>
public EnvelopeStatus? Status { get; init; }
}
/// <summary> /// <summary>
/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Common.Constants.EnvelopeStatus"/> /// Repräsentiert den Include eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Constants.EnvelopeStatus"/>
/// Invalid (0): Ungültiger Status. /// Invalid (0): Ungültiger Include.
/// EnvelopeCreated (1001): Der Umschlag wurde erstellt. /// EnvelopeCreated (1001): Der Umschlag wurde erstellt.
/// EnvelopeSaved (1002): Der Umschlag wurde gespeichert. /// EnvelopeSaved (1002): Der Umschlag wurde gespeichert.
/// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant. /// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant.
@@ -35,13 +51,26 @@ public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null);
/// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet. /// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet.
/// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet. /// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet.
/// MessageCompletionSent (3005): Abschlussbenachrichtigung 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> /// </summary>
public record EnvelopeStatusQuery( public record EnvelopeStatus
int? Min = null,
int? Max = null,
int[]? Ignore = null)
{ {
/// <summary>
/// Der minimale Statuswert, der berücksichtigt werden.
/// </summary>
public Constants.EnvelopeStatus? Min { get; init; }
/// <summary>
/// Der maximale Statuswert, der berücksichtigt werden.
/// </summary>
public Constants.EnvelopeStatus? Max { get; init; }
/// <summary>
/// Eine Liste von Statuswerten, die einbezogen werden.
/// </summary>
public Constants.EnvelopeStatus[]? Include { get; init; }
/// <summary>
/// Eine Liste von Statuswerten, die ignoriert werden werden.
/// </summary>
public Constants.EnvelopeStatus[]? Ignore { get; init; }
} }

View File

@@ -1,6 +1,6 @@
using EnvelopeGenerator.Application.Receivers.Queries.Read; using EnvelopeGenerator.Application.Receivers.Queries;
namespace EnvelopeGenerator.Application.Envelopes.Queries.ReceiverName; namespace EnvelopeGenerator.Application.Envelopes.Queries;
/// <summary> /// <summary>
/// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln, /// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln,

View File

@@ -1,4 +1,4 @@
using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Dto.Messaging;
namespace EnvelopeGenerator.Application.Extensions; namespace EnvelopeGenerator.Application.Extensions;

View File

@@ -0,0 +1,53 @@
using EnvelopeGenerator.Application.Exceptions;
namespace EnvelopeGenerator.Application.Extensions;
/// <summary>
/// Extension methods for tasks
/// </summary>
public static class TaskExtensions
{
/// <summary>
/// Awaits the specified task and ensures that the result is not <c>null</c>.
/// If the result is <c>null</c>, a <see cref="NotFoundException"/> is thrown.
/// </summary>
/// <typeparam name="T">The type of the result.</typeparam>
/// <param name="task">The task to await.</param>
/// <param name="exceptionMessage">Optional custom exception message.</param>
/// <returns>The awaited result if not <c>null</c>.</returns>
/// <exception cref="NotFoundException">Thrown if the result is <c>null</c>.</exception>
public static async Task<T> ThrowIfNull<T>(this Task<T?> task, string? exceptionMessage = null)
{
var result = await task;
return result ?? throw new NotFoundException(exceptionMessage);
}
/// <summary>
/// Awaits the specified task and ensures that the result is not <c>empty</c>.
/// If the result contains no elements, a <see cref="NotFoundException"/> is thrown.
/// </summary>
/// <typeparam name="T">The element type of the collection.</typeparam>
/// <param name="task">The task to await.</param>
/// <param name="exceptionMessage">Optional custom exception message.</param>
/// <returns>The awaited collection if it is not <c>null</c> or empty.</returns>
/// <exception cref="NotFoundException">Thrown if the result is <c>null</c> or empty.</exception>
public static async Task<IEnumerable<T>> ThrowIfNull<T>(this Task<IEnumerable<T>> task, string? exceptionMessage = null)
{
var result = await task;
return result?.Any() ?? false ? result : throw new NotFoundException(exceptionMessage);
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="I"></typeparam>
/// <param name="task"></param>
/// <param name="act"></param>
/// <returns></returns>
public static async Task<I> Then<T, I>(this Task<T> task, Func<T, I> act)
{
var res = await task;
return act(res);
}
}

View File

@@ -1,17 +1,18 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.Histories.Queries.Read;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Histories.Queries.Read; namespace EnvelopeGenerator.Application.Histories;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ReadHistoryMappingProfile: Profile public class MappingProfile: Profile
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ReadHistoryMappingProfile() public MappingProfile()
{ {
CreateMap<EnvelopeHistory, ReadHistoryResponse>(); CreateMap<EnvelopeHistory, ReadHistoryResponse>();
} }

View File

@@ -9,8 +9,8 @@ namespace EnvelopeGenerator.Application.Histories.Queries.Read;
/// Repräsentiert eine Abfrage für die Verlaufshistorie eines Umschlags. /// Repräsentiert eine Abfrage für die Verlaufshistorie eines Umschlags.
/// </summary> /// </summary>
/// <param name="EnvelopeId">Die eindeutige Kennung des Umschlags.</param> /// <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="Status">Der Include 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> /// <param name="OnlyLast">Abfrage zur Steuerung, ob nur der aktuelle Include oder der gesamte Datensatz zurückgegeben wird.</param>
public record ReadHistoryQuery( public record ReadHistoryQuery(
[Required] [Required]
int EnvelopeId, int EnvelopeId,

View File

@@ -1,5 +1,5 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.Contracts.Repositories; using EnvelopeGenerator.Application.Interfaces.Repositories;
using EnvelopeGenerator.Application.Exceptions; using EnvelopeGenerator.Application.Exceptions;
using MediatR; using MediatR;

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -2,7 +2,7 @@
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants; using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -2,7 +2,7 @@
using EnvelopeGenerator.Domain; using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,8 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///
@@ -83,7 +84,7 @@ public interface IEnvelopeReceiverRepository : ICRUDRepository<EnvelopeReceiver,
/// <param name="max_status"></param> /// <param name="max_status"></param>
/// <param name="ignore_statuses"></param> /// <param name="ignore_statuses"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<EnvelopeReceiver>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); Task<IEnumerable<EnvelopeReceiver>> ReadByUsernameAsync(string username, Constants.EnvelopeStatus? min_status = null, Constants.EnvelopeStatus? max_status = null, params Constants.EnvelopeStatus[] ignore_statuses);
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,8 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///
@@ -38,5 +39,5 @@ public interface IEnvelopeRepository : ICRUDRepository<Envelope, int>
/// <param name="max_status"></param> /// <param name="max_status"></param>
/// <param name="ignore_statuses"></param> /// <param name="ignore_statuses"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<Envelope>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses); Task<IEnumerable<Envelope>> ReadByUserAsync(int userId, Constants.EnvelopeStatus? min_status = null, Constants.EnvelopeStatus? max_status = null, params Constants.EnvelopeStatus[] ignore_statuses);
} }

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories; namespace EnvelopeGenerator.Application.Interfaces.Repositories;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using Dapper; using Dapper;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// ///

View File

@@ -1,4 +1,4 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// Provides methods for executing common queries on a given entity type. /// Provides methods for executing common queries on a given entity type.

View File

@@ -1,4 +1,4 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// Represents a raw SQL query contract. /// Represents a raw SQL query contract.

View File

@@ -1,4 +1,4 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// Defines methods for executing raw SQL queries or custom SQL query classes and returning query executors for further operations. /// Defines methods for executing raw SQL queries or custom SQL query classes and returning query executors for further operations.

View File

@@ -1,6 +1,6 @@
using Dapper; using Dapper;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; namespace EnvelopeGenerator.Application.Interfaces.SQLExecutor;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using OtpNet; using OtpNet;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,9 +1,9 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,8 +1,8 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,10 +1,10 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants; using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,8 +1,8 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,11 +1,11 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Application.Dto.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants; using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,10 +1,10 @@
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain; using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,8 +1,8 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,13 +1,15 @@
using CommandDotNet; using CommandDotNet;
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Dto.Messaging;
using EnvelopeGenerator.Application.Envelopes; using EnvelopeGenerator.Application.Envelopes;
using EnvelopeGenerator.Application.Receivers.Queries.Read; using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Receivers.Queries;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///
@@ -120,7 +122,7 @@ public interface IEnvelopeReceiverService : IBasicCRUDService<EnvelopeReceiverDt
/// <param name="receiverQuery"></param> /// <param name="receiverQuery"></param>
/// <param name="ignore_statuses"></param> /// <param name="ignore_statuses"></param>
/// <returns></returns> /// <returns></returns>
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<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, Constants.EnvelopeStatus? min_status = null, Constants.EnvelopeStatus? max_status = null, ReadEnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params Constants.EnvelopeStatus[] ignore_statuses);
/// <summary> /// <summary>
/// ///

View File

@@ -1,9 +1,10 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///
@@ -40,5 +41,5 @@ public interface IEnvelopeService : IBasicCRUDService<EnvelopeDto, Envelope, int
/// <param name="max_status"></param> /// <param name="max_status"></param>
/// <param name="ignore_statuses"></param> /// <param name="ignore_statuses"></param>
/// <returns></returns> /// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeDto>>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses); Task<DataResult<IEnumerable<EnvelopeDto>>> ReadByUserAsync(int userId, Constants.EnvelopeStatus? min_status = null, Constants.EnvelopeStatus? max_status = null, params Constants.EnvelopeStatus[] ignore_statuses);
} }

View File

@@ -1,7 +1,7 @@
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Dto.Messaging;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,8 +1,8 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,9 +1,9 @@
using DigitalData.Core.Abstraction.Application; using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO; using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
/// <summary> /// <summary>
/// ///

View File

@@ -1,6 +1,6 @@
using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Dto.Messaging;
namespace EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Interfaces.Services;
//TODO: move to DigitalData.Core //TODO: move to DigitalData.Core
/// <summary> /// <summary>

View File

@@ -1,77 +0,0 @@
namespace EnvelopeGenerator.Application;
/// <summary>
///
/// </summary>
public static class Key
{
/// <summary>
///
/// </summary>
public static readonly string InnerServiceError = nameof(InnerServiceError);
/// <summary>
///
/// </summary>
public static readonly string EnvelopeNotFound = nameof(EnvelopeNotFound);
/// <summary>
///
/// </summary>
public static readonly string EnvelopeReceiverNotFound = nameof(EnvelopeReceiverNotFound);
/// <summary>
///
/// </summary>
public static readonly string AccessCodeNull = nameof(AccessCodeNull);
/// <summary>
///
/// </summary>
public static readonly string WrongAccessCode = nameof(WrongAccessCode);
/// <summary>
///
/// </summary>
public static readonly string DataIntegrityIssue = nameof(DataIntegrityIssue);
/// <summary>
///
/// </summary>
public static readonly string SecurityBreachOrDataIntegrity = nameof(SecurityBreachOrDataIntegrity);
/// <summary>
///
/// </summary>
public static readonly string PossibleDataIntegrityIssue = nameof(PossibleDataIntegrityIssue);
/// <summary>
///
/// </summary>
public static readonly string SecurityBreach = nameof(SecurityBreach);
/// <summary>
///
/// </summary>
public static readonly string PossibleSecurityBreach = nameof(PossibleSecurityBreach);
/// <summary>
///
/// </summary>
public static readonly string WrongEnvelopeReceiverId = nameof(WrongEnvelopeReceiverId);
/// <summary>
///
/// </summary>
public static readonly string EnvelopeOrReceiverNonexists = nameof(EnvelopeOrReceiverNonexists);
/// <summary>
///
/// </summary>
public static readonly string PhoneNumberNonexists = nameof(PhoneNumberNonexists);
/// <summary>
///
/// </summary>
public static readonly string Default = nameof(Default);
}

View File

@@ -1,10 +0,0 @@
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
{
}

Some files were not shown because too many files have changed in this diff Show More