Compare commits

...

34 Commits

Author SHA1 Message Date
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
136 changed files with 954 additions and 961 deletions

View File

@@ -1,6 +1,6 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,6 +1,6 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants;

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.EnvelopeHistory;
using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants;

View File

@@ -1,7 +1,7 @@
using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,10 +1,11 @@
using CommandDotNet;
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.Messaging;
using EnvelopeGenerator.Application.Envelopes;
using EnvelopeGenerator.Application.Receivers.Queries.Read;
using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Receivers.Queries;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
@@ -120,7 +121,7 @@ public interface IEnvelopeReceiverService : IBasicCRUDService<EnvelopeReceiverDt
/// <param name="receiverQuery"></param>
/// <param name="ignore_statuses"></param>
/// <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, int? min_status = null, int? max_status = null, ReadEnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params int[] ignore_statuses);
/// <summary>
///

View File

@@ -1,6 +1,6 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,5 +1,5 @@
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.Messaging;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -1,6 +1,6 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;

View File

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

View File

@@ -7,7 +7,7 @@ using DigitalData.Core.Client;
using QRCoder;
using EnvelopeGenerator.Application.Contracts.Services;
using System.Reflection;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
namespace EnvelopeGenerator.Application;

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,13 +1,23 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Dto;
using MediatR;
using EnvelopeGenerator.Domain.Entities;
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>
/// Handles queries for reading <see cref="EnvelopeDocument"/> data based on either the document ID or the envelope ID.
/// </summary>
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, ReadDocumentResponse?>
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, EnvelopeDocumentDto?>
{
/// <summary>
/// Repository for accessing <see cref="EnvelopeDocument"/> entities.
@@ -24,25 +34,25 @@ public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, ReadD
}
/// <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>
/// <param name="query">The query containing the document ID or envelope ID to search for.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>
/// A <see cref="ReadDocumentResponse"/> if a matching document is found; otherwise, <c>null</c>.
/// A <see cref="EnvelopeDocumentDto"/> if a matching document is found; otherwise, <c>null</c>.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown when neither <see cref="ReadDocumentQuery.Id"/> nor <see cref="ReadDocumentQuery.EnvelopeId"/> is provided.
/// </exception>
[Obsolete("Use MediatR")]
public async Task<ReadDocumentResponse?> Handle(ReadDocumentQuery query, CancellationToken cancellationToken)
public async Task<EnvelopeDocumentDto?> Handle(ReadDocumentQuery query, CancellationToken cancellationToken)
{
if (query.Id is not null)
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.Id == query.Id);
return await _repo.ReadOrDefaultAsync<EnvelopeDocumentDto>(d => d.Id == query.Id);
else if (query.EnvelopeId is not null)
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.EnvelopeId == query.EnvelopeId);
return await _repo.ReadOrDefaultAsync<EnvelopeDocumentDto>(d => d.EnvelopeId == query.EnvelopeId);
throw new InvalidOperationException(
$"Invalid {nameof(ReadDocumentQuery)}: either {nameof(query.Id)} or {nameof(query.EnvelopeId)} must be provided.");
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs;
namespace EnvelopeGenerator.Application.Dto;
/// <summary>
/// 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 Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs;
namespace EnvelopeGenerator.Application.Dto;
/// <summary>
///

View File

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

View File

@@ -1,8 +1,8 @@
using DigitalData.UserManager.Application.DTOs.User;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.Receiver;
using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
namespace EnvelopeGenerator.Application.Dto.EnvelopeHistory;
/// <summary>
/// Data Transfer Object representing the history of an envelope, including status, sender, receiver, and related metadata.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,13 +1,13 @@
using AutoMapper;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.EnvelopeHistory;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.Dto.Messaging;
using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.DTOs;
namespace EnvelopeGenerator.Application.Dto;
/// <summary>
/// Represents the AutoMapper profile configuration for mapping between

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using MediatR;

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities;

View File

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

View File

@@ -14,8 +14,8 @@
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.0.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.3.4" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.1.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />
<PackageReference Include="DigitalData.Core.Client" Version="2.1.0" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" />
<PackageReference Include="MediatR" Version="12.5.0" />

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 System.Collections.Generic;
using EnvelopeGenerator.Application.Envelopes.Commands;
using MediatR;
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>
/// Signaturposition auf einem Dokument.
/// </summary>

View File

@@ -1,10 +1,10 @@
using AutoMapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
/// <summary>
/// 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

