Files
EnvelopeGenerator/EnvelopeGenerator.ServiceHost/Jobs/FinalizeDocumentJob.cs
TekH 737774f077 Remove PDF annotation and envelope data methods
Removed BurnAnnotationsToPdf, GetEnvelopeData, and GetAnnotationData from FinalizeDocumentJob. These methods handled document reading, annotation retrieval, and PDF annotation burning. This change reflects a refactor or shift in document processing responsibilities.
2026-03-09 15:34:58 +01:00

215 lines
8.1 KiB
C#

using System.Data;
using DigitalData.Modules.Database;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
using EnvelopeGenerator.ServiceHost.Exceptions;
using EnvelopeGenerator.ServiceHost.Jobs.FinalizeDocument;
using GdPicture14;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using EnvelopeGenerator.ServiceHost.Extensions;
using MediatR;
using EnvelopeGenerator.Application.Configuration.Queries;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Envelopes.Queries;
using DigitalData.Core.Abstraction.Application.Repository;
using Microsoft.EntityFrameworkCore;
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, IConfiguration config, ILogger<FinalizeDocumentJob> logger, TempFiles tempFiles, ActionService actionService, PDFBurner pdfBurner, PDFMerger pdfMerger, ReportCreator reportCreator, ReportModel _reportModel, MSSQLServer _database, 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(CancellationToken cancel = default)
{
var gdPictureKey = _options.GdPictureLicenseKey;
tempFiles.Create();
var jobId = typeof(FinalizeDocumentJob).FullName;
_config = await mediator.Send(new ReadDefaultConfigQuery(), cancel);
var envelopes = await envRepo
.Where(e => e.Status == EnvelopeStatus.EnvelopeCompletelySigned
&& e.ChangedWhen.HasValue
&& EF.Functions.DateDiffMinute(e.ChangedWhen.Value, DateTime.Now) >= CompleteWaitTime)
.OrderBy(e => e.Id)
.ToListAsync(cancel);
if (envelopes.Count > 0)
logger.LogInformation("Found [{count}] completed envelopes.", envelopes.Count);
foreach (var envelope in envelopes)
{
try
{
await Finalize(envelope, cancel);
}
catch (Exception ex)
{
logger.LogError(ex, "Unhandled exception while working envelope [{id}]", envelope.Id);
if(RethrowOnError)
throw;
}
logger.LogInformation("Envelope [{id}] finalized!", envelope.Id);
}
}
private async Task Finalize(Envelope envelope, CancellationToken cancel)
{
var annotations = await docStatusRepo.Where(s => s.EnvelopeId == envelope.Id).Select(s => s.Value).ToListAsync(cancel);
var burnedDocument = pdfBurner!.BurnAnnotsToPDF(envelope.DefaultDocument.ByteData!, annotations, envelope.Id);
if (burnedDocument is null)
{
logger.LogWarning("Document could not be finalized!");
throw new ApplicationException("Document could not be finalized");
}
if (actionService?.CreateReport(envelope) == false)
{
logger.LogWarning("Document Report could not be created!");
throw new ApplicationException("Document Report could not be created");
}
var report = reportCreator!.CreateReport(envelope);
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");
logger.LogInformation("Output path is [{outputFilePath}]", outputFilePath);
try
{
File.WriteAllBytes(outputFilePath, mergedDocument);
}
catch (Exception ex)
{
logger.LogWarning("Could not export final document to disk!");
throw new ExportDocumentException("Could not export final document to disk!", ex);
}
UpdateFileDb(outputFilePath, envelope.Id);
if (!SendFinalEmails(envelope))
throw new ApplicationException("Final emails could not be sent!");
logger.LogInformation("Report-mails successfully sent!");
if (actionService?.FinalizeEnvelope(envelope) == false)
{
logger.LogWarning("Envelope could not be finalized!");
throw new ApplicationException("Envelope could not be finalized");
}
}
private void UpdateFileDb(string filePath, long envelopeId)
{
try
{
var imageData = ReadFile(filePath);
if (imageData is null)
{
return;
}
var query = $"UPDATE TBSIG_ENVELOPE SET DOC_RESULT = @ImageData WHERE GUID = {envelopeId}";
using var command = new SqlCommand(query, _database!.GetConnection);
command.Parameters.Add(new SqlParameter("@ImageData", imageData));
command.ExecuteNonQuery();
}
catch (Exception ex)
{
logger?.LogError(ex);
}
}
private static byte[]? ReadFile(string path)
{
var fileInfo = new FileInfo(path);
var numBytes = fileInfo.Length;
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
using var reader = new BinaryReader(stream);
return reader.ReadBytes((int)numBytes);
}
private bool SendFinalEmails(Envelope 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(Envelope envelope, FinalEmailType mailToCreator)
{
var includeAttachment = SendFinalEmailWithAttachment(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(Envelope envelope, FinalEmailType mailToReceivers)
{
var includeAttachment = SendFinalEmailWithAttachment(mailToReceivers);
foreach (var receiver in envelope.EnvelopeReceivers ?? Enumerable.Empty<EnvelopeReceiver>())
{
if (actionService?.CompleteEnvelope(envelope, receiver.Receiver) == false)
{
logger?.LogError(new Exception("CompleteEnvelope failed"), "Envelope could not be completed for receiver [{email}]", receiver.Receiver?.EmailAddress);
return false;
}
}
return true;
}
private static bool SendFinalEmailWithAttachment(FinalEmailType type)
{
return type == FinalEmailType.YesWithAttachment;
}
}