Skip to content

Commit

Permalink
added test cases for designatedproductclassification, changed paramet…
Browse files Browse the repository at this point in the history
…er order (breaking change)

#335
  • Loading branch information
stephanstapel committed Aug 29, 2024
1 parent 6bc4313 commit f1db682
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 20 deletions.
108 changes: 107 additions & 1 deletion ZUGFeRD-Test/ZUGFeRD22Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2035,5 +2035,111 @@ public void ShouldLoadCiiWithoutQdtNamespace()
Assert.AreEqual(desc.TradeLineItems.Count, 2);
Assert.AreEqual(desc.LineTotalAmount, 314.86m);
} // !ShouldLoadCIIWithoutQdtNamespace()
}


[TestMethod]
public void TestDesignatedProductClassificationWithFullClassification()
{
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
desc.TradeLineItems.First().AddDesignatedProductClassification(
"Test Value",
DesignatedProductClassificationClassCodes.HS,
"List ID Value",
"List Version ID Value");

MemoryStream ms = new MemoryStream();

desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);

// string comparison
ms.Seek(0, SeekOrigin.Begin);
StreamReader reader = new StreamReader(ms);
string content = reader.ReadToEnd();
Assert.IsTrue(content.Contains("<ram:DesignatedProductClassification>"));
Assert.IsTrue(content.Contains("<ram:ClassCode listID=\"List ID Value\" listVersionID=\"List Version ID Value\">HS</ram:ClassCode>"));
Assert.IsTrue(content.Contains("<ram:ClassName>Test Value</ram:ClassName>"));

// structure comparison
ms.Seek(0, SeekOrigin.Begin);
File.WriteAllBytes("e:\\output.xml", ms.ToArray());

ms.Seek(0, SeekOrigin.Begin);
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);

Assert.AreEqual(DesignatedProductClassificationClassCodes.HS, desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
Assert.AreEqual("List ID Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
Assert.AreEqual("List Version ID Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
} // !TestDesignatedProductClassificationWithFullClassification()


[TestMethod]
public void TestDesignatedProductClassificationWithEmptyVersionId()
{
// test with empty version id value
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
desc.TradeLineItems.First().AddDesignatedProductClassification(
"Test Value",
DesignatedProductClassificationClassCodes.HS,
"List ID Value"
);

MemoryStream ms = new MemoryStream();

desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);

ms.Seek(0, SeekOrigin.Begin);
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);

Assert.AreEqual(DesignatedProductClassificationClassCodes.HS, desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
Assert.AreEqual("List ID Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
} // !TestDesignatedProductClassificationWithEmptyVersionId()



[TestMethod]
public void TestDesignatedProductClassificationWithEmptyListIdAndVersionId()
{
// test with empty version id value
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
desc.TradeLineItems.First().AddDesignatedProductClassification(
"Test Value",
DesignatedProductClassificationClassCodes.HS);

MemoryStream ms = new MemoryStream();

desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);

ms.Seek(0, SeekOrigin.Begin);
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);

Assert.AreEqual(DesignatedProductClassificationClassCodes.HS, desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
} // !TestDesignatedProductClassificationWithEmptyListIdAndVersionId()


[TestMethod]
public void TestDesignatedProductClassificationWithoutClassCode()
{
// test with empty version id value
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
desc.TradeLineItems.First().AddDesignatedProductClassification("Test Value");

MemoryStream ms = new MemoryStream();

desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);

ms.Seek(0, SeekOrigin.Begin);
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);

Assert.AreEqual(default(DesignatedProductClassificationClassCodes), desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
} // !TestDesignatedProductClassificationWithoutClassCode()
}
}
30 changes: 26 additions & 4 deletions ZUGFeRD/DesignatedProductClassificationClassCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,33 @@

namespace s2industries.ZUGFeRD
{
public enum DesignatedProductClassificationClassCodes
/// <summary>
/// A code for the classification of an item according to type or kind or nature.
///
/// Classification codes are used for the aggregation of similar products, which might be useful for various
/// purposes,
/// for instance like public procurement, in accordance with the Common Vocabulary for Public Procurement
/// [CPV]), e-Commerce(UNSPSC) etc.
///
/// Source: UNTDID 7143
/// Business rule: BR-65
/// </summary>
public enum DesignatedProductClassificationClassCodes
{
HS,
Unknown
}
Unknown = 0,

Check warning on line 38 in ZUGFeRD/DesignatedProductClassificationClassCodes.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'DesignatedProductClassificationClassCodes.Unknown'

Check warning on line 38 in ZUGFeRD/DesignatedProductClassificationClassCodes.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'DesignatedProductClassificationClassCodes.Unknown'

/// <summary>
/// Product version number
/// Number assigned by manufacturer or seller to identify the release of a product.
/// </summary>
AA,

/// <summary>
/// Harmonised system
/// The item number is part of, or is generated in the context of the Harmonised Commodity Description and Coding System (Harmonised System), as developed and maintained by the World Customs Organization (WCO).
/// </summary>
HS
}