@@ -1,47 +0,0 @@
using EnvelopeGenerator.Application.Histories;
namespace EnvelopeGenerator.Application.EnvelopeReceivers;
/// <summary>
/// Stellt eine Abfrage für einen Envelope-Empfänger dar.
/// </summary>
/// <param name="Status">Der Status der Abfrage, optional.</param>
public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null);
/// <summary>
/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Common.Constants.EnvelopeStatus"/>
/// Invalid (0): Ungültiger Status.
/// EnvelopeCreated (1001): Der Umschlag wurde erstellt.
/// EnvelopeSaved (1002): Der Umschlag wurde gespeichert.
/// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant.
/// EnvelopeSent (1004): Der Umschlag wurde versendet. (Nicht verwendet)
/// EnvelopePartlySigned (1005): Der Umschlag wurde teilweise unterschrieben.
/// EnvelopeCompletelySigned (1006): Der Umschlag wurde vollständig unterschrieben.
/// EnvelopeReportCreated (1007): Ein Abschlussbericht wurde für den Umschlag erstellt.
/// EnvelopeArchived (1008): Der Umschlag wurde archiviert.
/// EnvelopeDeleted (1009): Der Umschlag wurde gelöscht.
/// AccessCodeRequested (2001): Der Zugriffscode wurde angefordert.
/// AccessCodeCorrect (2002): Der Zugriffscode war korrekt.
/// AccessCodeIncorrect (2003): Der Zugriffscode war falsch.
/// DocumentOpened (2004): Das Dokument wurde geöffnet.
/// DocumentSigned (2005): Ein Dokument wurde unterschrieben.
/// SignatureConfirmed (2006): Die Signatur wurde bestätigt.
/// DocumentRejected (2007): Ein Dokument wurde abgelehnt.
/// EnvelopeShared (2008): Der Umschlag wurde geteilt.
/// EnvelopeViewed (2009): Der Umschlag wurde angesehen.
/// DocumentForwarded (4001): Das Dokument wurde weitergeleitet.
/// MessageInvitationSent (3001): Einladung wurde gesendet (vom Trigger verwendet).
/// MessageAccessCodeSent (3002): Zugriffscode wurde gesendet.
/// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet.
/// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet.
/// MessageCompletionSent (3005): Abschlussbenachrichtigung wurde gesendet.
/// <param name="Min">Der minimale Statuswert, der berücksichtigt werden soll.</param>
/// <param name="Max">Der maximale Statuswert, der berücksichtigt werden soll.</param>
/// <param name="Ignore">Eine Liste von Statuswerten, die ignoriert werden sollen.</param>
/// </summary>
public record EnvelopeStatusQuery(
int? Min = null,
int? Max = null,
int[]? Ignore = null)
{
}

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,137 @@
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Application.Receivers.Queries;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Extensions;
using MediatR;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
/// <summary>
/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers.
/// Invalid (0): Ungültiger Status.
/// EnvelopeCreated (1001): Der Umschlag wurde erstellt.
/// EnvelopeSaved (1002): Der Umschlag wurde gespeichert.
/// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant.
/// EnvelopeSent (1004): Der Umschlag wurde versendet. (Nicht verwendet)
/// EnvelopePartlySigned (1005): Der Umschlag wurde teilweise unterschrieben.
/// EnvelopeCompletelySigned (1006): Der Umschlag wurde vollständig unterschrieben.
/// EnvelopeReportCreated (1007): Ein Abschlussbericht wurde für den Umschlag erstellt.
/// EnvelopeArchived (1008): Der Umschlag wurde archiviert.
/// EnvelopeDeleted (1009): Der Umschlag wurde gelöscht.
/// AccessCodeRequested (2001): Der Zugriffscode wurde angefordert.
/// AccessCodeCorrect (2002): Der Zugriffscode war korrekt.
/// AccessCodeIncorrect (2003): Der Zugriffscode war falsch.
/// DocumentOpened (2004): Das Dokument wurde geöffnet.
/// DocumentSigned (2005): Ein Dokument wurde unterschrieben.
/// SignatureConfirmed (2006): Die Signatur wurde bestätigt.
/// DocumentRejected (2007): Ein Dokument wurde abgelehnt.
/// EnvelopeShared (2008): Der Umschlag wurde geteilt.
/// EnvelopeViewed (2009): Der Umschlag wurde angesehen.
/// DocumentForwarded (4001): Das Dokument wurde weitergeleitet.
/// MessageInvitationSent (3001): Einladung wurde gesendet (vom Trigger verwendet).
/// MessageAccessCodeSent (3002): Zugriffscode wurde gesendet.
/// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet.
/// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet.
/// MessageCompletionSent (3005): Abschlussbenachrichtigung wurde gesendet.
/// </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 Status, die Zuordnung zwischen Umschlag und Empfänger
/// sowie zusätzliche Metadaten.
/// </remarks>
public record ReadEnvelopeReceiverQuery : IRequest<EnvelopeReceiverDto>
{
/// <summary>
///
/// </summary>
public string? Key
{
get => Envelope?.Uuid is string uuid && Receiver?.Signature is string signature
? (uuid, signature).EncodeEnvelopeReceiverId()
: null;
init
{
if (value is null)
return;
(string? EnvelopeUuid, string? ReceiverSignature) = value.DecodeEnvelopeReceiverId();
if(string.IsNullOrEmpty(EnvelopeUuid) || string.IsNullOrEmpty(ReceiverSignature))
{
throw new BadRequestException("Der EnvelopeReceiverKey muss ein gültiger Base64-kodierter String sein, der die EnvelopeUuid und die ReceiverSignature enthält.");
}
Envelope = new ReadEnvelopeQuery()
{
Uuid = EnvelopeUuid
};
Receiver = new ReadReceiverQuery()
{
Signature = ReceiverSignature
};
}
}
/// <summary>
/// Der Umschlag, der mit dem Empfänger verknüpft ist.
/// </summary>
public ReadEnvelopeQuery? Envelope { get; set; }
/// <summary>
/// Der Empfänger, der mit dem Umschlag verknüpft ist.
/// </summary>
public ReadReceiverQuery? Receiver { get; set; }
/// <summary>
/// Abfrage des Status des Umschlags
/// </summary>
public EnvelopeStatusQuery? Status { get; init; }
};
/// <summary>
/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Constants.EnvelopeStatus"/>
/// Invalid (0): Ungültiger Status.
/// EnvelopeCreated (1001): Der Umschlag wurde erstellt.
/// EnvelopeSaved (1002): Der Umschlag wurde gespeichert.
/// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant.
/// EnvelopeSent (1004): Der Umschlag wurde versendet. (Nicht verwendet)
/// EnvelopePartlySigned (1005): Der Umschlag wurde teilweise unterschrieben.
/// EnvelopeCompletelySigned (1006): Der Umschlag wurde vollständig unterschrieben.
/// EnvelopeReportCreated (1007): Ein Abschlussbericht wurde für den Umschlag erstellt.
/// EnvelopeArchived (1008): Der Umschlag wurde archiviert.
/// EnvelopeDeleted (1009): Der Umschlag wurde gelöscht.
/// AccessCodeRequested (2001): Der Zugriffscode wurde angefordert.
/// AccessCodeCorrect (2002): Der Zugriffscode war korrekt.
/// AccessCodeIncorrect (2003): Der Zugriffscode war falsch.
/// DocumentOpened (2004): Das Dokument wurde geöffnet.
/// DocumentSigned (2005): Ein Dokument wurde unterschrieben.
/// SignatureConfirmed (2006): Die Signatur wurde bestätigt.
/// DocumentRejected (2007): Ein Dokument wurde abgelehnt.
/// EnvelopeShared (2008): Der Umschlag wurde geteilt.
/// EnvelopeViewed (2009): Der Umschlag wurde angesehen.
/// DocumentForwarded (4001): Das Dokument wurde weitergeleitet.
/// MessageInvitationSent (3001): Einladung wurde gesendet (vom Trigger verwendet).
/// MessageAccessCodeSent (3002): Zugriffscode wurde gesendet.
/// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet.
/// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet.
/// MessageCompletionSent (3005): Abschlussbenachrichtigung wurde gesendet.
/// </summary>
public record EnvelopeStatusQuery
{
/// <summary>
/// Der minimale Statuswert, der berücksichtigt werden soll.
/// </summary>
public int? Min { get; init; }
/// <summary>
/// Der maximale Statuswert, der berücksichtigt werden soll.
/// </summary>
public int? Max { get; init; }
/// <summary>
/// Eine Liste von Statuswerten, die ignoriert werden sollen.
/// </summary>
public int[]? Ignore { get; init; }
}

