Skip to content

Commit f1db682

Browse files
committed
added test cases for designatedproductclassification, changed parameter order (breaking change)
#335
1 parent 6bc4313 commit f1db682

6 files changed

+148
-20
lines changed

ZUGFeRD-Test/ZUGFeRD22Tests.cs

+107-1
Original file line numberDiff line numberDiff line change
@@ -2035,5 +2035,111 @@ public void ShouldLoadCiiWithoutQdtNamespace()
20352035
Assert.AreEqual(desc.TradeLineItems.Count, 2);
20362036
Assert.AreEqual(desc.LineTotalAmount, 314.86m);
20372037
} // !ShouldLoadCIIWithoutQdtNamespace()
2038-
}
2038+
2039+
2040+
[TestMethod]
2041+
public void TestDesignatedProductClassificationWithFullClassification()
2042+
{
2043+
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
2044+
desc.TradeLineItems.First().AddDesignatedProductClassification(
2045+
"Test Value",
2046+
DesignatedProductClassificationClassCodes.HS,
2047+
"List ID Value",
2048+
"List Version ID Value");
2049+
2050+
MemoryStream ms = new MemoryStream();
2051+
2052+
desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);
2053+
2054+
// string comparison
2055+
ms.Seek(0, SeekOrigin.Begin);
2056+
StreamReader reader = new StreamReader(ms);
2057+
string content = reader.ReadToEnd();
2058+
Assert.IsTrue(content.Contains("<ram:DesignatedProductClassification>"));
2059+
Assert.IsTrue(content.Contains("<ram:ClassCode listID=\"List ID Value\" listVersionID=\"List Version ID Value\">HS</ram:ClassCode>"));
2060+
Assert.IsTrue(content.Contains("<ram:ClassName>Test Value</ram:ClassName>"));
2061+
2062+
// structure comparison
2063+
ms.Seek(0, SeekOrigin.Begin);
2064+
File.WriteAllBytes("e:\\output.xml", ms.ToArray());
2065+
2066+
ms.Seek(0, SeekOrigin.Begin);
2067+
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);
2068+
2069+
Assert.AreEqual(DesignatedProductClassificationClassCodes.HS, desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
2070+
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
2071+
Assert.AreEqual("List ID Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
2072+
Assert.AreEqual("List Version ID Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
2073+
} // !TestDesignatedProductClassificationWithFullClassification()
2074+
2075+
2076+
[TestMethod]
2077+
public void TestDesignatedProductClassificationWithEmptyVersionId()
2078+
{
2079+
// test with empty version id value
2080+
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
2081+
desc.TradeLineItems.First().AddDesignatedProductClassification(
2082+
"Test Value",
2083+
DesignatedProductClassificationClassCodes.HS,
2084+
"List ID Value"
2085+
);
2086+
2087+
MemoryStream ms = new MemoryStream();
2088+
2089+
desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);
2090+
2091+
ms.Seek(0, SeekOrigin.Begin);
2092+
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);
2093+
2094+
Assert.AreEqual(DesignatedProductClassificationClassCodes.HS, desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
2095+
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
2096+
Assert.AreEqual("List ID Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
2097+
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
2098+
} // !TestDesignatedProductClassificationWithEmptyVersionId()
2099+
2100+
2101+
2102+
[TestMethod]
2103+
public void TestDesignatedProductClassificationWithEmptyListIdAndVersionId()
2104+
{
2105+
// test with empty version id value
2106+
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
2107+
desc.TradeLineItems.First().AddDesignatedProductClassification(
2108+
"Test Value",
2109+
DesignatedProductClassificationClassCodes.HS);
2110+
2111+
MemoryStream ms = new MemoryStream();
2112+
2113+
desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);
2114+
2115+
ms.Seek(0, SeekOrigin.Begin);
2116+
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);
2117+
2118+
Assert.AreEqual(DesignatedProductClassificationClassCodes.HS, desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
2119+
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
2120+
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
2121+
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
2122+
} // !TestDesignatedProductClassificationWithEmptyListIdAndVersionId()
2123+
2124+
2125+
[TestMethod]
2126+
public void TestDesignatedProductClassificationWithoutClassCode()
2127+
{
2128+
// test with empty version id value
2129+
InvoiceDescriptor desc = this.InvoiceProvider.CreateInvoice();
2130+
desc.TradeLineItems.First().AddDesignatedProductClassification("Test Value");
2131+
2132+
MemoryStream ms = new MemoryStream();
2133+
2134+
desc.Save(ms, ZUGFeRDVersion.Version22, Profile.XRechnung);
2135+
2136+
ms.Seek(0, SeekOrigin.Begin);
2137+
InvoiceDescriptor loadedInvoice = InvoiceDescriptor.Load(ms);
2138+
2139+
Assert.AreEqual(default(DesignatedProductClassificationClassCodes), desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassCode);
2140+
Assert.AreEqual("Test Value", desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ClassName);
2141+
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListID);
2142+
Assert.IsNull(desc.TradeLineItems.First().GetDesignatedProductClassifications().First().ListVersionID);
2143+
} // !TestDesignatedProductClassificationWithoutClassCode()
2144+
}
20392145
}

ZUGFeRD/DesignatedProductClassificationClassCodes.cs

+26-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,33 @@
2222

