Compare commits

...

159 Commits

Author SHA1 Message Date
3616d43f2e fix(EGDbContext): remove principal key mapping on DocumentStatus.Receiver 2025-08-27 15:24:26 +02:00
d5443b223c fix(EGDbContext); remove Uuid from principal key 2025-08-27 15:12:09 +02:00
c456cb0301 refactor(CreateHistoryCommand); update to use EnvelopeReceiverQueryBase and related extension methods 2025-08-27 14:41:20 +02:00
1c0c23aca4 remove url encoder injection 2025-08-27 11:42:33 +02:00
05d7ac7864 refactor(ReadEnvelopeReceiverQueryHandler): update to use extension method and move to related query class 2025-08-27 11:39:03 +02:00
95e793b081 update read envelope, receiver and envelope-receiver queries to inhered from query-bases 2025-08-27 11:04:30 +02:00
dfa1667939 refactor(ReadDocumentQuery): update to add CancellationToken 2025-08-27 10:50:51 +02:00
Developer 02
8a4d3ff6f9 refactor(SaveDocStatusCommand): simplify repository filtering in SaveDocStatusCommandHandler
- Replaced explicit envelope and receiver expression filters with a single `.Where(request)` call.
- Removed redundant checks for null and empty values in handler.
- Updated using statements to include `EnvelopeGenerator.Application.Extensions`.
- Maintains the same functionality while reducing code complexity.
2025-08-26 22:34:54 +02:00
Developer 02
783d91a658 feat(QueryExtensions): add combined EnvelopeReceiver query support in QueryExtensions 2025-08-26 22:32:34 +02:00
Developer 02
ad032b2bdf fix(QueryExtensions): update to use base classes instead of interfaces 2025-08-26 22:23:26 +02:00
Developer 02
f2876d8995 move model intterfaces to interfaces dir 2025-08-26 22:09:45 +02:00
Developer 02
5468d7b2aa feat: add QueryExtensions for filtering by Envelope and Receiver
- Introduced extension methods on IQueryable<TEntity> to filter entities
  by Envelope (Id or Uuid) and Receiver (Id, EmailAddress, or Signature).