View File

@@ -0,0 +1,75 @@
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
/// <summary>
///
/// </summary>
public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeReceiverQuery, EnvelopeReceiverDto>
{
private readonly IRepository<EnvelopeReceiver> _repo;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiver"></param>
public ReadEnvelopeReceiverQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiver, IMapper mapper)
{
_repo = envelopeReceiver;
_mapper = mapper;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<EnvelopeReceiverDto> Handle(ReadEnvelopeReceiverQuery request, CancellationToken cancel)
{
var q = _repo.Read();
if(request.Envelope is not null)
{
var env = request.Envelope;
if (env.Id is not null)
q = q.Where(er => er.EnvelopeId == env.Id);
if (env.Status is not null)
q = q.Where(er => er.Envelope.Status == env.Status);
if (env.Uuid is not null)
q = q.Where(er => er.Envelope.Uuid == env.Uuid);
}
if (request.Receiver is not null)
{
var rcv = request.Receiver;
if (rcv.Id is not null)
q = q.Where(r => r.ReceiverId == rcv.Id);
if (rcv.EmailAddress is not null)
q = q.Where(r => r.Receiver.EmailAddress == rcv.EmailAddress);
if (rcv.Signature is not null)
q = q.Where(er => er.Receiver.Signature == rcv.Signature);
}
var er = 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)
.FirstOrDefaultAsync(cancel);
var dto = _mapper.Map<EnvelopeReceiverDto>(er);
return dto;
}
}

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 System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
@@ -15,7 +17,7 @@ public record CreateEnvelopeCommand(
[Required] string Title,
[Required] string Message,
bool TFAEnabled = false
) : IRequest<CreateEnvelopeResponse?>
) : IRequest<EnvelopeDto?>
{
/// <summary>
/// Id of receiver
@@ -23,4 +25,4 @@ public record CreateEnvelopeCommand(
[JsonIgnore]
[BindNever]
public int? UserId { get; set; }
};
};

View File