2323
namespace s2industries.ZUGFeRD
2424
{
25-
public enum DesignatedProductClassificationClassCodes
25+
/// <summary>
26+
/// A code for the classification of an item according to type or kind or nature.
27+
///
28+
/// Classification codes are used for the aggregation of similar products, which might be useful for various
29+
/// purposes,
30+
/// for instance like public procurement, in accordance with the Common Vocabulary for Public Procurement
31+
/// [CPV]), e-Commerce(UNSPSC) etc.
32+
///
33+
/// Source: UNTDID 7143
34+
/// Business rule: BR-65
35+
/// </summary>
36+
public enum DesignatedProductClassificationClassCodes
2637
{
27-
HS,
28-
Unknown
29-
}
38+
Unknown = 0,
39+
40+
/// <summary>
41+
/// Product version number
42+
/// Number assigned by manufacturer or seller to identify the release of a product.
43+
/// </summary>
44+
AA,
45+
46+
/// <summary>
47+
/// Harmonised system
48+
/// 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).
49+
/// </summary>
50+
HS
51+
}
3052

3153
internal static class DesignatedProductClassificationClassCodesExtensions
3254
{

ZUGFeRD/InvoiceDescriptor22CIIReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ private static TradeLineItem _parseTradeLineItem(XmlNode tradeLineItem, XmlNames
615615
string listID = XmlUtils.NodeAsString(designatedProductClassificationNode, ".//ram:ClassCode/@listID", nsmgr);
616616
string listVersionID = XmlUtils.NodeAsString(designatedProductClassificationNode, ".//ram:ClassCode/@listVersionID", nsmgr);
617617

618-
item.AddDesignatedProductClassification(classCode, className, listID, listVersionID);
618+
item.AddDesignatedProductClassification(className, classCode, listID, listVersionID);
619619
} // !foreach(designatedProductClassificationNode))
620620

621621
return item;

ZUGFeRD/InvoiceDescriptor22CIIWriter.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,11 @@ public override void Save(InvoiceDescriptor descriptor, Stream stream, ZUGFeRDFo
175175
{
176176
foreach(var designatedProductClassification in tradeLineItem.GetDesignatedProductClassifications())
177177
{
178-
Writer.WriteStartElement("ram:DesignatedProductClassification");
179-
Writer.WriteOptionalElementString("ram:ClassName", designatedProductClassification.ClassName);
178+
Writer.WriteStartElement("ram:DesignatedProductClassification");
180179

181180
if (designatedProductClassification.ClassCode.HasValue)
182181
{
183-
Writer.WriteStartElement("ram::ClassCode");
182+
Writer.WriteStartElement("ram:ClassCode");
184183
if (!String.IsNullOrWhiteSpace(designatedProductClassification.ListID))
185184
{
186185
Writer.WriteAttributeString("listID", designatedProductClassification.ListID);
@@ -189,7 +188,8 @@ public override void Save(InvoiceDescriptor descriptor, Stream stream, ZUGFeRDFo
189188
Writer.WriteValue(designatedProductClassification.ClassCode.Value.ToString());
190189
Writer.WriteEndElement(); // !ram::ClassCode
191190
}
192-
Writer.WriteEndElement(); // !ram:DesignatedProductClassification
191+
Writer.WriteOptionalElementString("ram:ClassName", designatedProductClassification.ClassName);
192+
Writer.WriteEndElement(); // !ram:DesignatedProductClassification
193193
}
194194
}
195195

ZUGFeRD/InvoiceDescriptor22UblReader.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,8 @@ private static TradeLineItem _parseTradeLineItem(XmlNode tradeLineItem, XmlNames
476476
{
477477
DesignatedProductClassificationClassCodes code = default(DesignatedProductClassificationClassCodes).FromString(commodityClassification.InnerText);
478478
item.AddDesignatedProductClassification(
479-
code,
480-
"", // no name in Peppol Billing!
479+
"", // no name in Peppol Billing!
480+
code,
481481
XmlUtils.NodeAsString(commodityClassification, "./@listID", nsmgr),
482482
XmlUtils.NodeAsString(commodityClassification, "./@istVersionID", nsmgr));
483483
}

ZUGFeRD/TradeLineItem.cs

+8-8
Original file line numberDiff line numberDiff line change
@@ -388,14 +388,14 @@ public void AddReceivableSpecifiedTradeAccountingAccount(string AccountID, Accou
388388
}
389389

390390

391-
/// <summary>
392-
/// Adds a product classification
393-
/// </summary>
394-
/// <param name="classCode">Identifier of the item classification</param>
395-
/// <param name="className">Classification name. If you leave className empty, it will be omitted in the output</param>
396-
/// <param name="listID">Product classification name (optional)</param>
397-
/// <param name="listVersionID">Version of product classification (optional)</param>
398-
public void AddDesignatedProductClassification(DesignatedProductClassificationClassCodes classCode, string className, string listID = null, string listVersionID = null)
391+
/// <summary>
392+
/// Adds a product classification
393+
/// </summary>
394+
/// <param name="className">Classification name. If you leave className empty, it will be omitted in the output</param>
395+
/// <param name="classCode">Identifier of the item classification (optional)</param>
396+
/// <param name="listID">Product classification name (optional)</param>
397+
/// <param name="listVersionID">Version of product classification (optional)</param>
398+
public void AddDesignatedProductClassification(string className, DesignatedProductClassificationClassCodes classCode = default(DesignatedProductClassificationClassCodes), string listID = null, string listVersionID = null)
399399
{
400400
this.DesignedProductClassifications.Add(new DesignatedProductClassification()
401401
{

0 commit comments

Comments
 (0)