- Throws BadRequestException if no valid identifier is provided when notnull = true.
- Improves query handling consistency across application layer.
2025-08-26 22:05:33 +02:00
Developer 02
b005c194d3 create and implement IHasEnvelopeQuery and IHasReceiverQuery 2025-08-26 19:43:55 +02:00
Developer 02
dee6608390 add and implement IHasEnvelope and IHasReceiver 2025-08-26 19:20:44 +02:00
Developer 02
8b53eae6da init QueryExtensions 2025-08-26 18:51:57 +02:00
Developer 02
405b619bdc refactor(ReceiverAlreadySignedQuery): update to use common models 2025-08-26 17:29:07 +02:00
Developer 02
c5918b8e49 refactor(CreateHistoryCommand): update to use EnvelopeQuery- and ReceiverQueryBase 2025-08-26 17:16:30 +02:00
Developer 02
05cd8a05f4 refactor(MappingProfile): create to handle model mappings 2025-08-26 17:13:21 +02:00
Developer 02
2355a566e4 refactor(EnvelopeReceiverQueryBase): simplify EnvelopeReceiverQueryBase.Key handling
- Introduced private backing field `_key` for Key property
- Removed dynamic recomputation from Envelope and Receiver
- Ensured Key is only set once during initialization
- Improved null handling and exception safety
2025-08-26 16:49:22 +02:00
Developer 02
c887f857cd fix(EnvelopeReceiverQueryBase): make Envelope and Receiver properties not null and set default value 2025-08-26 16:39:12 +02:00
Developer 02
f114144d34 Fügen das Suffix „-base“ am Ende gängiger Modelle hinzu. 2025-08-26 16:36:52 +02:00
Developer 02
5c09601e3f refactor(ModifyDocStatusCommandBase): update to use EnvelopeReceiverQuery 2025-08-26 16:33:56 +02:00
Developer 02
18b05a3c63 refactor(ReceiverQuery): make properties virtual 2025-08-26 16:26:52 +02:00
Developer 02
ce35b0fea1 refactor(EnvelopeQuery): make properties virtual 2025-08-26 16:26:11 +02:00
Developer 02
7f18cd64c5 feat(EnvelopeReceiverQuery): create query with Key, Envelope and Receiver properties 2025-08-26 16:25:37 +02:00
Developer 02
0083c1b6c1 Create common Envelope and Receiver queries 2025-08-26 14:34:52 +02:00
59e73dbcf0 refactor(CreateHistoryCommand): add Envelope and Receiver queries 2025-08-26 10:36:46 +02:00
f34770931f feat(CreateHistoryCommand): add CreateHistoryCommandHandler with repository integration
- Extend CreateHistoryCommand to implement IRequest<long?>
- Introduce CreateHistoryCommandHandler to handle command via IRepository<EnvelopeHistory>
- Implement async creation and verification of EnvelopeHistory records
2025-08-25 17:33:49 +02:00
78100ef24f create CreateHistoryCommand 2025-08-25 17:22:26 +02:00
99083a68aa move mapping profile to pre dir 2025-08-25 16:50:42 +02:00
0939e57c56 refactor(EnvelopeController): migrate envelope update to MediatR with annotations
- Renamed `Update` action to `CreateOrUpdate`.
- Replaced manual signing logic with `_mediator.SignDocAsync`.
- Added `ExpandoObject` parameter to handle document annotations.
- Improved authorization checks and logging for missing claims.
- Kept legacy `Reject` endpoint intact with obsolete services.
2025-08-25 16:40:46 +02:00
00bdfeb9bb refactor(query): restructure ReceiverAlreadySignedQuery for clarity
- Replaced internal string properties with EnvelopeQuery and ReceiverQuery records
- Updated Key property to encode/decode using the new structured types
- Added overloaded IMediator extension methods IsSignedAsync for better usability
- Simplified ReceiverAlreadySignedQueryHandler to work with the new structure
2025-08-25 16:27:37 +02:00
cced0e5579 refator(SaveDocStatusCommandHandler): use SingleOrDefaultAsync instead of FirstOrDefaultAsync 2025-08-25 15:56:37 +02:00
82150290d2 refactor(Extensions): update SaveDocStatusAsync to use uuid and signature 2025-08-25 15:55:37 +02:00
fb7fd47a2a feat(SaveDocStatusCommand): add IMediator extension methods for saving and signing document status
- Introduced `SaveDocStatusAsync` extension method on IMediator to simplify saving document status
- Added `SignDocAsync` extension method as a shortcut for signing document status
- Refactored `SaveDocStatusCommand` usage to support new mediator extension
2025-08-25 15:43:54 +02:00
20b6b328f5 feat(EGDbContext): Eindeutige Indizes und Beziehungen für die Entitäten „Envelope“, „Receiver“ und „DocumentStatus“ hinzufügen
- Eindeutiger Index für „Envelope.Uuid“ hinzugefügt
- Eindeutige Indizes für „Receiver.Signature“ und „Receiver.EmailAddress“ hinzugefügt
- Beziehungen von „DocumentStatus“ zu „Envelope.Uuid“ und „Receiver“ (Signature und EmailAddress) konfiguriert
- Entitätsbeschränkungen für die Datenintegrität verbessert
2025-08-25 15:32:48 +02:00
fb07d9151f add mapping profiles 2025-08-25 15:20:29 +02:00
a3bc26bd08 feat(SaveDocStatusCommand): enhance SaveDocStatusCommandHandler with flexible envelope & receiver filters
- Added support for filtering by Envelope.Id or Envelope.Uuid
- Added support for filtering by Receiver.Id, Receiver.EmailAddress, or Receiver.Signature
- Throw BadRequestException when required identifiers are missing
- Updated repository queries to combine envelope and receiver filters
2025-08-25 15:02:57 +02:00
e1f793e571 refactor(TaskExtensions): TaskExtensions verallgemeinern, um benutzerdefinierte Ausnahmegeneratoren zu unterstützen
- Feste NotFoundException durch generischen Ausnahmegenerator in ThrowIfNull-Methoden ersetzt.
- Neue Exceptions-Hilfsklasse für die Erstellung gängiger Ausnahmen (NotFound, BadRequest, Forbidden) hinzugefügt.
- Funktionalität der Then-Erweiterungsmethode unverändert beibehalten.
2025-08-25 12:41:27 +02:00
86d8fcda07 chore: update to use DigitalData.Core.Exceptions instead of project exceptions classes 2025-08-25 11:48:29 +02:00
2f8401073f feat(SaveDocStatusCommand): Füge SaveDocStatusCommand und Handler hinzu, um den Dokumentstatus zu erstellen oder zu aktualisieren. 2025-08-25 11:41:08 +02:00
85a855fe64 refactor(ModifyDocStatusCommandBase): remove ChangedWhen-property 2025-08-25 11:18:48 +02:00
996b544633 feat(ModifyDocStatusCommandBase): create abstract class to handle common properties of commands 2025-08-25 11:16:57 +02:00
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
266 changed files with 7168 additions and 2535 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,12 @@
namespace EnvelopeGenerator.Application.DocStatus.Commands;
/// <summary>
///
/// </summary>
public record CreateDocStatusCommand : ModifyDocStatusCommandBase
{
/// <summary>
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
/// </summary>
public DateTime AddedWhen => StatusChangedWhen;
}