@@ -1,5 +1,6 @@
using AutoMapper;
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using EnvelopeGenerator.Application.Dto;
using MediatR;
namespace EnvelopeGenerator.Application.Envelopes.Commands;
@@ -7,7 +8,7 @@ namespace EnvelopeGenerator.Application.Envelopes.Commands;
/// <summary>
///
/// </summary>
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?>
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, EnvelopeDto?>
{
private readonly IEnvelopeExecutor _envelopeExecutor;
@@ -30,12 +31,12 @@ public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeComman
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <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.");
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

@@ -0,0 +1,24 @@
using MediatR;
namespace EnvelopeGenerator.Application.Envelopes.Queries;
/// <summary>
/// Repräsentiert eine Abfrage für Umschläge.
/// </summary>
public class ReadEnvelopeQuery : IRequest
{
/// <summary>
/// Die eindeutige Kennung des Umschlags.
/// </summary>
public int? Id { get; init; }
/// <summary>
/// Der Status des Umschlags.
/// </summary>
public int? Status { get; init; }
/// <summary>
/// Die universell eindeutige Kennung des Umschlags.
/// </summary>
public string? Uuid { 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>
/// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln,

View File

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

View File

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

View File

@@ -1,10 +0,0 @@
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
/// <summary>
/// Stellt eine Abfrage dar, um die Details eines Empfängers zu lesen.
/// Diese Abfrage erbt von <see cref="ReceiverQuery"/> und wird verwendet,
/// um spezifische Informationen über einen Empfänger abzurufen.
/// </summary>
public record ReadReceiverQuery : ReceiverQuery
{
}

View File

@@ -1,12 +0,0 @@
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
/// <summary>
/// Repräsentiert die Antwort auf eine Abfrage, um einen Empfänger zu lesen.
/// </summary>
/// <param name="Id">Die eindeutige Identifikationsnummer des Empfängers.</param>
/// <param name="EmailAddress">Die E-Mail-Adresse des Empfängers.</param>
/// <param name="AddedWhen">Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde.</param>
/// <param name="Signature">Die Signatur des Empfängers.</param>
public record ReadReceiverResponse(int Id, string EmailAddress, DateTime AddedWhen, string Signature)
{
}

View File

@@ -0,0 +1,23 @@
namespace EnvelopeGenerator.Application.Receivers.Queries;
/// <summary>
/// Stellt eine Abfrage dar, um die Details eines Empfängers zu lesen.
/// um spezifische Informationen über einen Empfänger abzurufen.
/// </summary>
public record ReadReceiverQuery
{
/// <summary>
/// ID des Empfängers
/// </summary>
public int? Id { get; init; }
/// <summary>
/// E-Mail Adresse des Empfängers
/// </summary>
public string? EmailAddress { get; init; }
/// <summary>
/// Eindeutige Signatur des Empfängers
/// </summary>
public string? Signature { get; init; }
}

View File

@@ -1,9 +0,0 @@
namespace EnvelopeGenerator.Application.Receivers;
/// <summary>
/// Empfänger des Umschlags
/// </summary>
/// <param name="Id">ID des Empfängers</param>
/// <param name="EmailAddress">E-Mail Adresse des Empfängers</param>
/// <param name="Signature">Eindeutige Signatur des Empfängers</param>
public record ReceiverQuery(int? Id = null, string? EmailAddress = null, string? Signature = null);

View File

@@ -2,7 +2,7 @@
using DigitalData.Core.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;
using Microsoft.Extensions.Caching.Memory;

View File

@@ -1,7 +1,7 @@
using AutoMapper;
using DigitalData.Core.Application;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;

View File

@@ -1,7 +1,7 @@
using AutoMapper;
using DigitalData.Core.Application;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;

View File

@@ -1,6 +1,6 @@
using AutoMapper;
using DigitalData.Core.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;
using static EnvelopeGenerator.Domain.Constants;

View File

@@ -1,7 +1,7 @@
using AutoMapper;
using DigitalData.Core.Application;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;

View File

@@ -3,8 +3,8 @@ using DigitalData.Core.Application;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;
using static EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.EnvelopeHistory;
using EnvelopeGenerator.Application.Dto.Receiver;
using EnvelopeGenerator.Application.Contracts.Services;
using DigitalData.Core.Abstraction.Application.DTO;

View File

@@ -2,12 +2,12 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using static EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Extensions;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.Extensions;
using Newtonsoft.Json;

View File

@@ -1,7 +1,7 @@
using AutoMapper;
using DigitalData.Core.Application;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;

View File

@@ -1,17 +1,18 @@
using AutoMapper;
using DigitalData.Core.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using EnvelopeGenerator.Extensions;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Dto.Messaging;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.Envelopes;
using EnvelopeGenerator.Application.Receivers.Queries.Read;
using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Receivers.Queries;
namespace EnvelopeGenerator.Application.Services;
@@ -236,7 +237,7 @@ public class EnvelopeReceiverService : BasicCRUDService<IEnvelopeReceiverReposit
/// <param name="receiverQuery"></param>
/// <param name="ignore_statuses"></param>
/// <returns></returns>
public async Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, EnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params int[] ignore_statuses)
public async Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, ReadEnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params int[] ignore_statuses)
{
var er_list = await _repository.ReadByUsernameAsync(username: username, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses);

View File

@@ -2,7 +2,7 @@
using DigitalData.Core.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;

View File

@@ -1,7 +1,7 @@
using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Dto.Messaging;
using EnvelopeGenerator.Application.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;

View File

@@ -1,6 +1,6 @@
using AutoMapper;
using DigitalData.Core.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Dto;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;
using Microsoft.Extensions.Caching.Memory;

View File

@@ -3,7 +3,7 @@ using DigitalData.Core.Client.Interface;
using DigitalData.Core.Client;
using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.Contracts.Services;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Dto.Messaging;
using Microsoft.Extensions.Options;
namespace EnvelopeGenerator.Application.Services;

View File

@@ -2,7 +2,7 @@
using DigitalData.Core.Application;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.Application.Contracts.Repositories;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Dto.Receiver;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.Contracts.Services;

View File

@@ -436,6 +436,7 @@
<Content Include="Images\circle.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Compile Include="Models\ReceiverVM.vb" />
<Content Include="README.txt" />
<EmbeddedResource Include="Templates\document_access_code_de.html" />
<EmbeddedResource Include="Templates\email_de.html" />

View File

@@ -4,6 +4,7 @@ Imports DigitalData.Modules.Base
Imports Quartz
Imports System.Security.Cryptography
Imports DevExpress.DataProcessing
Imports EnvelopeGenerator.Domain.Entities
Namespace Jobs
Public Class APIEnvelopeJob
@@ -83,7 +84,7 @@ Namespace Jobs
oEnvelope.CURRENT_WORK_APP = "signFLOW_API_EnvJob_InvMail"
Logger.Debug("SendInvMail - Loading Envelope Data..")
Dim oEnvelopeData = GetEnvelopeData(oId)
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id).ToList()
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id).OfType(Of EnvelopeReceiver).ToList()
Logger.Debug("SendInvMail - Created Reveivers!")
If oEnvelopeData Is Nothing Then
Logger.Warn("SendInvMail - EnvelopeData could not be loaded for Id [{0}]!", oId)
@@ -133,7 +134,7 @@ Namespace Jobs
Throw New ArgumentNullException("EnvelopeData")
End If
oEnvelope.CURRENT_WORK_APP = "signFLOW_API_EnvJob_Withdrawn"
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id).ToList()
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id).OfType(Of EnvelopeReceiver).ToList()
Logger.Debug("WithdrawnEnv - Sending Withdrawn Mails..")

View File

@@ -217,7 +217,7 @@ Namespace Jobs
If Not IsNothing(imageData) Then
sFileName = System.IO.Path.GetFileName(pFilePath)
'Set insert query
qry = $"UPDATE TBSIG_ENVELOPE SET DOC_RESULT = @ImageData WHERE GUID = {pEnvelopeID}"
qry = $"UPDATE TBSIG_ENVELOPE SET DocResult = @ImageData WHERE GUID = {pEnvelopeID}"
'Initialize SqlCommand object for insert.
SqlCom = New SqlCommand(qry, Database.GetConnection)
'We are passing File Name and Image byte data as sql parameters.
@@ -338,7 +338,7 @@ Namespace Jobs
For Each oReceiver In pEnvelope.Receivers
If ActionService.CompleteEnvelope(pEnvelope, oReceiver) = False Then ', oAttachment
Logger.Error("Envelope could not be completed for receiver [{0}]", oReceiver.EmailAddress)
Logger.Error("Envelope could not be completed for receiver [{0}]", oReceiver.Receiver.EmailAddress)
Return False
End If
Next

View File

