feat: implement set-based invoice payment calculations and enhance email logging configuration
Playwright Tests / test (push) Canceled after 0s
Playwright Tests / test (push) Canceled after 0s
This commit is contained in:
@@ -74,8 +74,8 @@ public class ProcessWebComService : IComService
|
||||
FuchsTelemetry.EmailsFailed.Add(1, new KeyValuePair<string, object?>("reason", "invalid-email"));
|
||||
act?.SetStatus(ActivityStatusCode.Error, "invalid-email");
|
||||
// Every attempt is audit-logged, including this early rejection (previously it returned unlogged).
|
||||
await WriteAuditLogAsync(reference, "", "", default, false,
|
||||
[$"Invalid recipient email address: '{email}'"]);
|
||||
await WriteAuditLogAsync(reference, "", BuildAuditConfig(subject, email, name, cc, attachments?.Keys),
|
||||
default, false, [$"Invalid recipient email address: '{email}'"]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,8 @@ public class ProcessWebComService : IComService
|
||||
_logger.LogInformation(
|
||||
"[ComService DISABLED] Would send email ref={Reference} subject='{Subject}' to={Email}",
|
||||
reference, subject, email);
|
||||
await WriteAuditLogAsync(reference, "", "", default, false, ["Service disabled – email not sent"]);
|
||||
await WriteAuditLogAsync(reference, "", BuildAuditConfig(subject, email, name, cc, attachments?.Keys),
|
||||
default, false, ["Service disabled – email not sent"]);
|
||||
FuchsTelemetry.EmailsFailed.Add(1, new KeyValuePair<string, object?>("reason", "disabled"));
|
||||
return false;
|
||||
}
|
||||
@@ -153,7 +154,8 @@ public class ProcessWebComService : IComService
|
||||
_logger.LogInformation("SendEmailAsync ref={Reference} success={Success} in {Ms} ms",
|
||||
reference, success, sw.ElapsedMilliseconds);
|
||||
|
||||
await WriteAuditLogAsync(reference, messageId, "", success ? DateTime.UtcNow : default, success, errors);
|
||||
await WriteAuditLogAsync(reference, messageId, BuildAuditConfig(subject, email, name, cc, attachments?.Keys),
|
||||
success ? DateTime.UtcNow : default, success, errors);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -308,6 +310,30 @@ public class ProcessWebComService : IComService
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialises the audit <c>config</c> stored in <c>fds__emaillog.config</c>: who the mail went
|
||||
/// to, its subject and the attachment <em>names</em> — never the body or attachment bytes.
|
||||
/// The shape (<c>subject</c>/<c>from</c>/<c>to[]</c>/<c>cc[]</c>/<c>bcc[]</c>/<c>attachments[]</c>,
|
||||
/// addresses as <c>"Name" <email></c>) is the one the legacy mailer wrote and that
|
||||
/// <c>[dbo].[fds_wgd_lastEmails]</c> reads back with <c>OPENJSON</c>; an empty string here
|
||||
/// made that dashboard widget fail for every row the new service logged.
|
||||
/// Pure so the contract can be unit-tested without a database.
|
||||
/// </summary>
|
||||
internal static string BuildAuditConfig(string subject, string email, string? name, string? cc,
|
||||
IEnumerable<string>? attachmentNames) =>
|
||||
JsonConvert.SerializeObject(new
|
||||
{
|
||||
subject = subject ?? "",
|
||||
from = "",
|
||||
to = new[] { FormatAddress(email, name) },
|
||||
cc = string.IsNullOrWhiteSpace(cc) ? Array.Empty<string>() : new[] { cc.Trim() },
|
||||
bcc = Array.Empty<string>(),
|
||||
attachments = (attachmentNames ?? []).ToArray()
|
||||
});
|
||||
|
||||
private static string FormatAddress(string email, string? name) =>
|
||||
string.IsNullOrWhiteSpace(name) ? (email ?? "") : $"\"{name.Trim()}\" <{email}>";
|
||||
|
||||
/// <summary>
|
||||
/// Builds the parameter list for <c>[dbo].[fds__logEmail]</c>. <c>fds__emaillog</c> declares
|
||||
/// <c>config</c> and <c>DateSent</c> as NOT NULL, so neither may be sent as NULL:
|
||||
|
||||
Reference in New Issue
Block a user