View File

@@ -0,0 +1,39 @@
using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.DocStatus.Commands;
/// <summary>
///
/// </summary>
public record ModifyDocStatusCommandBase : EnvelopeReceiverQueryBase
{
/// <summary>
/// Gets the current status code.
/// </summary>
public Constants.DocumentStatus Status => Value is null ? Constants.DocumentStatus.Created : Constants.DocumentStatus.Signed;
/// <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.
/// </summary>
public DateTime StatusChangedWhen { get; } = DateTime.Now;
/// <summary>
/// Maps the current command to a new instance of the specified type.
/// </summary>
/// <typeparam name="TDest"></typeparam>
/// <returns></returns>
public TDest To<TDest>() where TDest : ModifyDocStatusCommandBase, new()
=> new()
{
Key = Key,
Envelope = Envelope,
Receiver = Receiver,
Value = Value
};
}

View File

@@ -0,0 +1,79 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
using EnvelopeGenerator.Application.Extensions;
namespace EnvelopeGenerator.Application.DocStatus.Commands;
/// <summary>
/// Represents a command to save the status of a document, either by creating a new status or updating an existing one based on the provided envelope and receiver identifiers.
/// It returns the identifier of the saved document status.
/// </summary>
public record SaveDocStatusCommand : ModifyDocStatusCommandBase, IRequest<int?>;
/// <summary>
///
/// </summary>
public static class Extensions
{
/// <summary>
///
/// </summary>
/// <param name="mediator"></param>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="value"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<int?> SignDocAsync(this IMediator mediator, string uuid, string signature, string value, CancellationToken cancel = default)
=> mediator.Send(new SaveDocStatusCommand()
{
Envelope = new() { Uuid = uuid },
Receiver = new() { Signature = signature },
Value = value
}, cancel);
}
/// <summary>
///
/// </summary>
public class SaveDocStatusCommandHandler : IRequestHandler<SaveDocStatusCommand, int?>
{
private readonly IRepository<DocumentStatus> _repo;
/// <summary>
///
/// </summary>
/// <param name="repo"></param>
public SaveDocStatusCommandHandler(IRepository<DocumentStatus> repo)
{
_repo = repo;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<int?> Handle(SaveDocStatusCommand request, CancellationToken cancel)
{
// ceck if exists
bool isExists = await _repo.ReadOnly().Where(request).AnyAsync(cancel);
if (isExists)
{
var uReq = request.To<UpdateDocStatusCommand>();
await _repo.UpdateAsync(uReq, q => q.Where(request), cancel);
}
else
{
var cReq = request.To<CreateDocStatusCommand>();
await _repo.CreateAsync(cReq, cancel);
}
var docStatus = await _repo.ReadOnly().Where(request).SingleOrDefaultAsync(cancel);
return docStatus?.Id;
}
}

View File

@@ -0,0 +1,14 @@
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.DocStatus.Commands;
/// <summary>
///
/// </summary>
public record UpdateDocStatusCommand : ModifyDocStatusCommandBase
{
/// <summary>
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
/// </summary>
public DateTime? ChangedWhen => StatusChangedWhen;
}

View File

@@ -0,0 +1,20 @@
using AutoMapper;
using EnvelopeGenerator.Application.DocStatus.Commands;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.DocStatus;
/// <summary>
///
/// </summary>
public class MappingProfile : Profile
{
/// <summary>
///
/// </summary>
public MappingProfile()
{
CreateMap<CreateDocStatusCommand, DocumentStatus>();
CreateMap<UpdateDocStatusCommand, DocumentStatus>();
}
}

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,48 +1,69 @@
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) /// <param name="mapper"></param>
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="cancel">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")] public async Task<EnvelopeDocumentDto?> Handle(ReadDocumentQuery query, CancellationToken cancel)
public async Task<ReadDocumentResponse?> 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(cancel);
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(cancel);
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.Exceptions; using EnvelopeGenerator.Application.Dto;
using DigitalData.Core.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;
@@ -13,14 +15,17 @@ namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemplateCommand> public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemplateCommand>
{ {
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,29 @@
<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.2.1" />
<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.Core.Exceptions" Version="1.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,126 @@
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Application.Receivers.Queries;
using MediatR;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
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 : EnvelopeReceiverQueryBase<ReadEnvelopeQuery, ReadReceiverQuery>, IRequest<IEnumerable<EnvelopeReceiverDto>>;
/// <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());
}
}
/// <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="BadRequestException"></exception>
public async Task<IEnumerable<EnvelopeReceiverDto>> Handle(ReadEnvelopeReceiverQuery request, CancellationToken cancel)
{
var q = _repo.Read().Where(request, notnull: false);
if (request.Envelope.Status is not null)
{
var status = request.Envelope.Status;
if (status.Min is not null)
q = q.Where(er => er.Envelope!.Status >= status.Min);
if (status.Max is not null)
q = q.Where(er => er.Envelope!.Status <= status.Max);
if (status.Include?.Length > 0)
q = q.Where(er => status.Include.Contains(er.Envelope!.Status));
if (status.Ignore is not null)
q = q.Where(er => !status.Ignore.Contains(er.Envelope!.Status));
}
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,78 @@
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Model;
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 : EnvelopeReceiverQueryBase, IRequest<bool>;
/// <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> IsSignedAsync(this IMediator mediator, string key, CancellationToken cancel = default)
=> mediator.Send(new ReceiverAlreadySignedQuery { Key = key }, cancel);
/// <summary>
///
/// </summary>
/// <param name="mediator"></param>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<bool> IsSignedAsync(this IMediator mediator, string uuid, string signature, CancellationToken cancel = default)
=> mediator.Send(new ReceiverAlreadySignedQuery
{
Envelope = new() { Uuid = uuid },
Receiver = new() { Signature = signature }
}, 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.Envelope.Uuid)
.Where(er => er.Receiver.Signature == request.Receiver.Signature)
.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
@@ -23,4 +25,4 @@ public record CreateEnvelopeCommand(
[JsonIgnore] [JsonIgnore]
[BindNever] [BindNever]
public int? UserId { get; set; } public int? UserId { get; set; }
}; };

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,23 @@
using EnvelopeGenerator.Application.Histories; using MediatR;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Application.Model;
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 record ReadEnvelopeQuery : EnvelopeQueryBase, IRequest
public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null); {
/// <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 +42,27 @@ 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(
int? Min = null, public record EnvelopeStatus
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,22 +0,0 @@
namespace EnvelopeGenerator.Application.Exceptions;
/// <summary>
/// Represents an exception that is thrown when a bad request is encountered.
/// </summary>
public class BadRequestException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="BadRequestException"/> class.
/// </summary>
public BadRequestException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BadRequestException"/> class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public BadRequestException(string? message) : base(message)
{
}
}

