Removed MediatorGetOrContext.cs, eliminating the fluent API for handling null or empty MediatR responses with custom exceptions. Added two ExecuteAsync overloads to FinalizeDocumentJob: one for processing a single EnvelopeDto and another for processing all envelopes with the EnvelopeCompletelySigned status.
155 lines
5.9 KiB
C#
155 lines
5.9 KiB
C#
using DigitalData.Core.Abstraction.Application.Repository;
|
|
using EnvelopeGenerator.Application.Common.Dto;
|
|
using EnvelopeGenerator.Application.Configuration.Queries;
|
|
using EnvelopeGenerator.Application.Envelopes.Queries;
|
|
using EnvelopeGenerator.Domain.Constants;
|
|
using EnvelopeGenerator.Domain.Entities;
|
|
using EnvelopeGenerator.ServiceHost.Exceptions;
|
|
using EnvelopeGenerator.ServiceHost.Extensions;
|
|
using EnvelopeGenerator.ServiceHost.Jobs.FinalizeDocument;
|
|
using GdPicture14;
|
|
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Options;
|
|
using System.Data;
|
|
|
|
namespace EnvelopeGenerator.ServiceHost.Jobs;
|
|
|
|
[Obsolete("ActionService is a placeholder service added by copilot. Migrate the actual logic from CommonServices.Jobs")]
|
|
public class FinalizeDocumentJob(IOptions<WorkerOptions> options, ILogger<FinalizeDocumentJob> logger, TempFiles tempFiles, ActionService actionService, PDFBurner pdfBurner, PDFMerger pdfMerger, ReportCreator reportCreator, GdViewer? _gdViewer, LicenseManager licenseManager, IMediator mediator, IRepository<Envelope> envRepo, IRepository<Domain.Entities.DocumentStatus> docStatusRepo)
|
|
{
|
|
private readonly WorkerOptions _options = options.Value;
|
|
|
|
private ConfigDto? _config;
|
|
|
|
private const int CompleteWaitTime = 1;
|
|
private string _parentFolderUid = string.Empty;
|
|
|
|
private sealed class EnvelopeData
|
|
{
|
|
public int EnvelopeId { get; set; }
|
|
public string EnvelopeUuid { get; set; } = string.Empty;
|
|
public string DocumentPath { get; set; } = string.Empty;
|
|
public List<string> AnnotationData { get; set; } = new();
|
|
public byte[]? DocAsByte { get; set; }
|
|
}
|
|
|
|
public bool RethrowOnError { get; set; } = true;
|
|
|
|
public async Task ExecuteAsync(IEnumerable<EnvelopeDto> envelopes, CancellationToken cancel = default)
|
|
{
|
|
var gdPictureKey = _options.GdPictureLicenseKey;
|
|
tempFiles.Create();
|
|
var jobId = typeof(FinalizeDocumentJob).FullName;
|
|
|
|
_config = await mediator.Send(new ReadDefaultConfigQuery(), cancel);
|
|
|
|
foreach (var envelope in envelopes)
|
|
{
|
|
try
|
|
{
|
|
await Finalize(envelope, cancel);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogWarning(ex, "An unexpected exception was ignored while processing the envelope with ID [{id}].", envelope.Id);
|
|
|
|
if(RethrowOnError)
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Task ExecuteAsync(EnvelopeDto envelope, CancellationToken cancel = default) => ExecuteAsync([envelope], cancel);
|
|
|
|
public async Task ExecuteAsync(CancellationToken cancel = default)
|
|
{
|
|
var envelopes = await mediator.Send(new ReadEnvelopeQuery()
|
|
{
|
|
Status = new () { Include = [EnvelopeStatus.EnvelopeCompletelySigned] },
|
|
MinMinutesSinceLastChange = CompleteWaitTime,
|
|
}, cancel);
|
|
|
|
await ExecuteAsync(envelopes, cancel);
|
|
}
|
|
|
|
private async Task Finalize(EnvelopeDto envelope, CancellationToken cancel)
|
|
{
|
|
var annotations = await docStatusRepo.Where(s => s.EnvelopeId == envelope.Id).Select(s => s.Value).ToListAsync(cancel);
|
|
var burnedDocument = pdfBurner!.BurnAnnotsToPDF(envelope.Documents?.FirstOrDefault()?.ByteData!, annotations, envelope.Id)
|
|
?? throw new ApplicationException("Document could not be finalized");
|
|
|
|
actionService.CreateReport(envelope, cancel);
|
|
|
|
var report = await reportCreator!.CreateReportAsync(envelope, cancel);
|
|
|
|
var mergedDocument = pdfMerger!.MergeDocuments(burnedDocument, report);
|
|
|
|
var outputDirectoryPath = Path.Combine(_config!.ExportPath, _parentFolderUid);
|
|
|
|
if (!Directory.Exists(outputDirectoryPath))
|
|
Directory.CreateDirectory(outputDirectoryPath);
|
|
|
|
var outputFilePath = Path.Combine(outputDirectoryPath, $"{envelope.Uuid}.pdf");
|
|
|
|
try
|
|
{
|
|
File.WriteAllBytes(outputFilePath, mergedDocument);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new ExportDocumentException("Could not export final document to disk. Envelope Id is " + envelope.Id, ex);
|
|
}
|
|
|
|
var outputFile = await File.ReadAllBytesAsync(outputFilePath, cancel);
|
|
await envRepo.UpdateAsync(e => e.DocResult = outputFile, e => e.Id == envelope.Id, cancel);
|
|
|
|
SendFinalEmails(envelope);
|
|
|
|
actionService.FinalizeEnvelope(envelope, cancel);
|
|
}
|
|
|
|
private bool SendFinalEmails(EnvelopeDto envelope)
|
|
{
|
|
var mailToCreator = (FinalEmailType)(envelope.FinalEmailToCreator ?? 0);
|
|
var mailToReceivers = (FinalEmailType)(envelope.FinalEmailToReceivers ?? 0);
|
|
|
|
if (mailToCreator != FinalEmailType.No)
|
|
SendFinalEmailToCreator(envelope, mailToCreator);
|
|
else
|
|
logger?.LogWarning("No SendFinalEmailToCreator - oMailToCreator [{mailToCreator}] <> [{noFinalEmailType}] ", mailToCreator, FinalEmailType.No);
|
|
|
|
if (mailToReceivers != FinalEmailType.No)
|
|
{
|
|
SendFinalEmailToReceivers(envelope, mailToReceivers);
|
|
}
|
|
else
|
|
{
|
|
logger?.LogWarning("No SendFinalEmailToReceivers - oMailToCreator [{mailToReceivers}] <> [{noFinalEmailType}] ", mailToReceivers, FinalEmailType.No);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private bool SendFinalEmailToCreator(EnvelopeDto envelope, FinalEmailType mailToCreator)
|
|
{
|
|
if (actionService.CompleteEnvelope(envelope) == false)
|
|
{
|
|
logger?.LogError(new Exception("CompleteEnvelope failed"), "Envelope could not be completed for receiver [{email}]", envelope.User?.Email);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private bool SendFinalEmailToReceivers(EnvelopeDto envelope, FinalEmailType mailToReceivers)
|
|
{
|
|
foreach (var receiver in envelope.EnvelopeReceivers ?? [])
|
|
{
|
|
if (!actionService.CompleteEnvelope(envelope, receiver.Receiver!))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
} |