@@ -1,4 +1,5 @@
Imports EnvelopeGenerator.Domain
Imports EnvelopeGenerator.CommonServices.EnvelopeGenerator.Domain.Entities
Imports EnvelopeGenerator.Domain
Imports EnvelopeGenerator.Domain.Entities
Public Class EmailData
Public Property EmailAdress As String = ""
@@ -28,7 +29,7 @@ Public Class EmailData
''' <param name="pEnvelope"></param>
''' <param name="pReceiver"></param>
''' <param name="pStatus"></param>
Public Sub New(pEnvelope As Entities.Envelope, pReceiver As Receiver, pStatus As Constants.EnvelopeStatus)
Public Sub New(pEnvelope As Entities.Envelope, pReceiver As ReceiverVM, pStatus As Constants.EnvelopeStatus)
EmailAdress = pReceiver.EmailAddress
EmailSubject = String.Empty
EmailType = pStatus

View File

@@ -49,16 +49,16 @@ Public Class EnvelopeModel
.UseAccessCode = pRow.ItemEx("USE_ACCESS_CODE", False),
.FinalEmailToCreator = ObjectEx.ToEnum(Of FinalEmailType)(pRow.ItemEx("FINAL_EMAIL_TO_CREATOR", FinalEmailType.No.ToString())),
.FinalEmailToReceivers = ObjectEx.ToEnum(Of FinalEmailType)(pRow.ItemEx("FINAL_EMAIL_TO_RECEIVERS", FinalEmailType.No.ToString())),
.TFA_Enabled = pRow.ItemEx("TFA_Enabled", False)
.TfaEnabled = pRow.ItemEx("TFA_ENABLED", False)
}
Dim oDOC_RESULT = pRow.Item("DOC_RESULT")
If Not IsDBNull(oDOC_RESULT) Then
Dim oByte As Byte() = DirectCast(pRow.Item("DOC_RESULT"), Byte())
If Not IsNothing(oByte) Then
oEnvelope.DOC_RESULT = oByte
oEnvelope.DocResult = oByte
End If
Else
oEnvelope.DOC_RESULT = Nothing
oEnvelope.DocResult = Nothing
End If
oEnvelope.User = UserModel.SelectUser(oEnvelope.UserId)
oEnvelope.Receivers = ReceiverModel.ListEnvelopeReceivers(oEnvelope.Id)
@@ -76,15 +76,9 @@ Public Class EnvelopeModel
End Function
Public Function GetByUuid(pEnvelopeUuid As String) As Envelope
Try
Dim oSql = $"SELECT * FROM [dbo].[TBSIG_ENVELOPE] WHERE ENVELOPE_UUID = '{pEnvelopeUuid}'"
Dim oTable = Database.GetDatatable(oSql)
Return ToEnvelope(oTable)
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
Dim oSql = $"SELECT * FROM [dbo].[TBSIG_ENVELOPE] WHERE ENVELOPE_UUID = '{pEnvelopeUuid}'"
Dim oTable = Database.GetDatatable(oSql)
Return ToEnvelope(oTable)
End Function
Public Function GetById(pEnvelopeId As Integer) As Envelope
@@ -191,7 +185,7 @@ Public Class EnvelopeModel
oSql += " [SEND_REMINDER_EMAILS] = @SEND_REMINDER_EMAILS, "
oSql += " [USE_ACCESS_CODE] = @USE_ACCESS_CODE, "
oSql += " [CHANGED_WHEN] = GETDATE(), "
oSql += " [TFA_Enabled] = @TFA_Enabled"
oSql += " [TfaEnabled] = @TfaEnabled"
oSql += " WHERE GUID = @ID AND USER_ID = @USER_ID"
@@ -216,7 +210,7 @@ Public Class EnvelopeModel
oCommand.Parameters.Add("REMINDER_INTERVAL_DAYS", SqlDbType.Int).Value = pEnvelope.ReminderIntervalDays
oCommand.Parameters.Add("SEND_REMINDER_EMAILS", SqlDbType.Bit).Value = pEnvelope.SendReminderEmails
oCommand.Parameters.Add("USE_ACCESS_CODE", SqlDbType.Bit).Value = pEnvelope.UseAccessCode
oCommand.Parameters.Add("TFA_ENABLED", SqlDbType.Bit).Value = pEnvelope.TFA_Enabled
oCommand.Parameters.Add("TFA_ENABLED", SqlDbType.Bit).Value = pEnvelope.TfaEnabled
Return Database.ExecuteNonQuery(oCommand, pTransaction)
Catch ex As Exception

View File

@@ -23,7 +23,7 @@ Public Class EnvelopeTypeModel
.FinalEmailToReceivers = pRow.ItemEx("FINAL_EMAIL_TO_RECEIVERS", 0),
.ContractType = pRow.ItemEx("CONTRACT_TYPE", 0),
.CertificationType = pRow.ItemEx("CERTIFICATION_TYPE", 0),
.TFA_Enabled = pRow.ItemEx("TFA_Enabled", 0)
.TFA_Enabled = pRow.ItemEx("TfaEnabled", 0)
}
End Function

View File

@@ -1,6 +1,4 @@
Imports System.Data.SqlClient
Imports System.Net.Mail
Imports DevExpress.DataProcessing
Imports DigitalData.Modules.Base
Imports EnvelopeGenerator.Domain.Constants
Imports EnvelopeGenerator.Domain.Entities
@@ -12,7 +10,7 @@ Public Class ReceiverModel
MyBase.New(pState)
End Sub
Private Function ToReceiver(pRow As DataRow, pColorIndex As Integer) As Receiver
Private Function ToReceiver(pRow As DataRow, pColorIndex As Integer) As ReceiverVM
Dim EmailAdress As String = pRow.ItemEx("EMAIL_ADDRESS", "")
Dim EnvelopeId As Integer = pRow.ItemEx("ENVELOPE_ID", 0)
Dim SignedDate As DateTime = DateTime.MinValue
@@ -25,7 +23,7 @@ Public Class ReceiverModel
End If
End If
Return New Receiver() With {
Return New ReceiverVM() With {
.Id = pRow.ItemEx("GUID", 0),
.EmailAddress = pRow.ItemEx("EMAIL_ADDRESS", ""),
.Name = pRow.ItemEx("NAME", ""),
@@ -39,75 +37,31 @@ Public Class ReceiverModel
}
End Function
Private Function ToReceiver(pTable As DataTable) As Receiver
Return pTable?.Rows.Cast(Of DataRow).
Select(AddressOf ToReceiver).
Single()
End Function
Public Function TestReceiverExists(pReceiver As Receiver) As Boolean
Try
Dim oGuid = Database.GetScalarValue($"SELECT COALESCE(GUID, 0) FROM TBSIG_RECEIVER WHERE EMAIL_ADDRESS = '{pReceiver.EmailAddress}'")
pReceiver.Id = oGuid
Return oGuid > 0
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
End Function
Public Function Insert(pReceiver As Receiver, pTransaction As SqlTransaction) As Boolean
Try
Dim oSignature As String = pReceiver.GetSignature()
Dim oCheck = $"SELECT COUNT(GUID) FROM [dbo].[TBSIG_RECEIVER] WHERE SIGNATURE = '{oSignature}'"
Dim oExists = Database.GetScalarValue(oCheck)
Dim oSignature As String = pReceiver.GetSignature()
Dim oCheck = $"SELECT COUNT(GUID) FROM [dbo].[TBSIG_RECEIVER] WHERE SIGNATURE = '{oSignature}'"
Dim oExists = Database.GetScalarValue(oCheck)
If oExists = 0 Then
Dim oSql As String = $"INSERT INTO [dbo].[TBSIG_RECEIVER]
If oExists = 0 Then
Dim oSql As String = $"INSERT INTO [dbo].[TBSIG_RECEIVER]
([EMAIL_ADDRESS]
,[SIGNATURE])
VALUES
('{pReceiver.EmailAddress}'
,'{pReceiver.GetSignature()}')"
Dim oCommand = New SqlCommand(oSql)
Dim oResult = Database.ExecuteNonQuery(oCommand)
If oResult = True Then
pReceiver.Id = GetReceiverIdByEmail(pReceiver.EmailAddress, pTransaction)
Return True
Else
Return False
End If
Else
Logger.Warn($"Receiver [{pReceiver.EmailAddress}] already existing! SignatureID: {oSignature} Check SQL {oCheck}")
Return True
End If
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
End Function
Public Function Update(pReceiver As Receiver, pTransaction As SqlTransaction) As Boolean
Try
Dim oSql As String = $"UPDATE [dbo].[TBSIG_USER_RECEIVER]
SET [NAME] = '{pReceiver.Name}'
,[COMPANY_NAME] = '{pReceiver.Company}'
,[JOB_TITLE] = '{pReceiver.JobTitle}'
WHERE RECEIVER_ID = {pReceiver.Id}"
Dim oCommand = New SqlCommand(oSql)
'oCommand.Parameters.Add("NAME", SqlDbType.NVarChar).Value = pReceiver.Name
'oCommand.Parameters.Add("COMPANY", SqlDbType.NVarChar).Value = pReceiver.Company
'oCommand.Parameters.Add("JOB", SqlDbType.NVarChar).Value = pReceiver.JobTitle
'oCommand.Parameters.Add("RECEIVER_ID", SqlDbType.Int).Value = pReceiver.Id
'oCommand.Parameters.Add("USER_ID", SqlDbType.Int).Value = pReceiver.Id
Return Database.ExecuteNonQuery(oCommand, pTransaction)
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
Dim oResult = Database.ExecuteNonQuery(oCommand)
If oResult = True Then
pReceiver.Id = GetReceiverIdByEmail(pReceiver.EmailAddress, pTransaction)
Return True
Else
Return False
End If
Else
Logger.Warn($"Receiver [{pReceiver.EmailAddress}] already existing! SignatureID: {oSignature} Check SQL {oCheck}")
Return True
End If
End Function
Public Function Unassign(pEnvelope As Envelope, pTransaction As SqlTransaction) As Boolean
@@ -119,7 +73,7 @@ Public Class ReceiverModel
End Try
End Function
Public Function Assign(pEnvelope As Envelope, pReceiver As Receiver, pTransaction As SqlTransaction) As Boolean
Public Function Assign(pEnvelope As Envelope, pReceiver As ReceiverVM, pTransaction As SqlTransaction) As Boolean
Dim oSql = $"INSERT INTO [dbo].[TBSIG_ENVELOPE_RECEIVER]
([ENVELOPE_ID]
,[RECEIVER_ID]
@@ -137,7 +91,7 @@ Public Class ReceiverModel
,'{pReceiver.AccessCode}'
,'{pReceiver.Name}'
,'{pReceiver.JobTitle}'
,'{pReceiver.Company}'
,'{pReceiver.CompanyName}'
,'{pReceiver.Sequence}'
,'{pReceiver.PhoneNumber}')"
@@ -148,13 +102,13 @@ Public Class ReceiverModel
'oCommand.Parameters.Add("ACCESS_CODE", SqlDbType.NVarChar).Value = pReceiver.AccessCode
'oCommand.Parameters.Add("NAME", SqlDbType.NVarChar).Value = pReceiver.Name
'oCommand.Parameters.Add("JOB", SqlDbType.NVarChar).Value = pReceiver.JobTitle
'oCommand.Parameters.Add("COMPANY", SqlDbType.NVarChar).Value = pReceiver.Company
'oCommand.Parameters.Add("COMPANY", SqlDbType.NVarChar).Value = pReceiver.CompanyName
'oCommand.Parameters.Add("SEQUENCE", SqlDbType.NVarChar).Value = pReceiver.Sequence
Return Database.ExecuteNonQuery(oCommand, pTransaction)
End Function
Public Function ListEnvelopeReceivers(pEnvelopeId As Integer) As IEnumerable(Of Receiver)
Public Function ListEnvelopeReceivers(pEnvelopeId As Integer) As IEnumerable(Of ReceiverVM)
Try
Dim oSql = $"SELECT * FROM [dbo].[VWSIG_ENVELOPE_RECEIVERS] WHERE ENVELOPE_ID = {pEnvelopeId}"
Dim oTable = Database.GetDatatable(oSql)

View File

@@ -0,0 +1,119 @@
Imports System.Drawing
Imports EnvelopeGenerator.Domain
Imports EnvelopeGenerator.Domain.Entities
''' <summary>
''' Handles the combination of the envelope and receiver for common services and submodules as a view model.
''' </summary>
Public Class ReceiverVM
Inherits EnvelopeReceiver
Public Shared Function From(source As EnvelopeReceiver) As ReceiverVM
Return New ReceiverVM() With {
.EnvelopeId = source.EnvelopeId,
.ReceiverId = source.ReceiverId,
.Sequence = source.Sequence,
.Name = source.Name,
.JobTitle = source.JobTitle,
.CompanyName = source.CompanyName,
.PrivateMessage = source.PrivateMessage,
.AccessCode = source.AccessCode,
.AddedWhen = source.AddedWhen,
.ChangedWhen = source.ChangedWhen,
.PhoneNumber = source.PhoneNumber,
.Status = source.Status,
.Envelope = source.Envelope,
.Receiver = source.Receiver
}
End Function
Private ReadOnly Property SReceiver As Receiver
Get
If Receiver Is Nothing Then
Receiver = New Receiver()
End If
Return Receiver
End Get
End Property
Public Property Id As Integer
Get
Return SReceiver.Id
End Get
Set(value As Integer)
SReceiver.Id = value
End Set
End Property
Public Property EmailAddress As String
Get
Return SReceiver.EmailAddress
End Get
Set(value As String)
SReceiver.EmailAddress = value
End Set
End Property
Public Property Signature As String
Get
Return SReceiver.Signature
End Get
Set(value As String)
SReceiver.Signature = value
End Set
End Property
Public Property AddedWhen As DateTime
Get
Return SReceiver.AddedWhen
End Get
Set(value As DateTime)
SReceiver.AddedWhen = value
End Set
End Property
Public Property TotpSecretkey As String
Get
Return SReceiver.TotpSecretkey
End Get
Set(value As String)
SReceiver.TotpSecretkey = value
End Set
End Property
Public Property TfaRegDeadline As DateTime?
Get
Return SReceiver.TfaRegDeadline
End Get
Set(value As DateTime?)
SReceiver.TfaRegDeadline = value
End Set
End Property
#Region "Model of old service"
Public Property SignedDate As DateTime = DateTime.MinValue
Public Property ColorType As Constants.ColorType
Public ReadOnly Property SignedDateDisplayValue As String
Get
If SignedDate = DateTime.MinValue Then
Return "-"
Else
Return SignedDate.ToString("G")
End If
End Get
End Property
Public ReadOnly Property Color As Color
Get
Return ColorType.ToColor()
End Get
End Property
Public Function GetSignature() As String
Return Receiver.GetSignature()
End Function
#End Region
End Class