View File

@@ -1,22 +0,0 @@
namespace EnvelopeGenerator.Application.Exceptions;
/// <summary>
/// Represents an exception that is thrown when a requested resource is not found.
/// </summary>
public class NotFoundException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="NotFoundException"/> class.
/// </summary>
public NotFoundException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="NotFoundException"/> class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public NotFoundException(string? message) : base(message)
{
}
}

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,77 @@
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Domain.Interfaces;
namespace EnvelopeGenerator.Application.Extensions;
/// <summary>
///
/// </summary>
public static class QueryExtensions
{
/// <summary>
///
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="root"></param>
/// <param name="query"></param>
/// <param name="notnull"></param>
/// <returns></returns>
/// <exception cref="BadRequestException"></exception>
public static IQueryable<TEntity> Where<TEntity>(this IQueryable<TEntity> root, EnvelopeQueryBase query, bool notnull = true)
where TEntity : IHasEnvelope
{
if (query.Id is not null)
root = root.Where(e => e.Envelope!.Id == query.Id);
else if (query.Uuid is not null)
root = root.Where(e => e.Envelope!.Uuid == query.Uuid);
else if (notnull)
throw new BadRequestException(
"Either Envelope Id or Envelope Uuid must be provided in the query."
);
return root;
}
/// <summary>
///
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="root"></param>
/// <param name="query"></param>
/// <param name="notnull"></param>
/// <returns></returns>
/// <exception cref="BadRequestException"></exception>
public static IQueryable<TEntity> Where<TEntity>(this IQueryable<TEntity> root, ReceiverQueryBase query, bool notnull = true)
where TEntity : IHasReceiver
{
if (query.Id is not null)
root = root.Where(e => e.Receiver!.Id == query.Id);
else if (query.EmailAddress is not null)
root = root.Where(e => e.Receiver!.EmailAddress == query.EmailAddress);
else if (query.Signature is not null)
root = root.Where(e => e.Receiver!.Signature == query.Signature);
else if (notnull)
throw new BadRequestException(
"Receiver must have at least one identifier (Id, EmailAddress, or Signature)."
);
return root;
}
/// <summary>
///
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TEnvelopeQuery"></typeparam>
/// <typeparam name="TReceiverQuery"></typeparam>
/// <param name="root"></param>
/// <param name="query"></param>
/// <param name="notnull"></param>
/// <returns></returns>
public static IQueryable<TEntity> Where<TEntity, TEnvelopeQuery, TReceiverQuery>(this IQueryable<TEntity> root, EnvelopeReceiverQueryBase<TEnvelopeQuery, TReceiverQuery> query, bool notnull = true)
where TEntity : IHasEnvelope, IHasReceiver
where TEnvelopeQuery : EnvelopeQueryBase, new()
where TReceiverQuery : ReceiverQueryBase, new()
=> root.Where(query.Envelope, notnull).Where(query.Receiver, notnull);
}