internal static class DesignatedProductClassificationClassCodesExtensions
{
Expand Down
2 changes: 1 addition & 1 deletion ZUGFeRD/InvoiceDescriptor22CIIReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ private static TradeLineItem _parseTradeLineItem(XmlNode tradeLineItem, XmlNames
string listID = XmlUtils.NodeAsString(designatedProductClassificationNode, ".//ram:ClassCode/@listID", nsmgr);
string listVersionID = XmlUtils.NodeAsString(designatedProductClassificationNode, ".//ram:ClassCode/@listVersionID", nsmgr);

item.AddDesignatedProductClassification(classCode, className, listID, listVersionID);
item.AddDesignatedProductClassification(className, classCode, listID, listVersionID);
} // !foreach(designatedProductClassificationNode))

return item;
Expand Down
8 changes: 4 additions & 4 deletions ZUGFeRD/InvoiceDescriptor22CIIWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,11 @@ public override void Save(InvoiceDescriptor descriptor, Stream stream, ZUGFeRDFo
{
foreach(var designatedProductClassification in tradeLineItem.GetDesignatedProductClassifications())
{
Writer.WriteStartElement("ram:DesignatedProductClassification");
Writer.WriteOptionalElementString("ram:ClassName", designatedProductClassification.ClassName);
Writer.WriteStartElement("ram:DesignatedProductClassification");

if (designatedProductClassification.ClassCode.HasValue)
{
Writer.WriteStartElement("ram::ClassCode");
Writer.WriteStartElement("ram:ClassCode");
if (!String.IsNullOrWhiteSpace(designatedProductClassification.ListID))
{
Writer.WriteAttributeString("listID", designatedProductClassification.ListID);
Expand All @@ -189,7 +188,8 @@ public override void Save(InvoiceDescriptor descriptor, Stream stream, ZUGFeRDFo
Writer.WriteValue(designatedProductClassification.ClassCode.Value.ToString());
Writer.WriteEndElement(); // !ram::ClassCode
}
Writer.WriteEndElement(); // !ram:DesignatedProductClassification
Writer.WriteOptionalElementString("ram:ClassName", designatedProductClassification.ClassName);
Writer.WriteEndElement(); // !ram:DesignatedProductClassification
}
}

Expand Down
4 changes: 2 additions & 2 deletions ZUGFeRD/InvoiceDescriptor22UblReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,8 @@ private static TradeLineItem _parseTradeLineItem(XmlNode tradeLineItem, XmlNames
{
DesignatedProductClassificationClassCodes code = default(DesignatedProductClassificationClassCodes).FromString(commodityClassification.InnerText);
item.AddDesignatedProductClassification(
code,
"", // no name in Peppol Billing!
"", // no name in Peppol Billing!
code,
XmlUtils.NodeAsString(commodityClassification, "./@listID", nsmgr),
XmlUtils.NodeAsString(commodityClassification, "./@istVersionID", nsmgr));
}
Expand Down
16 changes: 8 additions & 8 deletions ZUGFeRD/TradeLineItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -388,14 +388,14 @@ public void AddReceivableSpecifiedTradeAccountingAccount(string AccountID, Accou
}


/// <summary>
/// Adds a product classification
/// </summary>
/// <param name="classCode">Identifier of the item classification</param>
/// <param name="className">Classification name. If you leave className empty, it will be omitted in the output</param>
/// <param name="listID">Product classification name (optional)</param>
/// <param name="listVersionID">Version of product classification (optional)</param>
public void AddDesignatedProductClassification(DesignatedProductClassificationClassCodes classCode, string className, string listID = null, string listVersionID = null)
/// <summary>
/// Adds a product classification
/// </summary>
/// <param name="className">Classification name. If you leave className empty, it will be omitted in the output</param>
/// <param name="classCode">Identifier of the item classification (optional)</param>
/// <param name="listID">Product classification name (optional)</param>
/// <param name="listVersionID">Version of product classification (optional)</param>
public void AddDesignatedProductClassification(string className, DesignatedProductClassificationClassCodes classCode = default(DesignatedProductClassificationClassCodes), string listID = null, string listVersionID = null)
{
this.DesignedProductClassifications.Add(new DesignatedProductClassification()
{
Expand Down

0 comments on commit f1db682

Please sign in to comment.