Persist invoice validation reports as JSON blobs

This commit is contained in:
admin committed 2026-09-07 16:26:02 +02:00
1 parent 2075bcb2c3
commit bb9b20cc25
3 files changed
+93 -38

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
namespace ImportAssist.Core;
public sealed record InvoiceCheckResult(
int LineNumber,
string InvoiceId,
bool IsValid,
IReadOnlyList<string> Errors);
public sealed record ImportReport(
string SourceBlob,
DateTimeOffset CheckedAtUtc,
string Status,
IReadOnlyList<InvoiceCheckResult> Rows,
IReadOnlyList<string> FileErrors)
{
public int TotalCount => Rows.Count;
public int ValidCount => Rows.Count(row => row.IsValid);
public int InvalidCount => TotalCount - ValidCount;
}
@@ -1,3 +1,4 @@
using System.Text.Json;
using ImportAssist.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
@@ -7,60 +8,69 @@ namespace ImportAssist_Functions;
public sealed class InvoiceBlobTrigger(
ILogger<InvoiceBlobTrigger> logger)
{
private static readonly JsonSerializerOptions JsonOptions =
new(JsonSerializerDefaults.Web)
{
WriteIndented = true
};
[Function("InvoiceBlobTrigger")]
public void Run(
[BlobOutput(
"results/{name}.json",
Connection = "AzureWebJobsStorage")]
public string Run(
[BlobTrigger(
"imports/{name}",
Connection = "AzureWebJobsStorage")]
string content,
string name)
{
IReadOnlyList<InvoiceRow> rows;
ImportReport report;
try
{
rows = InvoiceCsvParser.Parse(content);
var rows = InvoiceCsvParser.Parse(content);
var results = new List<InvoiceCheckResult>();
for (var index = 0; index < rows.Count; index++)
{
var row = rows[index];
var errors = InvoiceValidator.Validate(row);
results.Add(new InvoiceCheckResult(
LineNumber: index + 2,
InvoiceId: row.InvoiceId,
IsValid: errors.Count == 0,
Errors: errors));
}
report = new ImportReport(
SourceBlob: name,
CheckedAtUtc: DateTimeOffset.UtcNow,
Status: "Completed",
Rows: results,
FileErrors: []);
}
catch (FormatException exception)
{
logger.LogWarning(
"Datei {BlobName} wegen CSV-Formatfehler abgewiesen: {Reason}",
name,
exception.Message);
return;
}
var validCount = 0;
foreach (var row in rows)
{
var errors = InvoiceValidator.Validate(row);
if (errors.Count == 0)
{
validCount++;
}
var invoiceId = string.IsNullOrWhiteSpace(row.InvoiceId)
? "(ohne Rechnungsnummer)"
: row.InvoiceId;
logger.LogInformation(
"{BlobName}: {InvoiceId}: {Result}",
name,
invoiceId,
errors.Count == 0
? "Gültig"
: string.Join("; ", errors));
report = new ImportReport(
SourceBlob: name,
CheckedAtUtc: DateTimeOffset.UtcNow,
Status: "Rejected",
Rows: [],
FileErrors: [exception.Message]);
}
logger.LogInformation(
"Dateiprüfung abgeschlossen: {BlobName}, " +
"{TotalCount} Rechnungen, {ValidCount} gültig, {InvalidCount} fehlerhaft.",
"Prüfbericht erstellt: {BlobName}, Status {Status}, " +
"{TotalCount} Rechnungen, {ValidCount} gültig, " +
"{InvalidCount} fehlerhaft.",
name,
rows.Count,
validCount,
rows.Count - validCount);
report.Status,
report.TotalCount,
report.ValidCount,
report.InvalidCount);
return JsonSerializer.Serialize(report, JsonOptions);
}
}