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,263 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Centron.BusinessLogic;
using Centron.BusinessLogic.WebServices.Sales.CustomerAssets.AutomaticFactura;
using Centron.Data.Entities.Administration.Logins;
using Centron.Data.WebServices.Sales.Receipts.Invoices;
using Centron.Interfaces.BL;
using Centron.Interfaces.Sales.BillingCenter.Contracts;
using Centron.Tests.EndToEnd.Infrastructure;
using CentronSoftware.Centron.WebServices.Entities.Sales.BillingCenter.Contracts;
using Xunit.Abstractions;
namespace Centron.Tests.EndToEnd.Tests.AutomaticFactura
{
public class AutomaticFacturaRMMTests : EndToEndTest
{
// Test data constants
private const int TestContractI3D = 1; // Assuming contract with RMM articles exists
private const int TestCustomerI3D = 10010; // Standard test customer
private const int TestUserI3D = 11; // Standard test user
public AutomaticFacturaRMMTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
// Ignore dynamic properties that change with each run
this.Verifier.Settings.IgnoreProperty<ReceiptInvoiceDTO>(f => f.CreatedAt);
this.Verifier.Settings.IgnoreProperty<ReceiptInvoiceDTO>(f => f.ChangedAt);
// Note: ReceiptInvoiceItemDTO doesn't have CreatedAt/ChangedAt properties
}
public override void Execute()
{
// Ignore this test for now
// SKA : 2025-07-15 : It's a good base for a future unit test. But at the moment it's hard to test the RMM-Functionality
// We have to first encapsulate the call of the external Riverbird Service, so that we can test it
// this.PrepareDatabase();
//
// // Test single interval (fallback case)
// this.TestSingleIntervalRMM();
//
// // Test multiple intervals (new functionality)
// this.TestMultipleIntervalsRMM();
}
private void PrepareDatabase()
{
// Ensure we have test data for RMM functionality
// This would typically involve setting up contract article references, etc.
using (var session = new BLSession())
{
// Any database preparation needed for RMM testing
// For now, we'll rely on existing test data
}
}
/// <summary>
/// Tests the fallback case with a single billing interval.
/// This should work exactly as before the refactoring.
/// </summary>
private void TestSingleIntervalRMM()
{
using (var session = new BLSession())
{
var loggedInUser = this.GetLoggedInUser(TestUserI3D);
// Create a billing parameter with single interval
var billingParam = new ContractToInvoiceParam
{
ContractID = new KeyValuePair<int, string>(TestContractI3D, "Test Contract"),
InvoiceFrom = DateTime.Today.AddDays(-30),
InvoiceTo = DateTime.Today,
InvoiceIntervalCount = 1, // Single interval
BillingIntervalKind = BillingIntervalKinds.Monthly,
BillingIntervalDuration = 1
};
// Create a test invoice
var invoice = this.CreateTestInvoice(session, loggedInUser);
// Add RMM placeholder to test removal and replacement
this.AddRMMPlaceholderToInvoice(invoice);
var automaticFacturaWebServiceBL = session.GetBL<AutomaticFacturaWebServiceBL>();
// This is the method we're testing - it should handle single interval correctly
try
{
// Use reflection to call the private CheckRMMArticle method
var checkRMMMethod = typeof(AutomaticFacturaWebServiceBL).GetMethod("CheckRMMArticle",
BindingFlags.NonPublic | BindingFlags.Instance);
checkRMMMethod?.Invoke(automaticFacturaWebServiceBL, new object[] { invoice, billingParam, loggedInUser });
// Verify the result
this.Verifier.Verify("SingleInterval_RMM_Invoice", invoice);
}
catch (Exception ex)
{
// If RMM service is not available, we expect a specific exception
if (ex.InnerException?.GetType().Name == "RMMServiceUnavailableException")
{
this.Verifier.Verify("SingleInterval_RMM_ServiceUnavailable", ex.InnerException.Message);
}
else
{
throw;
}
}
}
}
/// <summary>
/// Tests the new functionality with multiple billing intervals.
/// Device counts should be summed across all intervals.
/// </summary>
private void TestMultipleIntervalsRMM()
{
using (var session = new BLSession())
{
var loggedInUser = this.GetLoggedInUser(TestUserI3D);
// Create billing parameters with multiple intervals
var billingParam = new ContractToInvoiceParam
{
ContractID = new KeyValuePair<int, string>(TestContractI3D, "Test Contract"),
InvoiceFrom = DateTime.Today.AddDays(-60),
InvoiceTo = DateTime.Today,
InvoiceIntervalCount = 2, // Two intervals
BillingIntervalKind = BillingIntervalKinds.Monthly,
BillingIntervalDuration = 1
};
// Create a test invoice
var invoice = this.CreateTestInvoice(session, loggedInUser);
// Add RMM placeholder to test removal and replacement
this.AddRMMPlaceholderToInvoice(invoice);
var automaticFacturaWebServiceBL = session.GetBL<AutomaticFacturaWebServiceBL>();
try
{
// Use reflection to call the private CheckRMMArticle method
var checkRMMMethod = typeof(AutomaticFacturaWebServiceBL).GetMethod("CheckRMMArticle",
BindingFlags.NonPublic | BindingFlags.Instance);
checkRMMMethod?.Invoke(automaticFacturaWebServiceBL, new object[] { invoice, billingParam, loggedInUser });
// Verify the result - should show summed device counts
this.Verifier.Verify("MultipleIntervals_RMM_Invoice", invoice);
}
catch (Exception ex)
{
// If RMM service is not available, we expect a specific exception
if (ex.InnerException?.GetType().Name == "RMMServiceUnavailableException")
{
this.Verifier.Verify("MultipleIntervals_RMM_ServiceUnavailable", ex.InnerException.Message);
}
else
{
throw;
}
}
}
}
/// <summary>
/// Tests quarterly billing with different BillingIntervalDuration values.
/// </summary>
private void TestQuarterlyIntervalsRMM()
{
using (var session = new BLSession())
{
var loggedInUser = this.GetLoggedInUser(TestUserI3D);
// Test quarterly billing - Variant 1: BillingIntervalKind=Quarterly, Duration=1
var billingParamQuarterly = new ContractToInvoiceParam
{
ContractID = new KeyValuePair<int, string>(TestContractI3D, "Test Contract"),
InvoiceFrom = DateTime.Today.AddDays(-180),
InvoiceTo = DateTime.Today,
InvoiceIntervalCount = 2, // Two quarters
BillingIntervalKind = BillingIntervalKinds.Quarterly,
BillingIntervalDuration = 1
};
// Test quarterly billing - Variant 2: BillingIntervalKind=Monthly, Duration=3
var billingParamMonthly3 = new ContractToInvoiceParam
{
ContractID = new KeyValuePair<int, string>(TestContractI3D, "Test Contract"),
InvoiceFrom = DateTime.Today.AddDays(-180),
InvoiceTo = DateTime.Today,
InvoiceIntervalCount = 2, // Two 3-month periods
BillingIntervalKind = BillingIntervalKinds.Monthly,
BillingIntervalDuration = 3 // Every 3 months
};
var automaticFacturaWebServiceBL = session.GetBL<AutomaticFacturaWebServiceBL>();
// Test both variants to ensure they produce equivalent results
this.TestBillingParameterVariant(session, automaticFacturaWebServiceBL, loggedInUser, billingParamQuarterly, "Quarterly_Variant1");
this.TestBillingParameterVariant(session, automaticFacturaWebServiceBL, loggedInUser, billingParamMonthly3, "Quarterly_Variant2");
}
}
private void TestBillingParameterVariant(BLSession session, AutomaticFacturaWebServiceBL webServiceBL,
LoggedInUser loggedInUser, ContractToInvoiceParam billingParam, string testName)
{
var invoice = this.CreateTestInvoice(session, loggedInUser);
this.AddRMMPlaceholderToInvoice(invoice);
try
{
var checkRMMMethod = typeof(AutomaticFacturaWebServiceBL).GetMethod("CheckRMMArticle",
BindingFlags.NonPublic | BindingFlags.Instance);
checkRMMMethod?.Invoke(webServiceBL, new object[] { invoice, billingParam, loggedInUser });
this.Verifier.Verify($"{testName}_RMM_Invoice", invoice);
}
catch (Exception ex)
{
if (ex.InnerException?.GetType().Name == "RMMServiceUnavailableException")
{
this.Verifier.Verify($"{testName}_RMM_ServiceUnavailable", ex.InnerException.Message);
}
else
{
throw;
}
}
}
private ReceiptInvoiceDTO CreateTestInvoice(BLSession session, LoggedInUser loggedInUser)
{
// Create a minimal test invoice
var invoice = new ReceiptInvoiceDTO
{
CustomerI3D = TestCustomerI3D,
Items = new List<ReceiptInvoiceItemDTO>(),
CreatedAt = DateTime.Now,
ChangedAt = DateTime.Now
};
return invoice;
}
private void AddRMMPlaceholderToInvoice(ReceiptInvoiceDTO invoice)
{
// Add a placeholder RMM item to test removal and replacement
var rmmPlaceholderItem = new ReceiptInvoiceItemDTO
{
Text = "Test item with @@RMMArtikel@@ placeholder",
RichText = "Rich text with @@RMMArtikel@@ placeholder",
QuantityComplete = 1
};
invoice.Items.Add(rmmPlaceholderItem);
}
}
}
@@ -0,0 +1,151 @@
{
AdditionalText: null,
AddressI3D: null,
BranchI3D: null,
BranchOrigin: 0,
CampaignI3D: null,
ChangedByI3D: null,
ChangedThroughApplication: 0,
City: null,
CollectiveAccount: null,
ConcurrencyControlGuid: Guid,
ContactName: null,
ContactPersonI3D: null,
ContractI3D: null,
CostCenterI3D: null,
CostObjectI3D: null,
CountryI3D: null,
CreatedByI3D: null,
CurrencyFactor: 0.0,
CurrencyFactorIsFixed: false,
CurrencyI3D: null,
CurrencyString: null,
CustomerI3D: 10010,
CustomUpdateArticlePricesAndTexts: false,
Date: DateTime,
DeliveryAddress: null,
DeliveryAddressAddressI3D: null,
DeliveryAddressContactPersonI3D: null,
DeliveryAddressCustomerI3D: null,
DeliveryAddressInformation: null,
DeliveryConditionI3D: null,
DeliveryConditionText: null,
DeliveryDate: null,
DirectoryI3D: null,
DownPaymentForOrderI3D: null,
EditorI3D: null,
Email: null,
EsrAmount: null,
EsrCodelineAmount: null,
EsrReferenceNumber: null,
ExclusiveOfVAT: false,
ExternalInvoiceDate: null,
ExternalInvoiceNumber: null,
Fax: null,
HasPostOfficeBox: false,
I3D: 0,
Information: null,
InvoiceAddress: null,
InvoiceAddressAddressI3D: null,
InvoiceAddressContactPersonI3D: null,
InvoiceAddressCustomerI3D: null,
InvoiceAddressInformation: null,
IsCashAsset: false,
IsFixed: false,
IsPartialDeliveryPossible: false,
Items: [
{
AddAdditionalInformations: null,
ArticleCode: null,
ArticleI3D: null,
ArticlePositionKind: 0,
AttachedData: null,
BalanceID: null,
Barcodes: null,
BasePrice: null,
ChangeStock: false,
ContractI3D: null,
CostCenterI3D: null,
CostObjectI3D: null,
CustomerCostCenter: null,
DeliveryDate: null,
DifferentBalanceDate: null,
Discount: 0.0,
EANCode: null,
Expanded: null,
FontColor: null,
FontName: null,
FontSize: null,
FontStyle: null,
GroupID: 0,
HelpdeskTimerI3Ds: null,
I3D: 0,
Indent: 0,
InternalPosition: 0,
IsBillingPartList: false,
IsReverseCharge: false,
Kind: 0,
LicenseDate: null,
ManufacturerCode: null,
MasterDataListSerialNumberI3D: null,
OriginalPurchasePrice: null,
OriginKind: null,
OriginReceiptI3D: null,
OriginReceiptItemI3D: null,
PreparationDate: null,
ProjectOfferRichText: null,
PurchaseBasePrice: null,
PurchaseInformations: null,
PurchaseOrderNumber: null,
QuantityComplete: 1.0,
QuantityProcessed: null,
ReasonForCustomPurchasePrice: null,
ReceiptI3D: 0,
ReceiptItemServiceArticleClassificationI3D: null,
RevenueAccount: null,
RichText: 'Rich text with @@RMMArtikel@@ placeholder',
RMAItemI3D: null,
SpecialAgreementI3D: null,
Text: 'Test item with @@RMMArtikel@@ placeholder',
VATI3D: null,
VATRate: null,
Visible: 0,
WarehouseI3D: null,
WEEE: null
}
],
LicenseeAddress: null,
LicenseeAddressAddressI3D: null,
LicenseeAddressContactPersonI3D: null,
LicenseeAddressCustomerI3D: null,
LicenseeAddressInformation: null,
MandatI3D: null,
Number: 0,
OfficeStaffI3D: null,
PaidFC: 0.0,
PaymentConditionI3D: null,
PaymentConditionText: null,
PaymentDueDate: null,
Phone: null,
PostOfficeBox: null,
PreparationDate: null,
ProjectNumber: null,
Provision: null,
PurchaseOrderNumber: null,
ReceiptKind: 0,
ReceiptReceiver: null,
ReceiptUserStateI3D: null,
Receiver: null,
ReminderDate: null,
SalesRepresentativeI3D: null,
ShowInformation: false,
State: 0,
Street: null,
TrackingNumber: null,
TrackingNumberURL: null,
UsedAlternativeDeliveryAddress: false,
UsedAlternativeInvoiceAddress: false,
VariableDateField: null,
Version: 0,
Zip: null
}
@@ -0,0 +1,151 @@
{
AdditionalText: null,
AddressI3D: null,
BranchI3D: null,
BranchOrigin: 0,
CampaignI3D: null,
ChangedByI3D: null,
ChangedThroughApplication: 0,
City: null,
CollectiveAccount: null,
ConcurrencyControlGuid: Guid,
ContactName: null,
ContactPersonI3D: null,
ContractI3D: null,
CostCenterI3D: null,
CostObjectI3D: null,
CountryI3D: null,
CreatedByI3D: null,
CurrencyFactor: 0.0,
CurrencyFactorIsFixed: false,
CurrencyI3D: null,
CurrencyString: null,
CustomerI3D: 10010,
CustomUpdateArticlePricesAndTexts: false,
Date: DateTime,
DeliveryAddress: null,
DeliveryAddressAddressI3D: null,
DeliveryAddressContactPersonI3D: null,
DeliveryAddressCustomerI3D: null,
DeliveryAddressInformation: null,
DeliveryConditionI3D: null,
DeliveryConditionText: null,
DeliveryDate: null,
DirectoryI3D: null,
DownPaymentForOrderI3D: null,
EditorI3D: null,
Email: null,
EsrAmount: null,
EsrCodelineAmount: null,
EsrReferenceNumber: null,
ExclusiveOfVAT: false,
ExternalInvoiceDate: null,
ExternalInvoiceNumber: null,
Fax: null,
HasPostOfficeBox: false,
I3D: 0,
Information: null,
InvoiceAddress: null,
InvoiceAddressAddressI3D: null,
InvoiceAddressContactPersonI3D: null,
InvoiceAddressCustomerI3D: null,
InvoiceAddressInformation: null,
IsCashAsset: false,
IsFixed: false,
IsPartialDeliveryPossible: false,
Items: [
{
AddAdditionalInformations: null,
ArticleCode: null,
ArticleI3D: null,
ArticlePositionKind: 0,
AttachedData: null,
BalanceID: null,
Barcodes: null,
BasePrice: null,
ChangeStock: false,
ContractI3D: null,
CostCenterI3D: null,
CostObjectI3D: null,
CustomerCostCenter: null,
DeliveryDate: null,
DifferentBalanceDate: null,
Discount: 0.0,
EANCode: null,
Expanded: null,
FontColor: null,
FontName: null,
FontSize: null,
FontStyle: null,
GroupID: 0,
HelpdeskTimerI3Ds: null,
I3D: 0,
Indent: 0,
InternalPosition: 0,
IsBillingPartList: false,
IsReverseCharge: false,
Kind: 0,
LicenseDate: null,
ManufacturerCode: null,
MasterDataListSerialNumberI3D: null,
OriginalPurchasePrice: null,
OriginKind: null,
OriginReceiptI3D: null,
OriginReceiptItemI3D: null,
PreparationDate: null,
ProjectOfferRichText: null,
PurchaseBasePrice: null,
PurchaseInformations: null,
PurchaseOrderNumber: null,
QuantityComplete: 1.0,
QuantityProcessed: null,
ReasonForCustomPurchasePrice: null,
ReceiptI3D: 0,
ReceiptItemServiceArticleClassificationI3D: null,
RevenueAccount: null,
RichText: 'Rich text with @@RMMArtikel@@ placeholder',
RMAItemI3D: null,
SpecialAgreementI3D: null,
Text: 'Test item with @@RMMArtikel@@ placeholder',
VATI3D: null,
VATRate: null,
Visible: 0,
WarehouseI3D: null,
WEEE: null
}
],
LicenseeAddress: null,
LicenseeAddressAddressI3D: null,
LicenseeAddressContactPersonI3D: null,
LicenseeAddressCustomerI3D: null,
LicenseeAddressInformation: null,
MandatI3D: null,
Number: 0,
OfficeStaffI3D: null,
PaidFC: 0.0,
PaymentConditionI3D: null,
PaymentConditionText: null,
PaymentDueDate: null,
Phone: null,
PostOfficeBox: null,
PreparationDate: null,
ProjectNumber: null,
Provision: null,
PurchaseOrderNumber: null,
ReceiptKind: 0,
ReceiptReceiver: null,
ReceiptUserStateI3D: null,
Receiver: null,
ReminderDate: null,
SalesRepresentativeI3D: null,
ShowInformation: false,
State: 0,
Street: null,
TrackingNumber: null,
TrackingNumberURL: null,
UsedAlternativeDeliveryAddress: false,
UsedAlternativeInvoiceAddress: false,
VariableDateField: null,
Version: 0,
Zip: null
}