diff --git a/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml b/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml index 2fca806..e4b825e 100644 --- a/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml +++ b/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml @@ -104,5 +104,12 @@ Importiert am@Model.ImportedInvoice.ImportedAt.ToString("dd.MM.yyyy HH:mm")
✔ Rechnung wurde in der Datenbank gespeichert (ID: @Model.ImportedInvoice.Id)
+ @if (Model.IsDuplicate) + { +
+ ⚠️ Duplikat: Diese Rechnung wurde bereits importiert (ID: @Model.ImportedInvoice!.Id). + Es wurde kein neuer Eintrag angelegt. +
+ } } } \ No newline at end of file diff --git a/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml.cs b/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml.cs index 759bb6f..94d1407 100644 --- a/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml.cs +++ b/DXApp.TemplateKitProject/Pages/Invoices/Upload.cshtml.cs @@ -21,6 +21,7 @@ public class UploadModel( public string? ErrorMessage { get; private set; } public ZugferdInvoice? ImportedInvoice { get; private set; } public string? ResultFilePath { get; private set; } + public bool IsDuplicate { get; private set; } public void OnGet() { } @@ -56,10 +57,14 @@ public class UploadModel( if (Result.HasZugferdXml) { memStream.Position = 0; - ImportedInvoice = await zugferdImportService.ImportAsync(memStream, "Upload"); + ImportedInvoice = await zugferdImportService.ImportAsync(memStream, "Upload", Result.ZugferdGuidelineId); - // 3. Result-Package erstellen (nur wenn Import erfolgreich) - if (ImportedInvoice is not null) + // Duplikat erkennen: vorhandener Eintrag hat ImportedAt von früher + if (ImportedInvoice is not null && ImportedInvoice.ImportedAt < DateTime.UtcNow.AddSeconds(-5)) + IsDuplicate = true; + + // 3. Result-Package erstellen (nur wenn Import erfolgreich UND kein Duplikat) + if (ImportedInvoice is not null && !IsDuplicate) { ResultFilePath = await resultPackageService.CreateResultPackageAsync( originalBytes, PdfFile.FileName, ImportedInvoice); diff --git a/DXApp.TemplateKitProject/Services/ZugferdImportService.cs b/DXApp.TemplateKitProject/Services/ZugferdImportService.cs index 57c58c5..e54e882 100644 --- a/DXApp.TemplateKitProject/Services/ZugferdImportService.cs +++ b/DXApp.TemplateKitProject/Services/ZugferdImportService.cs @@ -1,5 +1,6 @@ using DXApp.TemplateKitProject.Data; using DXApp.TemplateKitProject.Models; +using Microsoft.EntityFrameworkCore; namespace DXApp.TemplateKitProject.Services; @@ -9,7 +10,7 @@ public class ZugferdImportService( AppDbContext db, ILogger logger) { - public async Task ImportAsync(Stream pdfStream, string sourceType) + public async Task ImportAsync(Stream pdfStream, string sourceType, string guidelineId = "") { var xml = extractor.ExtractXml(pdfStream); @@ -20,11 +21,31 @@ public class ZugferdImportService( } var invoice = parser.Parse(xml); + + // Duplikatprüfung + var duplicate = await db.ZugferdInvoices.FirstOrDefaultAsync(i => + i.InvoiceNumber == invoice.InvoiceNumber && + i.SellerTaxId == invoice.SellerTaxId); + + if (duplicate is not null) + { + logger.LogWarning( + "Duplikat erkannt: Rechnung '{Number}' von '{Seller}' existiert bereits (ID: {Id}).", + invoice.InvoiceNumber, invoice.SellerName, duplicate.Id); + return duplicate; + } + invoice.SourceType = sourceType; + invoice.GuidelineId = guidelineId; + invoice.ImportedAt = DateTime.UtcNow; db.ZugferdInvoices.Add(invoice); await db.SaveChangesAsync(); + logger.LogInformation( + "Rechnung '{Number}' von '{Seller}' importiert (ID: {Id}).", + invoice.InvoiceNumber, invoice.SellerName, invoice.Id); + return invoice; } } \ No newline at end of file