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
601 lines
19 KiB
C#
601 lines
19 KiB
C#
using Centron.BusinessLogic.EDI.Opentrans21;
|
|
using Centron.Data.WebServices.Accounts;
|
|
using Centron.Data.WebServices.Administration.MandatoryArea;
|
|
using Centron.Data.WebServices.Administration.MasterData;
|
|
using Centron.Data.WebServices.Sales.Receipts;
|
|
using Centron.Interfaces.EDI;
|
|
using CentronSoftware.Centron.WebServices.Entities.EDI;
|
|
using CentronSoftware.Centron.WebServices.Entities.Sales.Receipts.SupplierOrders;
|
|
using CentronSoftware.Centron.WebServices.Entities.Warehousing;
|
|
using JetBrains.Annotations;
|
|
|
|
namespace Centron.Tests.BL.EDI.Opentrans21;
|
|
|
|
[TestSubject(typeof(Opentrans21OrderBL))]
|
|
public class Opentrans21OrderBLTest
|
|
{
|
|
private readonly List<CountryDTO> _testCountries;
|
|
private readonly ReceiptSupplierOrderDTO _testReceipt;
|
|
private readonly MandatoryDTO _testMandatory;
|
|
private readonly AccountSearchItemDTO _testAddress;
|
|
private readonly AccountSearchItemDTO _testLicenceAddress;
|
|
private readonly AccountSearchItemDTO _testSupplierAccount;
|
|
private readonly ReceiptSettingsDTO _testReceiptSettings;
|
|
private readonly List<ReceiptSupplierOrderItemDTO> _testReceiptItems;
|
|
private readonly List<SpecialAgreementPreviewDTO> _testSpecialAgreements;
|
|
|
|
private const string _customerNumberAtSupplier = "CUST123";
|
|
private const string _supplierID = "SUPP456";
|
|
|
|
public Opentrans21OrderBLTest()
|
|
{
|
|
_testCountries = CreateTestCountries();
|
|
_testReceipt = CreateTestReceipt();
|
|
_testMandatory = CreateTestMandatory();
|
|
_testAddress = CreateTestAddress();
|
|
_testLicenceAddress = CreateTestLicenceAddress();
|
|
_testSupplierAccount = CreateTestSupplierAccount();
|
|
_testReceiptSettings = CreateTestReceiptSettings();
|
|
_testReceiptItems = CreateTestReceiptItems();
|
|
_testSpecialAgreements = CreateTestSpecialAgreements();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldSetCorrectOrderInfo_WhenValidDataProvided()
|
|
{
|
|
// Arrange
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var orderInfo = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "ORDER_INFO");
|
|
Assert.NotNull(orderInfo);
|
|
|
|
var orderId = orderInfo.Descendants().FirstOrDefault(x => x.Name.LocalName == "ORDER_ID");
|
|
Assert.NotNull(orderId);
|
|
Assert.Equal(_testReceipt.Number.ToString(), orderId.Value);
|
|
|
|
var orderDate = orderInfo.Descendants().FirstOrDefault(x => x.Name.LocalName == "ORDER_DATE");
|
|
Assert.NotNull(orderDate);
|
|
Assert.Equal(_testReceipt.Date.ToString("yyyy-MM-dd"), orderDate.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldIncludeCorrectParties_WhenStandardDistributor()
|
|
{
|
|
// Arrange
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var parties = xmlDoc.Descendants().Where(x => x.Name.LocalName == "PARTY").ToList();
|
|
|
|
// Should have buyer, supplier, and delivery parties
|
|
Assert.True(parties.Count >= 3);
|
|
|
|
var partyRoles = parties.SelectMany(p => p.Descendants().Where(x => x.Name.LocalName == "PARTY_ROLE"))
|
|
.Select(r => r.Value).ToList();
|
|
|
|
Assert.Contains("buyer", partyRoles);
|
|
Assert.Contains("supplier", partyRoles);
|
|
Assert.Contains("delivery", partyRoles);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldCalculateCorrectTotalAmount_WhenMultipleItems()
|
|
{
|
|
// Arrange
|
|
var receiptItems = new List<ReceiptSupplierOrderItemDTO>
|
|
{
|
|
CreateTestReceiptItem(1, 2.0m, 10.50m), // 2 * 10.50 = 21.00
|
|
CreateTestReceiptItem(2, 3.0m, 15.75m), // 3 * 15.75 = 47.25
|
|
CreateTestReceiptItem(3, 1.0m, 5.25m) // 1 * 5.25 = 5.25
|
|
};
|
|
// Total expected: 73.50
|
|
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
receiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var totalAmount = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "TOTAL_AMOUNT");
|
|
Assert.NotNull(totalAmount);
|
|
Assert.Equal("73.50", totalAmount.Value);
|
|
|
|
var totalItemNum = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "TOTAL_ITEM_NUM");
|
|
Assert.NotNull(totalItemNum);
|
|
Assert.Equal("3", totalItemNum.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldSetDeliveryDate_WhenDeliveryDateSpecified()
|
|
{
|
|
// Arrange
|
|
var receipt = CreateTestReceipt();
|
|
receipt.DeliveryDate = new DateTime(2024, 12, 25);
|
|
|
|
var orderBL = new Opentrans21OrderBL(
|
|
receipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var deliveryStartDate = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "DELIVERY_START_DATE");
|
|
var deliveryEndDate = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "DELIVERY_END_DATE");
|
|
|
|
Assert.NotNull(deliveryStartDate);
|
|
Assert.NotNull(deliveryEndDate);
|
|
Assert.Equal("2024-12-25", deliveryStartDate.Value);
|
|
Assert.Equal("2024-12-25", deliveryEndDate.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldHandleTHSSpecificity_WhenTHSOrderSpecificity()
|
|
{
|
|
// Arrange
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.THS,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
null, // No delivery address for THS
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var orderItems = xmlDoc.Descendants().Where(x => x.Name.LocalName == "ORDER_ITEM").ToList();
|
|
|
|
foreach (var item in orderItems)
|
|
{
|
|
var remarks = item.Descendants().Where(x => x.Name.LocalName == "REMARKS").ToList();
|
|
Assert.Equal(10, remarks.Count); // THS should have exactly 10 remarks
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldReturnError_WhenExceptionOccurs()
|
|
{
|
|
// Arrange
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Create invalid receipt items that will cause an exception
|
|
var invalidReceiptItems = new List<ReceiptSupplierOrderItemDTO?>
|
|
{
|
|
null // This should cause an exception
|
|
};
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
invalidReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.False(result.IsSuccess);
|
|
Assert.NotNull(result.Error);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldSetCorrectCurrency_WhenCurrencyFound()
|
|
{
|
|
// Arrange
|
|
var receipt = CreateTestReceipt();
|
|
receipt.CurrencyString = "EUR";
|
|
|
|
var orderBL = new Opentrans21OrderBL(
|
|
receipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var currency = xmlDoc.Descendants().FirstOrDefault(x => x.Name.LocalName == "CURRENCY");
|
|
Assert.NotNull(currency);
|
|
Assert.Equal("EUR", currency.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldIncludeLicenceAddress_WhenLicenceAddressProvided()
|
|
{
|
|
// Arrange
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
_testLicenceAddress,
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var parties = xmlDoc.Descendants().Where(x => x.Name.LocalName == "PARTY").ToList();
|
|
|
|
// Should have buyer, supplier, delivery, and licence parties
|
|
Assert.True(parties.Count >= 4);
|
|
|
|
var partyRoles = parties.SelectMany(p => p.Descendants().Where(x => x.Name.LocalName == "PARTY_ROLE"))
|
|
.Select(r => r.Value).ToList();
|
|
|
|
Assert.Contains("buyer", partyRoles);
|
|
Assert.Contains("supplier", partyRoles);
|
|
Assert.Contains("delivery", partyRoles);
|
|
|
|
// Find the licence party
|
|
var licenceParty = parties.FirstOrDefault(p =>
|
|
p.Descendants().Any(x => x.Name.LocalName == "PARTY_ROLE" && x.Value == "customer"));
|
|
|
|
Assert.NotNull(licenceParty);
|
|
|
|
// Verify licence party contains the correct information
|
|
var partyName = licenceParty.Descendants().FirstOrDefault(x => x.Name.LocalName == "NAME");
|
|
Assert.NotNull(partyName);
|
|
Assert.Equal(_testLicenceAddress.AccountName, partyName.Value);
|
|
|
|
var street = licenceParty.Descendants().FirstOrDefault(x => x.Name.LocalName == "STREET");
|
|
Assert.NotNull(street);
|
|
Assert.Equal(_testLicenceAddress.AddressStreet, street.Value);
|
|
|
|
var city = licenceParty.Descendants().FirstOrDefault(x => x.Name.LocalName == "CITY");
|
|
Assert.NotNull(city);
|
|
Assert.Equal(_testLicenceAddress.AddressCity, city.Value);
|
|
|
|
var zip = licenceParty.Descendants().FirstOrDefault(x => x.Name.LocalName == "ZIP");
|
|
Assert.NotNull(zip);
|
|
Assert.Equal(_testLicenceAddress.AddressZip, zip.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateOrderDocument_ShouldHandleNullLicenceAddress_WhenLicenceAddressNotProvided()
|
|
{
|
|
// Arrange
|
|
var orderBL = new Opentrans21OrderBL(
|
|
_testReceipt,
|
|
_customerNumberAtSupplier,
|
|
_supplierID,
|
|
(int)EDIOrderSpecificity.none,
|
|
_testCountries
|
|
);
|
|
|
|
// Act
|
|
var result = await orderBL.CreateOrderDocument(
|
|
_testReceiptItems,
|
|
_testMandatory,
|
|
_testSpecialAgreements,
|
|
_testAddress,
|
|
null, // No licence address
|
|
_testSupplierAccount,
|
|
EDIMultidistributors.None,
|
|
_testReceiptSettings,
|
|
"test@example.com"
|
|
);
|
|
|
|
// Assert
|
|
Assert.True(result.IsSuccess);
|
|
|
|
var xmlDoc = result.Data;
|
|
var parties = xmlDoc.Descendants().Where(x => x.Name.LocalName == "PARTY").ToList();
|
|
|
|
// Should have buyer, supplier, and delivery parties (no licence party)
|
|
var partyRoles = parties.SelectMany(p => p.Descendants().Where(x => x.Name.LocalName == "PARTY_ROLE"))
|
|
.Select(r => r.Value).ToList();
|
|
|
|
Assert.Contains("buyer", partyRoles);
|
|
Assert.Contains("supplier", partyRoles);
|
|
Assert.Contains("delivery", partyRoles);
|
|
|
|
// Ensure no licence party is present
|
|
Assert.DoesNotContain("licencee", partyRoles);
|
|
}
|
|
|
|
#region Test Data Creation Methods
|
|
|
|
private static List<CountryDTO> CreateTestCountries()
|
|
{
|
|
return
|
|
[
|
|
new CountryDTO
|
|
{
|
|
I3D = 1,
|
|
CountryCode = "DE",
|
|
CurrencySymbol = "EUR",
|
|
CurrencyISO = "EUR"
|
|
},
|
|
new CountryDTO
|
|
{
|
|
I3D = 2,
|
|
CountryCode = "US",
|
|
CurrencySymbol = "USD",
|
|
CurrencyISO = "USD"
|
|
}
|
|
];
|
|
}
|
|
|
|
private static ReceiptSupplierOrderDTO CreateTestReceipt()
|
|
{
|
|
return new ReceiptSupplierOrderDTO
|
|
{
|
|
Number = 12345,
|
|
Version = 1,
|
|
Date = new DateTime(2024, 10, 14),
|
|
CurrencyString = "EUR",
|
|
DeliveryDate = null
|
|
};
|
|
}
|
|
|
|
private static MandatoryDTO CreateTestMandatory()
|
|
{
|
|
return new MandatoryDTO
|
|
{
|
|
Mandator = "Test Company GmbH",
|
|
Street = "Test Street 123",
|
|
City = "Test City",
|
|
PostalCode = "12345",
|
|
Mail = "test@company.com",
|
|
Telephone = "+49 123 456789",
|
|
Country = new CountryDTO
|
|
{
|
|
I3D = 1,
|
|
CountryCode = "DE"
|
|
}
|
|
};
|
|
}
|
|
|
|
private static AccountSearchItemDTO CreateTestAddress()
|
|
{
|
|
return new AccountSearchItemDTO
|
|
{
|
|
AddressI3D = 1001,
|
|
AccountName = "Delivery Company",
|
|
AddressStreet = "Delivery Street 456",
|
|
AddressCity = "Delivery City",
|
|
AddressZip = "54321",
|
|
AddressCountryI3D = 1,
|
|
AddressDepartment = "Receiving Department",
|
|
AddressContactFirstname = "John",
|
|
AddressContactLastname = "Doe",
|
|
AddressContactTitle = "Mr.",
|
|
PrintName = true,
|
|
PrintDepartment = true,
|
|
PrintAddressContact = true
|
|
};
|
|
}
|
|
|
|
private static AccountSearchItemDTO CreateTestLicenceAddress()
|
|
{
|
|
return new AccountSearchItemDTO
|
|
{
|
|
AddressI3D = 1002,
|
|
AccountName = "Licence Company",
|
|
AddressStreet = "Licence Street 789",
|
|
AddressCity = "Licence City",
|
|
AddressZip = "65432",
|
|
AddressCountryI3D = 1,
|
|
AddressDepartment = "Licence Department",
|
|
AddressContactFirstname = "John",
|
|
AddressContactLastname = "Doe",
|
|
AddressContactTitle = "Mr.",
|
|
PrintName = true,
|
|
PrintDepartment = true,
|
|
PrintAddressContact = true
|
|
};
|
|
}
|
|
|
|
private static AccountSearchItemDTO CreateTestSupplierAccount()
|
|
{
|
|
return new AccountSearchItemDTO
|
|
{
|
|
AccountName = "Supplier Company Ltd",
|
|
AddressStreet = "Supplier Street 789",
|
|
AddressCity = "Supplier City",
|
|
AddressZip = "98765",
|
|
AddressCountryI3D = 1,
|
|
AddressDepartment = "Sales Department",
|
|
AddressContactFirstname = "Jane",
|
|
AddressContactLastname = "Smith",
|
|
AddressContactTitle = "Ms.",
|
|
ItScopeSupplierNumber = "12345",
|
|
PrintName = true,
|
|
PrintAddressContact = true,
|
|
PrintDepartment = true,
|
|
PrintDepartmentAddressContact = true
|
|
};
|
|
}
|
|
|
|
private static ReceiptSettingsDTO CreateTestReceiptSettings()
|
|
{
|
|
return new ReceiptSettingsDTO
|
|
{
|
|
ItScopeApiKey = "test-api-key"
|
|
};
|
|
}
|
|
|
|
private static List<ReceiptSupplierOrderItemDTO> CreateTestReceiptItems()
|
|
{
|
|
return
|
|
[
|
|
CreateTestReceiptItem(1, 2.0m, 25.50m),
|
|
CreateTestReceiptItem(2, 1.0m, 15.75m)
|
|
];
|
|
}
|
|
|
|
private static ReceiptSupplierOrderItemDTO CreateTestReceiptItem(int position, decimal quantity, decimal basePrice)
|
|
{
|
|
return new ReceiptSupplierOrderItemDTO
|
|
{
|
|
I3D = 1000 + position,
|
|
InternalPosition = position,
|
|
ArticleI3D = 2000 + position,
|
|
ArticleCode = $"ART-{position:D3}",
|
|
Text = $"Test Article {position}",
|
|
EANCode = $"123456789012{position}",
|
|
ManufacturerCode = $"MFG-{position:D3}",
|
|
SupplierManufacturerCode = $"SUP-MFG-{position:D3}",
|
|
QuantityComplete = quantity,
|
|
QuantityProcessed = 0,
|
|
BasePrice = basePrice,
|
|
PurchaseInformations = $"Purchase info for item {position}",
|
|
PurchaseOrderNumber = $"PO-{position:D6}",
|
|
SpecialAgreementI3D = null
|
|
};
|
|
}
|
|
|
|
private static List<SpecialAgreementPreviewDTO> CreateTestSpecialAgreements()
|
|
{
|
|
return
|
|
[
|
|
new SpecialAgreementPreviewDTO
|
|
{
|
|
I3D = 1,
|
|
Number = "SA-001",
|
|
Text = "Special Agreement 1",
|
|
IsProjectPrice = true,
|
|
IsInternal = false
|
|
}
|
|
];
|
|
}
|
|
|
|
#endregion
|
|
}
|