View File

@@ -653,7 +653,7 @@ Partial Public Class rptEnvelopeHistory
'ObjectDataSource1
'
Me.ObjectDataSource1.DataMember = "Items"
Me.ObjectDataSource1.DataSource = GetType(EnvelopeGenerator.CommonServices.ReportSource)
'Me.ObjectDataSource1.DataSource = GetType(EnvelopeGenerator.CommonServices.ReportSource)
Me.ObjectDataSource1.Name = "ObjectDataSource1"
'
'rptEnvelopeHistory

View File

@@ -2,6 +2,7 @@
Imports EnvelopeGenerator.Domain.Constants
Imports EnvelopeGenerator.CommonServices.My.Resources
Imports DigitalData.Modules.Database
Imports EnvelopeGenerator.CommonServices.EnvelopeGenerator.Domain.Entities
Public Class ActionService
Inherits BaseService
@@ -54,10 +55,10 @@ Public Class ActionService
Next
Return oSendResult
End Function
Public Function ResendReceiver(pEnvelope As Domain.Entities.Envelope, pReceiver As Receiver) As Boolean
Public Function ResendReceiver(pEnvelope As Domain.Entities.Envelope, pReceiver As ReceiverVM) As Boolean
Return EmailService.SendDocumentReceivedEmail(pEnvelope, pReceiver)
End Function
Public Function ManuallySendAccessCode(pEnvelope As Domain.Entities.Envelope, pReceiver As Receiver) As Boolean
Public Function ManuallySendAccessCode(pEnvelope As Domain.Entities.Envelope, pReceiver As ReceiverVM) As Boolean
Return EmailService.SendDocumentAccessCodeReceivedEmail(pEnvelope, pReceiver)
End Function
@@ -86,7 +87,7 @@ Public Class ActionService
End Function
Public Function API_SendWithdrawn_Mails(pEnvelope As Domain.Entities.Envelope, pReason As String) As Boolean
Dim oSendResult As Boolean = False
For Each oReceiver As Receiver In pEnvelope.Receivers
For Each oReceiver As ReceiverVM In pEnvelope.Receivers
If EmailService.SendEnvelopeDeletedEmail(pEnvelope, oReceiver, pReason) = False Then
Return False
End If
@@ -134,7 +135,7 @@ Public Class ActionService
Return True
End Function
Public Function SignEnvelope(pEnvelope As Domain.Entities.Envelope, pReceiver As Receiver) As Boolean
Public Function SignEnvelope(pEnvelope As Domain.Entities.Envelope, pReceiver As ReceiverVM) As Boolean
Dim oUserReference = pReceiver.EmailAddress
If HistoryService.SetEnvelopeStatus(pEnvelope, EnvelopeStatus.DocumentSigned, oUserReference) = False Then
@@ -152,7 +153,7 @@ Public Class ActionService
Return True
End Function
Public Function CompleteEnvelope(pEnvelope As Domain.Entities.Envelope, pReceiver As Domain.Entities.Receiver) As Boolean ', pAttachment As String
Public Function CompleteEnvelope(pEnvelope As Domain.Entities.Envelope, pReceiver As ReceiverVM) As Boolean ', pAttachment As String
If HistoryService.SetEnvelopeStatus(pEnvelope, EnvelopeStatus.MessageCompletionSent, pReceiver.EmailAddress) = False Then
Return False
End If

