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