Skip to content

Commit 6687450

Browse files
Merge pull request #812 from Suesswarendieb/feature/invoicer_contact
Add InvoicerContact for use with the extended profile
2 parents ed256c0 + 2d3c6ed commit 6687450

File tree

4 files changed

+67
-2
lines changed

4 files changed

+67
-2
lines changed

ZUGFeRD.Test/ZUGFeRD22Tests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3623,5 +3623,52 @@ public void TestRSMInvoice()
36233623
Assert.AreEqual(desc.InvoiceNo, "0815-99-1-a");
36243624
Assert.AreEqual(desc.InvoiceDate, new DateTime(2020, 06, 21));
36253625
} // !TestRSMInvoice()
3626+
3627+
[TestMethod]
3628+
public void TestInvoicerContactWriteAndRead()
3629+
{
3630+
var desc = InvoiceDescriptor.CreateInvoice("12345", new DateTime(2025, 06, 01), CurrencyCodes.EUR);
3631+
desc.Invoicer = new Party
3632+
{
3633+
Name = "Invoicer Name",
3634+
Street = "Straße 1",
3635+
Postcode = "01234",
3636+
City = "Musterstadt",
3637+
Country = CountryCodes.DE,
3638+
};
3639+
3640+
desc.InvoicerContact = new Contact
3641+
{
3642+
EmailAddress = "invoiceremail@example.com",
3643+
FaxNo = "+49 12345",
3644+
PhoneNo = "+49 54321"
3645+
};
3646+
3647+
using var invoiceStream = new MemoryStream();
3648+
desc.Save(invoiceStream, ZUGFeRDVersion.Version23, Profile.Extended);
3649+
3650+
var invoiceString = Encoding.UTF8.GetString(invoiceStream.ToArray());
3651+
3652+
const string expectedInvoicePart = """
3653+
<ram:DefinedTradeContact>
3654+
<ram:TelephoneUniversalCommunication>
3655+
<ram:CompleteNumber>+49 54321</ram:CompleteNumber>
3656+
</ram:TelephoneUniversalCommunication>
3657+
<ram:FaxUniversalCommunication>
3658+
<ram:CompleteNumber>+49 12345</ram:CompleteNumber>
3659+
</ram:FaxUniversalCommunication>
3660+
<ram:EmailURIUniversalCommunication>
3661+
<ram:URIID>invoiceremail@example.com</ram:URIID>
3662+
</ram:EmailURIUniversalCommunication>
3663+
</ram:DefinedTradeContact>
3664+
""";
3665+
StringAssert.Contains(invoiceString, expectedInvoicePart);
3666+
3667+
var loadedInvoice = InvoiceDescriptor.Load(invoiceStream);
3668+
3669+
Assert.AreEqual("invoiceremail@example.com", loadedInvoice.InvoicerContact.EmailAddress);
3670+
Assert.AreEqual("+49 12345", loadedInvoice.InvoicerContact.FaxNo);
3671+
Assert.AreEqual("+49 54321", loadedInvoice.InvoicerContact.PhoneNo);
3672+
}
36263673
}
36273674
}

ZUGFeRD/InvoiceDescriptor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ public class InvoiceDescriptor
219219
/// </summary>
220220
public Party Invoicer { get; set; }
221221

222+
/// <summary>
223+
/// Optional contact only used in Extended profile.
224+
/// Detailed contact information of the invoicer BG-X-34
225+
/// </summary>
226+
public Contact InvoicerContact { get; set; }
227+
222228
/// <summary>
223229
/// This party is optional and is written in most profiles except Minimum profile
224230
///

ZUGFeRD/InvoiceDescriptor23CIIReader.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,18 @@ public override InvoiceDescriptor Load(Stream stream)
247247
}
248248

249249
retval.Invoicer = _nodeAsParty(doc.DocumentElement, "//ram:ApplicableHeaderTradeSettlement/ram:InvoicerTradeParty", nsmgr);
250+
if (doc.SelectSingleNode("//ram:InvoicerTradeParty/ram:DefinedTradeContact", nsmgr) != null)
251+
{
252+
retval.InvoicerContact = new Contact()
253+
{
254+
Name = XmlUtils.NodeAsString(doc.DocumentElement, "//ram:InvoicerTradeParty/ram:DefinedTradeContact/ram:PersonName", nsmgr),
255+
OrgUnit = XmlUtils.NodeAsString(doc.DocumentElement, "//ram:InvoicerTradeParty/ram:DefinedTradeContact/ram:DepartmentName", nsmgr),
256+
PhoneNo = XmlUtils.NodeAsString(doc.DocumentElement, "//ram:InvoicerTradeParty/ram:DefinedTradeContact/ram:TelephoneUniversalCommunication/ram:CompleteNumber", nsmgr),
257+
FaxNo = XmlUtils.NodeAsString(doc.DocumentElement, "//ram:InvoicerTradeParty/ram:DefinedTradeContact/ram:FaxUniversalCommunication/ram:CompleteNumber", nsmgr),
258+
EmailAddress = XmlUtils.NodeAsString(doc.DocumentElement, "//ram:InvoicerTradeParty/ram:DefinedTradeContact/ram:EmailURIUniversalCommunication/ram:URIID", nsmgr)
259+
};
260+
}
261+
250262
retval.Payee = _nodeAsParty(doc.DocumentElement, "//ram:ApplicableHeaderTradeSettlement/ram:PayeeTradeParty", nsmgr);
251263

252264
retval.PaymentReference = XmlUtils.NodeAsString(doc.DocumentElement, "//ram:ApplicableHeaderTradeSettlement/ram:PaymentReference", nsmgr);
@@ -299,7 +311,7 @@ public override InvoiceDescriptor Load(Stream stream)
299311
bankleitzahl: i < creditorFinancialInstitutions.Count ? XmlUtils.NodeAsString(creditorFinancialInstitutions[i], ".//ram:GermanBankleitzahlID", nsmgr) : string.Empty,
300312
bankName: i < creditorFinancialInstitutions.Count ? XmlUtils.NodeAsString(creditorFinancialInstitutions[i], ".//ram:Name", nsmgr) : string.Empty,
301313
name: i < creditorFinancialAccountNodes.Count ? XmlUtils.NodeAsString(creditorFinancialAccountNodes[i], ".//ram:AccountName", nsmgr) : string.Empty);
302-
} // !for(i)
314+
} // !for(i)
303315

304316

305317
var specifiedTradeSettlementPaymentMeansNodes = doc.SelectNodes("//ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementPaymentMeans", nsmgr);

ZUGFeRD/InvoiceDescriptor23CIIWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ public override void Save(InvoiceDescriptor descriptor, Stream stream, ZUGFeRDFo
856856
_Writer.WriteOptionalElementString("ram", "InvoiceIssuerReference", this._Descriptor.SellerReferenceNo, Profile.Extended);
857857

858858
// 6. InvoicerTradeParty (optional), BG-X-33
859-
_writeOptionalParty(_Writer, PartyTypes.InvoicerTradeParty, this._Descriptor.Invoicer, Profile.Extended);
859+
_writeOptionalParty(_Writer, PartyTypes.InvoicerTradeParty, this._Descriptor.Invoicer, Profile.Extended, this._Descriptor.InvoicerContact);
860860

861861
// 7. InvoiceeTradeParty (optional), BG-X-36
862862
_writeOptionalParty(_Writer, PartyTypes.InvoiceeTradeParty, this._Descriptor.Invoicee, Profile.Extended, default, default, this._Descriptor.GetInvoiceeTaxRegistration());

0 commit comments

Comments
 (0)