View File

@@ -0,0 +1,78 @@
using DigitalData.Core.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>, the exception created by factory-method is thrown.
/// </summary>
/// <typeparam name="T">The type of the result.</typeparam>
/// <typeparam name="TException">The type of the exception.</typeparam>
/// <param name="task">The task to await.</param>
/// <param name="factory">Exception provider</param>
/// <returns>The awaited result if not <c>null</c>.</returns>
/// <exception>Thrown if the result is <c>null</c>.</exception>
public static async Task<T> ThrowIfNull<T, TException>(this Task<T?> task, Func<TException> factory) where TException : Exception
{
var result = await task;
return result ?? throw factory();
}
/// <summary>
/// Awaits the specified task and ensures that the result is not <c>empty</c>.
/// If the result contains no elements, the exception created by factory-method is thrown.
/// </summary>
/// <typeparam name="T">The element type of the collection.</typeparam>
/// <typeparam name="TException">The type of the exception.</typeparam>
/// <param name="task">The task to await.</param>
/// <param name="factory">Exception provider</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, TException>(this Task<IEnumerable<T>> task, Func<TException> factory) where TException : Exception
{
var result = await task;
return result?.Any() ?? false ? result : throw factory();
}
/// <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);
}
}
/// <summary>
///
/// </summary>
public static class Exceptions
{
/// <summary>
///
/// </summary>
public static NotFoundException NotFound() => new();
/// <summary>
///
/// </summary>
/// <returns></returns>
public static BadRequestException BadRequest() => new();
/// <summary>
///
/// </summary>
/// <returns></returns>
public static ForbiddenException Forbidden() => new();
}

View File

@@ -0,0 +1,91 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
using EnvelopeGenerator.Application.Extensions;
namespace EnvelopeGenerator.Application.Histories.Commands;
/// <summary>
///
/// </summary>
public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<long?>
{
/// <summary>
///
/// </summary>
public int? EnvelopeId { get; set; }
/// <summary>
///
/// </summary>
public string? UserReference { get; set; }
/// <summary>
///
/// </summary>
public Constants.EnvelopeStatus Status { get; set; }
/// <summary>
///
/// </summary>
public DateTime AddedWhen { get; } = DateTime.Now;
/// <summary>
///
/// </summary>
public DateTime ActionDate => AddedWhen;
/// <summary>
///
/// </summary>
public string? Comment { get; set; }
}
/// <summary>
///
/// </summary>
public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand, long?>
{
private readonly IRepository<EnvelopeHistory> _repo;
/// <summary>
///
/// </summary>
/// <param name="repo"></param>
public CreateHistoryCommandHandler(IRepository<EnvelopeHistory> repo)
{
_repo = repo;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<long?> Handle(CreateHistoryCommand request, CancellationToken cancel)
{
// create entitiy
await _repo.CreateAsync(request, cancel);
// check if created
var query = _repo.ReadOnly();
query = request.EnvelopeId is null
? query.Where(request.Envelope)
: query.Where(h => h.EnvelopeId == request.EnvelopeId);
query = request.UserReference is null
? query.Where(request.Receiver)
: query.Where(h => h.UserReference == request.UserReference);
var record = await query
.Where(h => h.ActionDate == request.ActionDate)
.SingleOrDefaultAsync(cancel);
return record?.Id;
}
}

View File

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

View File

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

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,6 +1,6 @@
using AutoMapper; using AutoMapper;
using EnvelopeGenerator.Application.Contracts.Repositories; using EnvelopeGenerator.Application.Interfaces.Repositories;
using EnvelopeGenerator.Application.Exceptions; using DigitalData.Core.Exceptions;
using MediatR; using MediatR;
namespace EnvelopeGenerator.Application.Histories.Queries.Read; namespace EnvelopeGenerator.Application.Histories.Queries.Read;

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>
/// ///

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