Compare commits

...

7 Commits

13 changed files with 2235 additions and 2175 deletions

View File

@@ -0,0 +1,18 @@
using System.Text.Json;
namespace EnvelopeGenerator.Application.Common.Extensions;
/// <summary>
///
/// </summary>
public static class JsonExtensions
{
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <param name="options"></param>
/// <returns></returns>
public static string ToJson(this object obj, JsonSerializerOptions? options = null)
=> JsonSerializer.Serialize(obj, options);
}

View File

@@ -1,4 +1,5 @@
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
using Newtonsoft.Json;
@@ -27,7 +28,7 @@ public record DocSignedNotification(EnvelopeReceiverDto Original) : EnvelopeRece
/// </summary>
public string EmailAddress => Receiver?.EmailAddress
?? throw new InvalidOperationException($"Receiver is null." +
$"DocSignedNotification:\n{JsonConvert.SerializeObject(this, Format.Json.ForDiagnostics)}");
$"DocSignedNotification:\n{this.ToJson(Format.Json.ForDiagnostics)}");
}
/// <summary>

View File

@@ -1,8 +1,7 @@
using EnvelopeGenerator.Application.Common.Notifications.DocSigned;
using EnvelopeGenerator.Application.DocStatus.Commands;
using EnvelopeGenerator.Application.DocStatus.Commands;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
using Newtonsoft.Json;
using System.Text.Json;
namespace EnvelopeGenerator.Application.Common.Notifications.DocSigned.Handlers;
@@ -34,7 +33,7 @@ public class AnnotationHandler : INotificationHandler<DocSignedNotification>
{
Envelope = new() { Id = notification.EnvelopeId },
Receiver = new() { Id = notification.ReceiverId},
Value = JsonConvert.SerializeObject(notification.Annotations, Format.Json.ForAnnotations)
Value = JsonSerializer.Serialize(notification.Annotations, Format.Json.ForAnnotations)
}, cancel);
}
}

View File

@@ -1,4 +1,4 @@
using EnvelopeGenerator.Application.Common.Notifications.DocSigned;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Histories.Commands;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
@@ -32,14 +32,13 @@ public class HistoryHandler : INotificationHandler<DocSignedNotification>
{
if(notification.Receiver is null)
if (notification.Receiver is null)
throw new InvalidOperationException($"Receiver information is missing in the notification. DocSignedNotification:\n {JsonConvert.SerializeObject(notification, Format.Json.ForDiagnostics)}");
throw new InvalidOperationException($"Receiver information is missing in the notification. DocSignedNotification:\n {notification.ToJson(Format.Json.ForDiagnostics)}");
await _sender.Send(new CreateHistoryCommand()
{
EnvelopeId = notification.EnvelopeId,
UserReference = notification.Receiver.EmailAddress,
Status = EnvelopeStatus.DocumentSigned,
Comment = JsonConvert.SerializeObject(notification.Annotations, Format.Json.ForAnnotations)
}, cancel);
}
}

View File

@@ -1,6 +1,7 @@
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
using EnvelopeGenerator.Application.Common.Configurations;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
@@ -101,7 +102,7 @@ public abstract class SendMailHandler<TNotification> : INotificationHandler<TNot
.ReadOnly()
.SingleOrDefaultAsync(x => x.Name == notification.TemplateType.ToString(), cancel)
?? throw new InvalidOperationException($"Receiver information is missing in the notification." +
$"{typeof(TNotification)}:\n {JsonConvert.SerializeObject(notification, Format.Json.ForDiagnostics)}");
$"{typeof(TNotification)}:\n {notification.ToJson(Format.Json.ForDiagnostics)}");
temp.Subject = ReplacePlaceHolders(temp.Subject, placeHolders, MailParams.Placeholders);

View File

@@ -20,4 +20,14 @@ public record ReceiverQueryBase
/// Eindeutige Signatur des Empfängers
/// </summary>
public virtual string? Signature { get; set; }
/// <summary>
/// Checks whether any of the specified query criteria have a value.
/// </summary>
/// <remarks>
/// This property returns <c>true</c> if at least one of the fields
/// <see cref="Id"/>, <see cref="EmailAddress"/>, or <see cref="Signature"/> is not null.
/// <para>Usage example: The query can be executed only if at least one criterion is specified.</para>
/// </remarks>
public bool HasAnyCriteria => Id is not null || EmailAddress is not null || Signature is not null;
}

