feat(CreateAnnotationCommand): implement CreateAnnotationCommand and handler logic

Added full implementation for CreateAnnotationCommand and its handler:
- Introduced `PSPDFKitInstantJSON` property to the command
- Injected repositories for `Signature` and `Annotation`
- Implemented query filtering for Envelope and Receiver
- Added annotation creation from parsed PSPDFKit JSON
- Created helper method `ParsePSPDFKitInstantJSON` for JSON parsing
This commit is contained in:
2025-10-13 15:28:38 +02:00
parent faa37e0dcd
commit f56928f44f
9 changed files with 95 additions and 16 deletions

View File

@@ -1,18 +1,50 @@
using EnvelopeGenerator.Application.Common.Query; using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Common.Query;
using EnvelopeGenerator.Domain.Entities;
using MediatR; using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.Annotations.Commands; namespace EnvelopeGenerator.Application.Annotations.Commands;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public record CreateAnnotationCommand : EnvelopeReceiverQueryBase, IRequest; public record CreateAnnotationCommand : EnvelopeReceiverQueryBase, IRequest
{
/// <summary>
///
/// </summary>
[JsonIgnore]
public string PSPDFKitInstantJSON { get; set; } = null!;
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CreateAnnotationCommandHandler : IRequestHandler<CreateAnnotationCommand> public class CreateAnnotationCommandHandler : IRequestHandler<CreateAnnotationCommand>
{ {
/// <summary>
///
/// </summary>
private readonly IRepository<Signature> _signRepo;
/// <summary>
///
/// </summary>
private readonly IRepository<Annotation> _annotRepo;
/// <summary>
///
/// </summary>
/// <param name="signRepo"></param>
public CreateAnnotationCommandHandler(IRepository<Signature> signRepo, IRepository<Annotation> annotRepo)
{
_signRepo = signRepo;
_annotRepo = annotRepo;
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -20,8 +52,50 @@ public class CreateAnnotationCommandHandler : IRequestHandler<CreateAnnotationCo
/// <param name="cancel"></param> /// <param name="cancel"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public Task Handle(CreateAnnotationCommand request, CancellationToken cancel) public async Task Handle(CreateAnnotationCommand request, CancellationToken cancel)
{ {
throw new NotImplementedException(); var query = _signRepo.Query;
#region Envelope Query
if (request.Envelope.Id is int envelopeId)
query = query.Where(annot => annot.Document.EnvelopeId == envelopeId);
if (request.Envelope.Uuid is string envelopeUuid)
query = query.Where(annot => annot.Document.Envelope!.Uuid == envelopeUuid);
#endregion
// Receiver Query
query = query.Where(request.Receiver);
var elements = await query.ToListAsync(cancel);
foreach (var element in elements)
{
var annots = ParsePSPDFKitInstantJSON(request.PSPDFKitInstantJSON, element.Id)
.Select(annot => new Annotation()
{
ElementId = element.Id,
Name = annot.Key,
Value = annot.Value,
AddedWhen = DateTime.UtcNow
});
await _annotRepo.CreateAsync(annots, cancel);
}
}
/// <summary>
///
/// </summary>
/// <param name="json"></param>
/// <param name="elementId"></param>
/// <returns></returns>
public static Dictionary<string, string> ParsePSPDFKitInstantJSON(string json, int elementId)
{
Dictionary<string, string> annots = new();
// parse json here
return annots;
} }
} }

View File

@@ -14,7 +14,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.5" /> <PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.6" />
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" /> <PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />
<PackageReference Include="DigitalData.Core.Client" Version="2.1.0" /> <PackageReference Include="DigitalData.Core.Client" Version="2.1.0" />
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" /> <PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />

View File

@@ -70,8 +70,8 @@
<Reference Include="DigitalData.Controls.DocumentViewer, Version=1.9.8.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DigitalData.Controls.DocumentViewer, Version=1.9.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Controls.DocumentViewer.1.9.8\lib\net462\DigitalData.Controls.DocumentViewer.dll</HintPath> <HintPath>..\packages\DigitalData.Controls.DocumentViewer.1.9.8\lib\net462\DigitalData.Controls.DocumentViewer.dll</HintPath>
</Reference> </Reference>
<Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.5.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.5\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath> <HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.6\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath>
</Reference> </Reference>
<Reference Include="DigitalData.Core.Abstractions, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DigitalData.Core.Abstractions, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstractions.4.1.1\lib\net462\DigitalData.Core.Abstractions.dll</HintPath> <HintPath>..\packages\DigitalData.Core.Abstractions.4.1.1\lib\net462\DigitalData.Core.Abstractions.dll</HintPath>

View File

@@ -3,7 +3,7 @@
<package id="AutoMapper" version="10.1.1" targetFramework="net462" /> <package id="AutoMapper" version="10.1.1" targetFramework="net462" />
<package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" /> <package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" />
<package id="DigitalData.Controls.DocumentViewer" version="1.9.8" targetFramework="net462" /> <package id="DigitalData.Controls.DocumentViewer" version="1.9.8" targetFramework="net462" />
<package id="DigitalData.Core.Abstraction.Application" version="1.3.5" targetFramework="net462" /> <package id="DigitalData.Core.Abstraction.Application" version="1.3.6" targetFramework="net462" />
<package id="DigitalData.Core.Abstractions" version="4.1.1" targetFramework="net462" /> <package id="DigitalData.Core.Abstractions" version="4.1.1" targetFramework="net462" />
<package id="DigitalData.Modules.Base" version="1.3.8" targetFramework="net462" /> <package id="DigitalData.Modules.Base" version="1.3.8" targetFramework="net462" />
<package id="DigitalData.Modules.Config" version="1.3.0" targetFramework="net462" /> <package id="DigitalData.Modules.Config" version="1.3.0" targetFramework="net462" />

View File

@@ -72,8 +72,8 @@
<Reference Include="DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" /> <Reference Include="DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.XtraGauges.v21.2.Core, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" /> <Reference Include="DevExpress.XtraGauges.v21.2.Core, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraReports.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" /> <Reference Include="DevExpress.XtraReports.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.5.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.5\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath> <HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.6\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath>
</Reference> </Reference>
<Reference Include="DigitalData.Core.Abstractions, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DigitalData.Core.Abstractions, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstractions.4.1.1\lib\net462\DigitalData.Core.Abstractions.dll</HintPath> <HintPath>..\packages\DigitalData.Core.Abstractions.4.1.1\lib\net462\DigitalData.Core.Abstractions.dll</HintPath>

View File

@@ -2,7 +2,7 @@
<packages> <packages>
<package id="AutoMapper" version="10.1.1" targetFramework="net462" /> <package id="AutoMapper" version="10.1.1" targetFramework="net462" />
<package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" /> <package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" />
<package id="DigitalData.Core.Abstraction.Application" version="1.3.5" targetFramework="net462" /> <package id="DigitalData.Core.Abstraction.Application" version="1.3.6" targetFramework="net462" />
<package id="DigitalData.Core.Abstractions" version="4.1.1" targetFramework="net462" /> <package id="DigitalData.Core.Abstractions" version="4.1.1" targetFramework="net462" />
<package id="DigitalData.Modules.Base" version="1.3.8" targetFramework="net462" /> <package id="DigitalData.Modules.Base" version="1.3.8" targetFramework="net462" />
<package id="DigitalData.Modules.Config" version="1.3.0" targetFramework="net462" /> <package id="DigitalData.Modules.Config" version="1.3.0" targetFramework="net462" />

View File

@@ -15,7 +15,7 @@ namespace EnvelopeGenerator.Domain.Entities
#endif #endif
[Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT", Schema = "dbo")] [Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT", Schema = "dbo")]
public class Signature : ISignature public class Signature : ISignature, IHasReceiver
{ {
public Signature() public Signature()
{ {
@@ -108,7 +108,12 @@ public class Signature : ISignature
public virtual Document Document { get; set; } public virtual Document Document { get; set; }
[ForeignKey("ReceiverId")] [ForeignKey("ReceiverId")]
public virtual Receiver Receiver { get; set; } public virtual Receiver
#if NET
?
#endif
Receiver
{ get; set; }
public virtual IEnumerable<Annotation> public virtual IEnumerable<Annotation>
#if NET #if NET

View File

@@ -22,8 +22,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" /> <PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.5" /> <PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.6" />
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.4.3" /> <PackageReference Include="DigitalData.Core.Infrastructure" Version="2.4.4" />
<PackageReference Include="QuestPDF" Version="2025.7.1" /> <PackageReference Include="QuestPDF" Version="2025.7.1" />
</ItemGroup> </ItemGroup>

View File

@@ -20,7 +20,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Bogus" Version="35.6.3" /> <PackageReference Include="Bogus" Version="35.6.3" />
<PackageReference Include="coverlet.collector" Version="6.0.0" /> <PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.5" /> <PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.6" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="4.1.1" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="4.1.1" />
<PackageReference Include="DigitalData.Core.API" Version="2.2.1" /> <PackageReference Include="DigitalData.Core.API" Version="2.2.1" />
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" /> <PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />