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
266 lines
12 KiB
C#
266 lines
12 KiB
C#
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; }
|
|
}
|
|
}
|