View File

@@ -91,6 +91,8 @@ public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeRece
{
private readonly IRepository<EnvelopeReceiver> _repo;
private readonly IRepository<Receiver> _rcvRepo;
private readonly IMapper _mapper;
/// <summary>
@@ -98,10 +100,11 @@ public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeRece
/// </summary>
/// <param name="envelopeReceiver"></param>
/// <param name="mapper"></param>
public ReadEnvelopeReceiverQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiver, IMapper mapper)
public ReadEnvelopeReceiverQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiver, IRepository<Receiver> rcvRepo, IMapper mapper)
{
_repo = envelopeReceiver;
_mapper = mapper;
_rcvRepo = rcvRepo;
}
/// <summary>
@@ -138,6 +141,14 @@ public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeRece
.Include(er => er.Receiver)
.ToListAsync(cancel);
if (request.Receiver.HasAnyCriteria && envRcvs.Any())
{
var receiver = await _rcvRepo.ReadOnly().Where(request.Receiver).FirstAsync(cancel);
foreach (var envRcv in envRcvs)
envRcv.Envelope?.Documents?.First().Elements.RemoveAll(s => s.ReceiverId != receiver.Id);
}
return _mapper.Map<List<EnvelopeReceiverDto>>(envRcvs);
}
}

View File

@@ -104,7 +104,7 @@ Public Class frmFinalizePDF
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
End Class

View File

@@ -1,5 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
#if NET
using System.Text.Json;
using System.Text.Json.Serialization;
#endif
namespace EnvelopeGenerator.Domain.Constants
{
@@ -8,18 +10,21 @@ namespace EnvelopeGenerator.Domain.Constants
#region Json Serializer Settings
public static class Json
{
public static readonly JsonSerializerSettings ForDiagnostics = new JsonSerializerSettings()
#if NET
public static readonly JsonSerializerOptions ForDiagnostics = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Include
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.Never
};
public static readonly JsonSerializerSettings ForAnnotations = new JsonSerializerSettings()
public static readonly JsonSerializerOptions ForAnnotations = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
};
#endif
}
#endregion
}

View File

@@ -0,0 +1,15 @@
namespace EnvelopeGenerator.Tests.Application;
public class DocSignedNotificationTest
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
Assert.Pass();
}
}

View File

@@ -1,4 +1,5 @@
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
@@ -33,7 +34,7 @@ public class DocumentController : ControllerBase
if(byteData is null || byteData.Length == 0)
{
_logger.LogError("Document byte data is null or empty for envelope-receiver entity:\n{envelopeKey}.",
JsonConvert.SerializeObject(envRcv, Format.Json.ForDiagnostics));
envRcv.ToJson(Format.Json.ForDiagnostics));
throw new NotFoundException("Document is empty.");
}

View File

@@ -1,15 +1,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Common.Notifications.DocSigned;
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
using EnvelopeGenerator.Application.Interfaces.Services;
using EnvelopeGenerator.Domain.Constants;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Web.Extensions;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Dynamic;
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Notifications.DocSigned;
using EnvelopeGenerator.Application.Common.Extensions;
namespace EnvelopeGenerator.Web.Controllers;

View File

@@ -5,7 +5,6 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PackageId>EnvelopeGenerator.Web</PackageId>
<Version>3.1.4</Version>
<Authors>Digital Data GmbH</Authors>
<Company>Digital Data GmbH</Company>
<Product>EnvelopeGenerator.Web</Product>
@@ -13,8 +12,9 @@
<PackageTags>digital data envelope generator web</PackageTags>
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
<AssemblyVersion>3.1.4</AssemblyVersion>
<FileVersion>3.1.4</FileVersion>
<Version>3.2.1</Version>
<AssemblyVersion>3.2.1</AssemblyVersion>
<FileVersion>3.2.1</FileVersion>
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
</PropertyGroup>