Files
EnvelopeGenerator/EnvelopeGenerator.ServiceHost/Jobs/FinalizeDocumentJob.cs
TekH bc07af9622 Refactor jobs to use EnvelopeDto/ReceiverDto instead of entities
Refactored ActionService and FinalizeDocumentJob to use EnvelopeDto and ReceiverDto in place of domain entities. Updated method signatures, internal logic, and envelope receiver handling to operate on DTOs. Improved logging, removed obsolete code, and added necessary using statements for DTO namespaces. Also updated document retrieval logic and removed null-conditional operator from actionService calls.
2026-04-01 16:18:17 +02:00

153 lines
5.8 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 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;
}
}