View File

@@ -1,4 +1,5 @@
Imports DigitalData.Modules.Logging
Imports EnvelopeGenerator.CommonServices.EnvelopeGenerator.Domain.Entities
Imports EnvelopeGenerator.Domain.Entities
Public Class EmailService
@@ -14,7 +15,7 @@ Public Class EmailService
EmailTemplate = New TemplateService(pState)
End Sub
Public Function SendEnvelopeDeletedEmail(pEnvelope As Envelope, pReceiver As Receiver, pReason As String) As Boolean
Public Function SendEnvelopeDeletedEmail(pEnvelope As Envelope, pReceiver As ReceiverVM, pReason As String) As Boolean
Logger.Debug("SendEnvelopeDeletedEmail - Creating email data object...")
Dim oEmailData As New EmailData(pEnvelope, pReceiver, Domain.Constants.EnvelopeStatus.MessageDeletionSent) With
{
@@ -32,7 +33,7 @@ Public Class EmailService
Return True
End Function
Public Function SendDocumentReceivedEmail(pEnvelope As Envelope, pReceiver As Receiver) As Boolean
Public Function SendDocumentReceivedEmail(pEnvelope As Envelope, pReceiver As ReceiverVM) As Boolean
Logger.Debug("Creating email data object.")
Dim oEmailData As New EmailData(pEnvelope, pReceiver, Domain.Constants.EnvelopeStatus.MessageInvitationSent) With
{
@@ -50,7 +51,7 @@ Public Class EmailService
Return True
End Function
Public Function GetReceiverUrl(pEnvelope As Envelope, pReceiver As Receiver) As String
Public Function GetReceiverUrl(pEnvelope As Envelope, pReceiver As ReceiverVM) As String
Logger.Debug($"State.DbConfig.SignatureHost: {State.DbConfig.SignatureHost}")
Logger.Debug($" pEnvelope.Uuid: {pEnvelope.Uuid}")
Logger.Debug($" pReceiver.Signature: {pReceiver.Signature}")
@@ -63,7 +64,7 @@ Public Class EmailService
End Function
Public Function SendDocumentAccessCodeReceivedEmail(pEnvelope As Envelope, pReceiver As Receiver) As Boolean
Public Function SendDocumentAccessCodeReceivedEmail(pEnvelope As Envelope, pReceiver As ReceiverVM) As Boolean
Logger.Debug("Creating email data object.")
Logger.Debug($"State.DbConfig.SignatureHost: {State.DbConfig.SignatureHost}")
Logger.Debug($" pEnvelope.Uuid: {pEnvelope.Uuid}")
@@ -84,7 +85,7 @@ Public Class EmailService
Return True
End Function
Public Function SendSignedEmail(pEnvelope As Envelope, pReceiver As Receiver) As Boolean
Public Function SendSignedEmail(pEnvelope As Envelope, pReceiver As ReceiverVM) As Boolean
Logger.Debug("Creating email data object.")
Dim oEmailData = New EmailData(pEnvelope, pReceiver, Domain.Constants.EnvelopeStatus.MessageConfirmationSent) With
{
@@ -101,7 +102,7 @@ Public Class EmailService
Return True
End Function
Public Function SendDocumentCompletedEmailToReceiver(pEnvelope As Envelope, pReceiver As Receiver) As Boolean ', pAttachment As String
Public Function SendDocumentCompletedEmailToReceiver(pEnvelope As Envelope, pReceiver As ReceiverVM) As Boolean ', pAttachment As String
Logger.Debug("Creating email data object.")
Dim oEmailData = New EmailData(pEnvelope, pReceiver, Domain.Constants.EnvelopeStatus.MessageCompletionSent) With
{

View File

@@ -35,9 +35,10 @@ public class Envelope
UseAccessCode = false;
Documents = Enumerable.Empty<EnvelopeDocument>().ToList();
History = Enumerable.Empty<EnvelopeHistory>().ToList();
Receivers = Enumerable.Empty<EnvelopeReceiver>().ToList();
#endif
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("GUID")]
@@ -125,6 +126,21 @@ public class Envelope
[ForeignKey("UserId")]
public User User { get; set; }
[Column("TFA_ENABLED")]
public bool TfaEnabled { get; set; }
#if NETFRAMEWORK
= false;
#endif
[NotMapped]
[Column("DOC_RESULT")]
public byte[]
#if NET
?
#endif
DocResult
{ get; set; }
[ForeignKey("EnvelopeTypeId")]
public virtual EnvelopeType
#if NET
@@ -138,23 +154,19 @@ public class Envelope
[NotMapped]
public bool IsAlreadySent => Status > (int)Constants.EnvelopeStatus.EnvelopeSaved;
[NotMapped]
public bool TFA_Enabled { get; set; } = false;
[NotMapped]
public byte[] DOC_RESULT { get; set; }
#endif
public List<EnvelopeDocument> Documents { get; set; }
public List<EnvelopeHistory> History { get; set; }
// TODO: * Check the Form App and remove the default value
[NotMapped]
public List<Receiver> Receivers { get; set; } = Enumerable.Empty<Receiver>().ToList();
public List<EnvelopeReceiver>
#if NET
?
#endif
Receivers { get; set; }
#if NETFRAMEWORK
//#if NETFRAMEWORK
/// <summary>
/// Validates whether the receiver and document data are complete.
/// </summary>
@@ -173,7 +185,7 @@ public class Envelope
return errors;
}
#endif
//#endif
}
#if NETFRAMEWORK

View File

@@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Drawing;
#if NETFRAMEWORK
using System;
#endif
@@ -14,6 +15,13 @@ namespace EnvelopeGenerator.Domain.Entities
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
public class EnvelopeReceiver
{
public EnvelopeReceiver()
{
#if NETFRAMEWORK
CompanyName = string.Empty;
#endif
}
[Column("ENVELOPE_ID")]
public int EnvelopeId { get; set; }
@@ -31,7 +39,11 @@ public class EnvelopeReceiver
public string JobTitle { get; set; }
[Column("COMPANY_NAME", TypeName = "nvarchar(128)")]
public string CompanyName { get; set; }
public string
#if NET
?
#endif
CompanyName { get; set; }
[Column("PRIVATE_MESSAGE", TypeName = "nvarchar(max)")]
public string PrivateMessage { get; set; }
@@ -62,6 +74,19 @@ public class EnvelopeReceiver
[ForeignKey("ReceiverId")]
public Receiver Receiver { get; set; }
#region Model of old serice
[NotMapped]
public Constants.ReceiverStatus Status { get; set; }
[NotMapped]
public bool HasId => Id.Item1 > 0 && Id.Item2 > 0;
[NotMapped]
public bool HasEmailAndName =>
!string.IsNullOrWhiteSpace(Receiver.EmailAddress) &&
!string.IsNullOrWhiteSpace(Name);
#endregion
}
#if NETFRAMEWORK

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