Codebasis als Dateien ins Arbeitsrepo statt als Gitlink

QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
This commit is contained in:
Christoph Schwörer
2026-08-26 07:43:51 +02:00
parent 18edae75b6
commit f045b99a25
24664 changed files with 5846716 additions and 1 deletions
@@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using Centron.BusinessLogic;
using Centron.BusinessLogic.EDI.SupplierEDI;
using Centron.Data.Entities.Administration.Logins;
using Centron.Data.Entities.EDI;
using Centron.Tests.EndToEnd.Infrastructure;
using CentronSoftware.Centron.WebServices.Entities.EDI;
using Xunit;
using Xunit.Abstractions;
namespace Centron.Tests.EndToEnd.Tests.EDI
{
/// <summary>
/// End-to-end test for diagnosing issues with EDI import functionality
/// specifically focusing on why some invoices in a ZIP file might not be processed.
/// </summary>
public class EdiImportTests : EndToEndTest
{
private const int SupplierI3D = 70003;
public EdiImportTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
// Set to true only when you need to update expected files
// Verifier.OverrideExpectedFiles = true;
}
public override void Execute()
{
using (var session = new BLSession())
{
// Execute the EDI import test
ImportEdiZipFile_ShouldProcessAllInvoices(session, GetLoggedInUser());
}
}
/// <summary>
/// Tests the EDI import functionality by directly loading a local ZIP file
/// and passing it to the import process, then verifies all invoices are processed.
/// </summary>
private void ImportEdiZipFile_ShouldProcessAllInvoices(BLSession session, LoggedInUser user)
{
// Load the test ZIP file from embedded resources
byte[] zipFileBytes;
var assembly = typeof(EdiImportTests).Assembly;
string resourceName = $"{typeof(EdiImportTests).Namespace}.ExampleData.IN_419872_250626.zip";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
throw new InvalidOperationException($"Embedded resource not found: {resourceName}");
}
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
zipFileBytes = memoryStream.ToArray();
}
}
TestOutputHelper.WriteLine($"Loaded ZIP file from embedded resource: {zipFileBytes.Length} bytes");
// Create supplier EDI business logic
var supplierEdiBL = session.GetBL<SupplierEdiBL>();
// Get all configurations to identify which one is relevant for our test file
var configs = GetRelevantEdiConfigurations(session, supplierEdiBL);
TestOutputHelper.WriteLine($"Found {configs.Count} relevant EDI configurations");
// Process the file with each configuration until we find the one that works
var importResults = ProcessFileWithConfigurations(zipFileBytes, configs, supplierEdiBL);
// Verify the results
Verifier.Verify("EdiImport_ZipFileContents", importResults.ZipContents);
Verifier.Verify("EdiImport_ProcessedFiles", importResults.ProcessedFiles);
Verifier.VerifySql("EdiImport_EDIInvoiceHead_Data", @"SELECT [I3D],[SupplierI3D],[OrigFileName],[SupplierFileName],[SourceOrderNumber],[SourceOrderDate],[SupplierInvoiceNumber],[SupplierInvoiceDate]
,[DeliveryDateStart],[DeliveryDateEnd],[CentronOrderNumber],[BuyerName],[BuyerName2],[BuyerName3],[BuyerStreet],[BuyerZip],[BuyerCity]
,[BuyerCountry],[DeliveryName],[DeliveryName2],[DeliveryName3],[DeliveryStreet],[DeliveryZip],[DeliveryCity],[DeliveryCountry],[BuyerPartyID]
,[DeliveryPartyID],[NeedsUserValidation],[SupplierNetto],[SupplierBrutto],[Currency],[Multidistributor],[Comment],[CentronDeliveryListI3D]
,[CentronOrderI3D],[State],[DeliveryNumber],[IsDeliveryAccept],[EDIConfigurationI3D],[AddField1],[AddField2],[OrderResponseNumber]
FROM [dbo].[EDIInvoiceHead]");
// Check that all 4 invoices were processed
Assert.Equal(4, importResults.ZipContents.Count);
Assert.True(importResults.ProcessedFiles.First().Success);
Assert.Equal(4, importResults.ProcessedFiles.First().FileCount);
Assert.Equal(4, session.DAOSession.GetSession().Query<EDIInvoiceHead>().Count());
// Log detailed information about processed and unprocessed files
LogProcessingResults(importResults);
}
private List<SupplierEdiConfigurations> GetRelevantEdiConfigurations(
BLSession session, SupplierEdiBL supplierEdiBL)
{
return new List<SupplierEdiConfigurations>()
{
new SupplierEdiConfigurations()
{
SupplierI3D = SupplierI3D,
ExportKind = 1,
ObjectKind = 3,
EdiDataType = 1,
DeleteAfterUpload = false,
SupplierCustomerNumber = "44-470896"
}
};
}
private (List<string> ZipContents, List<EDIProcessResult> ProcessedFiles) ProcessFileWithConfigurations(
byte[] zipFileBytes, List<SupplierEdiConfigurations> configs, SupplierEdiBL supplierEdiBL)
{
// Extract file names from zip to log what should be processed
var zipContents = GetZipContents(zipFileBytes);
TestOutputHelper.WriteLine($"ZIP file contains {zipContents.Count} files");
// Track processing results
var processedFiles = new List<EDIProcessResult>();
// Prepare memory stream for ZIP file
using (var zipStream = new MemoryStream(zipFileBytes))
{
// Process the ZIP file
var processResult = ProcessEdiZipFile(zipStream, configs, supplierEdiBL);
processedFiles.AddRange(processResult);
}
return (zipContents, processedFiles);
}
private List<string> GetZipContents(byte[] zipFileBytes)
{
var fileNames = new List<string>();
using (var zipStream = new MemoryStream(zipFileBytes))
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
{
foreach (var entry in archive.Entries)
{
fileNames.Add(entry.FullName);
TestOutputHelper.WriteLine($"ZIP contains file: {entry.FullName}, Size: {entry.Length} bytes");
}
}
return fileNames;
}
private List<EDIProcessResult> ProcessEdiZipFile(
MemoryStream zipStream, List<SupplierEdiConfigurations> configs, SupplierEdiBL supplierEdiBL)
{
var processedFiles = new List<EDIProcessResult>();
// Extract the contents of the ZIP file to EDIDistriFile objects
var distriFiles = new List<EDIDistriFile>();
distriFiles.Add(new EDIDistriFile { DistriName = "IN_419872_250626.zip" });
supplierEdiBL.ZipExtract(zipStream, distriFiles);
TestOutputHelper.WriteLine($"Extracted {distriFiles.Count} files from ZIP");
// Try each configuration until we find one that works
foreach (var config in configs)
{
try
{
TestOutputHelper.WriteLine($"Trying configuration: {config.SupplierI3D}, EDI Type: {config.EdiDataType}, Object Kind: {config.ObjectKind}");
// Create a local copy of distriFiles for each attempt to avoid side effects
var filesToProcess = new List<EDIDistriFile>(distriFiles);
// Call ApplyDistriToCentron
bool result = supplierEdiBL.ApplyDistriToCentron(filesToProcess, config, null).Result;
// Record the processing result
processedFiles.Add(new EDIProcessResult
{
ConfigurationId = config.I3D,
SupplierI3D = config.SupplierI3D,
EdiDataType = config.EdiDataType,
Success = result,
FileCount = distriFiles.Count
});
// If successful, no need to try other configurations
if (result)
{
TestOutputHelper.WriteLine($"Successfully processed files with configuration {config.I3D}");
break;
}
}
catch (Exception ex)
{
TestOutputHelper.WriteLine($"Error processing with configuration {config.I3D}: {ex.Message}");
// Continue with next configuration
}
}
// If no configuration succeeded, check EDI logs for errors
if (!processedFiles.Any(r => r.Success))
{
TestOutputHelper.WriteLine("No configuration successfully processed the files");
CheckEdiLogs(supplierEdiBL);
}
return processedFiles;
}
private void CheckEdiLogs(SupplierEdiBL supplierEdiBL)
{
var ediLogBL = supplierEdiBL.GetEDILogBL(0);
// Get logs for the test file
var logFilter = new EDIManagementLogFilter
{
SupplierI3D = SupplierI3D,
// StartDate = DateTime.Now.AddDays(-1),
// EndDate = DateTime.Now.AddDays(1)
};
// Use reflection to get logs
var getLogsMethod = ediLogBL.GetType().GetMethod("GetEDILogs");
var logs = getLogsMethod?.Invoke(ediLogBL, new object[] { logFilter });
if (logs != null)
{
Verifier.Verify("EdiImport_Logs", logs);
TestOutputHelper.WriteLine("Retrieved EDI logs for analysis");
}
}
private void LogProcessingResults((List<string> ZipContents, List<EDIProcessResult> ProcessedFiles) results)
{
TestOutputHelper.WriteLine("=== EDI Processing Results ===");
TestOutputHelper.WriteLine($"Files in ZIP: {results.ZipContents.Count}");
TestOutputHelper.WriteLine($"Files processed: {results.ProcessedFiles.Count(r => r.Success)}");
foreach (var file in results.ZipContents)
{
TestOutputHelper.WriteLine($"File: {file}");
}
foreach (var result in results.ProcessedFiles)
{
TestOutputHelper.WriteLine($"Config {result.ConfigurationId} (Supplier {result.SupplierI3D}, Type {result.EdiDataType}): {(result.Success ? "Success" : "Failed")}");
}
}
}
/// <summary>
/// Helper class to track EDI processing results
/// </summary>
public class EDIProcessResult
{
public int ConfigurationId { get; set; }
public int SupplierI3D { get; set; }
public int EdiDataType { get; set; }
public bool Success { get; set; }
public int FileCount { get; set; }
}
}