Compare commits
10 Commits
35b7b1a080
...
965838513f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
965838513f | ||
|
|
9c4766518e | ||
|
|
292b6b2ccf | ||
|
|
6f9b5d4b13 | ||
|
|
8459706c45 | ||
|
|
972c63388e | ||
|
|
cde9ed06a1 | ||
|
|
d94f885e92 | ||
|
|
028785a8c9 | ||
|
|
e6285f13f7 |
@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>EnvelopeGenerator.Application.VB</RootNamespace>
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,44 @@
|
||||
namespace EnvelopeGenerator.Application.Common.Dto;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record EnvelopeReportDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
// --- HEAD ---
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string HeadUuid { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string EnvelopeTitle { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string HeadMessage { get; set; } = null!;
|
||||
|
||||
// --- POSITIONS ---
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ItemStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime? ItemDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ItemUserReference { get; set; } = null!;
|
||||
}
|
||||
@ -37,6 +37,7 @@ public class MappingProfile : Profile
|
||||
CreateMap<Domain.Entities.EnvelopeReceiverReadOnly, EnvelopeReceiverReadOnlyDto>();
|
||||
CreateMap<ElementAnnotation, AnnotationDto>();
|
||||
CreateMap<ThirdPartyModule, ThirdPartyModuleDto>();
|
||||
CreateMap<EnvelopeReport, EnvelopeReportDto>();
|
||||
|
||||
// DTO to Entity mappings
|
||||
CreateMap<ConfigDto, Config>();
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReports;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record ReadEnvelopeReportQuery(int EnvelopeId) : IRequest<IEnumerable<EnvelopeReport>>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
public bool ThrowIfNotFound { get; init; } = true;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class ReadEnvelopeReportQueryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="throwIfNotFound"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<IEnumerable<EnvelopeReport>> ReadEnvelopeReportAsync(this ISender sender, int envelopeId, bool throwIfNotFound = true, CancellationToken cancel = default)
|
||||
=> sender.Send(new ReadEnvelopeReportQuery(envelopeId)
|
||||
{
|
||||
ThrowIfNotFound = throwIfNotFound
|
||||
}, cancel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadEnvelopeReportQueryHandler : IRequestHandler<ReadEnvelopeReportQuery, IEnumerable<EnvelopeReport>>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private readonly IRepository<EnvelopeReport> _repo;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repo"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public ReadEnvelopeReportQueryHandler(IRepository<EnvelopeReport> repo, IMapper mapper)
|
||||
{
|
||||
_repo = repo;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<EnvelopeReport>> Handle(ReadEnvelopeReportQuery request, CancellationToken cancel = default)
|
||||
{
|
||||
var reports = await _repo.Where(r => r.EnvelopeId == request.EnvelopeId).ToListAsync(cancel);
|
||||
var reportDtos = _mapper.Map<IEnumerable<EnvelopeReport>>(reports);
|
||||
|
||||
if(request.ThrowIfNotFound && !reportDtos.Any())
|
||||
throw new NotFoundException($"EnvelopeReport with EnvelopeId '{request.EnvelopeId}' was not found.");
|
||||
|
||||
return reportDtos;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,10 @@
|
||||
using MediatR;
|
||||
using EnvelopeGenerator.Application.Histories.Commands;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Application.EnvelopeReports;
|
||||
using EnvelopeGenerator.Application.Exceptions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Pdf.Behaviors;
|
||||
|
||||
@ -11,13 +15,17 @@ public class AddReportBehavior : IPipelineBehavior<BurnPdfCommand, byte[]>
|
||||
{
|
||||
private readonly ISender _sender;
|
||||
|
||||
private readonly ILogger<AddReportBehavior> _logger;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
public AddReportBehavior(ISender sender)
|
||||
/// <param name="logger"></param>
|
||||
public AddReportBehavior(ISender sender, ILogger<AddReportBehavior> logger)
|
||||
{
|
||||
_sender = sender;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -32,13 +40,68 @@ public class AddReportBehavior : IPipelineBehavior<BurnPdfCommand, byte[]>
|
||||
var docResult = await next(cancel);
|
||||
var base64 = Convert.ToBase64String(docResult);
|
||||
|
||||
await _sender.Send(new CreateHistoryCommand()
|
||||
{
|
||||
EnvelopeId = request.EnvelopeId,
|
||||
UserReference = "System",
|
||||
Status = EnvelopeStatus.EnvelopeReportCreated,
|
||||
}, cancel);
|
||||
if (!request.Debug)
|
||||
await _sender.Send(new CreateHistoryCommand()
|
||||
{
|
||||
EnvelopeId = request.EnvelopeId,
|
||||
UserReference = "System",
|
||||
Status = EnvelopeStatus.EnvelopeReportCreated,
|
||||
}, cancel);
|
||||
|
||||
docResult = await CreateReport(request.Envelope!, cancel);
|
||||
|
||||
return docResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelope"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="CreateReportException"></exception>
|
||||
public async Task<byte[]> CreateReport(Envelope envelope, CancellationToken cancel)
|
||||
{
|
||||
var oItems = await _sender.ReadEnvelopeReportAsync(envelope.Id, cancel: cancel);
|
||||
|
||||
if (!oItems.Any())
|
||||
{
|
||||
throw new CreateReportException("No report data found!");
|
||||
}
|
||||
|
||||
var oBuffer = DoCreateReport(oItems);
|
||||
|
||||
return oBuffer;
|
||||
}
|
||||
|
||||
private byte[] DoCreateReport(IEnumerable<EnvelopeReport> oItems)
|
||||
{
|
||||
var oSource = new ReportSource { Items = oItems };
|
||||
var oReport = new rptEnvelopeHistory
|
||||
{
|
||||
DataSource = oSource,
|
||||
DataMember = "Items"
|
||||
};
|
||||
|
||||
// Creating report in memory
|
||||
oReport.CreateDocument();
|
||||
|
||||
// Exporting report to stream
|
||||
using var oStream = new MemoryStream();
|
||||
oReport.ExportToPdf(oStream);
|
||||
|
||||
// Writing report to buffer
|
||||
return oStream.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReportSource
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required IEnumerable<EnvelopeReport> Items { get; init; }
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ using EnvelopeGenerator.Domain.Entities;
|
||||
using GdPicture14;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
@ -18,7 +19,12 @@ namespace EnvelopeGenerator.Application.Pdf;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record BurnPdfCommand(int? EnvelopeId = null, string? EnvelopeUuid = null) : IRequest<byte[]>;
|
||||
public record BurnPdfCommand(int? EnvelopeId = null, string? EnvelopeUuid = null) : IRequest<byte[]>
|
||||
{
|
||||
internal bool Debug { get; set; }
|
||||
|
||||
internal Envelope? Envelope { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -32,7 +38,7 @@ public static class BurnPdfCommandExtensions
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<byte[]> BurnPdf(this ISender sender, int envelopeId, CancellationToken cancel = default)
|
||||
public static Task<byte[]> BurnPdf(this ISender sender, int envelopeId, CancellationToken cancel = default)
|
||||
=> sender.Send(new BurnPdfCommand(EnvelopeId: envelopeId), cancel);
|
||||
|
||||
/// <summary>
|
||||
@ -61,6 +67,8 @@ public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand, byte[]>
|
||||
|
||||
private readonly IRepository<Domain.Entities.DocumentStatus> _docStatusRepo;
|
||||
|
||||
private readonly IConfiguration _config;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@ -69,13 +77,15 @@ public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand, byte[]>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="envRepo"></param>
|
||||
/// <param name="docStatusRepo"></param>
|
||||
public BurnPdfCommandHandler(IOptions<PDFBurnerParams> pdfBurnerParams, AnnotationManager manager, ILogger<BurnPdfCommandHandler> logger, IRepository<Envelope> envRepo, IRepository<Domain.Entities.DocumentStatus> docStatusRepo)
|
||||
/// <param name="config"></param>
|
||||
public BurnPdfCommandHandler(IOptions<PDFBurnerParams> pdfBurnerParams, AnnotationManager manager, ILogger<BurnPdfCommandHandler> logger, IRepository<Envelope> envRepo, IRepository<Domain.Entities.DocumentStatus> docStatusRepo, IConfiguration config)
|
||||
{
|
||||
_options = pdfBurnerParams.Value;
|
||||
_manager = manager;
|
||||
_docStatusRepo = docStatusRepo;
|
||||
_logger = logger;
|
||||
_envRepo = envRepo;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
|
||||
@ -88,18 +98,19 @@ public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand, byte[]>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public async Task<byte[]> Handle(BurnPdfCommand request, CancellationToken cancel)
|
||||
{
|
||||
var envQuery =
|
||||
request.EnvelopeId is not null ? _envRepo.Where(env => env.Id == request.EnvelopeId) :
|
||||
request.Debug = _config.GetValue<bool>("Debug");
|
||||
var envQuery =
|
||||
request.EnvelopeId is not null ? _envRepo.Where(env => env.Id == request.EnvelopeId) :
|
||||
request.EnvelopeUuid is not null ? _envRepo.Where(env => env.Uuid == request.EnvelopeUuid) :
|
||||
throw new BadRequestException("Request validation failed: Either Envelope Id or Envelope Uuid must be provided.");
|
||||
|
||||
var envelope = await envQuery
|
||||
request.Envelope = await envQuery
|
||||
.Include(env => env.Documents!).ThenInclude(doc => doc.Elements!).ThenInclude(element => element.Annotations)
|
||||
.FirstOrDefaultAsync(cancel)
|
||||
?? throw new BadRequestException($"Envelope could not be found. Request details:\n" +
|
||||
request.ToJson(Format.Json.ForDiagnostics));
|
||||
|
||||
var doc = envelope.Documents?.FirstOrDefault()
|
||||
var doc = request.Envelope.Documents?.FirstOrDefault()
|
||||
?? throw new NotFoundException($"Document could not be located within the specified envelope. Request details:\n" +
|
||||
request.ToJson(Format.Json.ForDiagnostics));
|
||||
|
||||
@ -110,7 +121,7 @@ public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand, byte[]>
|
||||
return doc.Elements?.SelectMany(e => e.Annotations ?? Enumerable.Empty<ElementAnnotation>()).Where(annot => annot is not null).Any() ?? false
|
||||
? BurnElementAnnotsToPDF(doc.ByteData, doc.Elements)
|
||||
: BurnInstantJSONAnnotsToPDF(doc.ByteData, await _docStatusRepo
|
||||
.Where(status => status.EnvelopeId == envelope.Id)
|
||||
.Where(status => status.EnvelopeId == request.Envelope.Id)
|
||||
.Select(status => status.Value)
|
||||
.ToListAsync(cancel));
|
||||
}
|
||||
|
||||
36
EnvelopeGenerator.Domain/Entities/EnvelopeReport.cs
Normal file
36
EnvelopeGenerator.Domain/Entities/EnvelopeReport.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
{
|
||||
[Table("VWSIG_ENVELOPE_REPORT", Schema = "dbo")]
|
||||
public class EnvelopeReport
|
||||
{
|
||||
[Key]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
// --- HEAD ---
|
||||
[Column("HEAD_UUID")]
|
||||
public string HeadUuid { get; set; }
|
||||
|
||||
[Column("HEAD_TITLE")]
|
||||
public string EnvelopeTitle { get; set; } = string.Empty;
|
||||
|
||||
[Column("HEAD_MESSAGE")]
|
||||
public string HeadMessage { get; set; }
|
||||
|
||||
// --- POSITIONS ---
|
||||
[Column("POS_STATUS")]
|
||||
public int ItemStatus { get; set; }
|
||||
|
||||
[Column("POS_WHEN")]
|
||||
public DateTime? ItemDate { get; set; }
|
||||
|
||||
[Column("POS_WHO")]
|
||||
public string ItemUserReference { get; set; }
|
||||
}
|
||||
}
|
||||
@ -4,5 +4,6 @@
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Debug": true
|
||||
}
|
||||
@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Dependenc
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Finalizer", "EnvelopeGenerator.Finalizer\EnvelopeGenerator.Finalizer.csproj", "{C4970E6C-DB2E-48C5-B3C5-2AF589405ED9}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EnvelopeGenerator.Application.VB", "EnvelopeGenerator.Application.VB\EnvelopeGenerator.Application.VB.vbproj", "{9E123E6B-2A94-47C7-8BA1-ECDA5E1422C6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -103,6 +105,10 @@ Global
|
||||
{C4970E6C-DB2E-48C5-B3C5-2AF589405ED9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C4970E6C-DB2E-48C5-B3C5-2AF589405ED9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4970E6C-DB2E-48C5-B3C5-2AF589405ED9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9E123E6B-2A94-47C7-8BA1-ECDA5E1422C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9E123E6B-2A94-47C7-8BA1-ECDA5E1422C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9E123E6B-2A94-47C7-8BA1-ECDA5E1422C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9E123E6B-2A94-47C7-8BA1-ECDA5E1422C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -125,6 +131,7 @@ Global
|
||||
{211619F5-AE25-4BA5-A552-BACAFE0632D3} = {9943209E-1744-4944-B1BA-4F87FC1A0EEB}
|
||||
{B97DE7DD-3190-4A84-85E9-E57AD735BE61} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{C4970E6C-DB2E-48C5-B3C5-2AF589405ED9} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{9E123E6B-2A94-47C7-8BA1-ECDA5E1422C6} = {9943209E-1744-4944-B1BA-4F87FC1A0EEB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {73E60370-756D-45AD-A19A-C40A02DACCC7}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user